从图表系列中获取主题颜色信息

san*_*ica 5 format excel charts vba excel-vba

我有一个图表系列使用一种颜色(它可以是一个msoThemeColorAccent<#>或任何其他)作为标记线,另一种颜色作为标记填充(它可以是msoThemeColorAccent<#>,更轻的x%,或任何其他),没有线.我想确定图表系列是否使用a msoThemeColorAccent<#>作为标记线,a msoThemeColorAccent<#>,较轻的x%,用于标记填充,如果是,则在每种情况下使用哪种特定的强调颜色.

我尝试返回一系列的一些属性,没有运气.在执行Sub的过程中的断点处,该Sub具有sr对图表系列的引用(为了测试目的,设置为具有线条,其颜色与标记线和标记填充相同,设置为Accent1),并且在With sr施工,我在即时窗口测试:

? .Format.Line.BackColor.ObjectThemeColor, .Format.Line.ForeColor.ObjectThemeColor
0             0
? .Format.Fill.BackColor.ObjectThemeColor, .Format.Fill.ForeColor.ObjectThemeColor
0            -2
Run Code Online (Sandbox Code Playgroud)

我期望以某种方式获得msoThemeColorAccent1(= 5)的值,这在我的系列中使用.有没有办法做到这一点?

我发现的所有示例都msoThemeColorIndex用于设置颜色,没有用作读取的值.

PS:我在第一部分没有成功,系列颜色均匀.我预见如果我克服了这个障碍,我可能仍然会在检测到TintAndShade没有线,不同标记填充与标记线的目标情况下的正确或甚至强调颜色方面存在问题.

Dee*_*ter 2

所以这很有趣。我使用所有默认值创建折线图,然后运行以下过程:

在此输入图像描述

Sub getLineCOlors()
Dim cht As Chart
Dim srs As Series
Dim colors As String
Dim pt As Point

Set cht = ActiveSheet.ChartObjects(1).Chart

For Each srs In cht.SeriesCollection
    With srs.Format.Line
    colors = colors & vbCrLf & srs.Name & " : " & _
            .ForeColor.RGB
    End With

Next

Debug.Print "Line Colors", colors

End Sub
Run Code Online (Sandbox Code Playgroud)

然后立即窗口显示:

Line Colors   
Series1 : 16777215
Series2 : 16777215
Series3 : 16777215
Run Code Online (Sandbox Code Playgroud)

但事实显然并非如此。很明显,它们都是不同的颜色。如果,而不是.RGB我这样做.ObjectThemeColor,那么我得到全部0,通过观察图表,这同样是错误的!

Line Colors   
Series1 : 0
Series2 : 0
Series3 : 0
Run Code Online (Sandbox Code Playgroud)

现在这里变得有趣了:

如果在创建图表后我更改了系列颜色(或者甚至通过分配给相同的 ThemeColors 使它们保持不变),则该函数将显示有效的 RGB:

Line Colors   
Series1 : 5066944
Series2 : 12419407
Series3 : 5880731
Run Code Online (Sandbox Code Playgroud)

就好像 Excel(和 PowerPoint/等)完全无法识别折线图上自动分配的颜色。一旦指定了颜色,它就可以读取颜色。

注意:折线图很挑剔,因为你没有.Fill,而是有.Format.Line.ForeColor( 和.BackColor) 和 IIRC 还有一些其他的怪癖,比如你可以选择一个单独的点并更改它的填充颜色,然后这会影响视觉效果前一条线段的外观等...

这仅限于折线图吗?也许。我过去的经验是“可能”,虽然我不能说这是一个错误,但它看起来确实是一个错误。

如果我在柱形图上运行类似的过程 - 再次仅使用自动分配的默认颜色,

Sub getCOlumnColors()

Dim cht As Chart
Dim srs As Series
Dim colors As String
Dim pt As Point

Set cht = ActiveSheet.ChartObjects(2).Chart

For Each srs In cht.SeriesCollection

    With srs.Format.Fill
    colors = colors & vbCrLf & srs.Name & " : " & _
            .ForeColor.RGB
    End With

Next

Debug.Print "Column Colors", colors

End Sub
Run Code Online (Sandbox Code Playgroud)

然后我得到了看似有效的 RGB 值:

Column Colors 
Series1 : 12419407
Series2 : 5066944
Series3 : 5880731
Run Code Online (Sandbox Code Playgroud)

但是:它仍然无法识别有效的ObjectThemeColor. 如果我改变,.RGB那么输出:

Column Colors 
Series1 : 0
Series2 : 0
Series3 : 0
Run Code Online (Sandbox Code Playgroud)

因此,根据这些观察,肯定无法访问自动分配的颜色格式的ObjectThemeColor和/或属性。.RGB

正如 Tim Williams 所证实的那样,这是一个早在 2005 年就存在的错误,至少与 RGB 相关,并且该错误可能会通过 ObjectThemeColor 等延续到 Excel 2007+ 中......它不太可能得到解决时间很快,所以我们需要一个黑客解决方案:)

更新的解决方案

将以上两种方法结合起来!将每个系列从折线转换为 xlColumnClustered,然后从 .Fill 查询颜色属性,然后将系列图表类型更改回其原始状态。这可能比尝试利用顺序索引更可靠(如果用户重新排序了系列,例如“Series1”位于索引 3 等,则顺序索引根本不可靠)

Sub getLineColors()
Dim cht As Chart
Dim chtType As Long
Dim srs As Series
Dim colors As String

Set cht = ActiveSheet.ChartObjects(1).Chart

For Each srs In cht.SeriesCollection
    chtType = srs.ChartType
    'Temporarily turn this in to a column chart:
    srs.ChartType = 51
    colors = colors & vbCrLf & srs.Name & " : " & _
            srs.Format.Fill.ForeColor.RGB
    'reset the chart type to its original state:
    srs.ChartType = chtType
Next

Debug.Print "Line Colors", colors

End Sub
Run Code Online (Sandbox Code Playgroud)

图片来源:大卫·泽门斯