VBA:使用默认颜色提取图表中线条的RGB值

问题

我想知道如何读取图表中自动指定颜色的当前RGB值,即使这需要将颜色冻结为其当前值(而不是在主题更改、系列重新排序等时进行更新)

用例

我的实际用例是,我希望使数据标签与折线图中线条/标记的颜色相匹配。如果我已经通过方案或显式RGB值显式设置了系列的颜色,那么这很容易

假定ColorFormat.Type=msoColorTypeRGB
s、 DataLabels.Format.TextFrame2.TextRange.Font.Fill.ForeColor.RGB=_
s、 Format.Line.ForeColor.RGB

但是,在自动指定系列颜色时执行此操作会产生白色标签。更具体地说,以下两个等式都成立

s.Format.Line.ForeColor.Type=msoColorTypeRGB
s、 Format.Line.ForeColor.RGB=RGB(255255)“白色

当然,线条不是白色,而是从主题中自动指定的颜色。这表明颜色是自动指定的

s.Border.ColorIndex=xlColorIndexAutomatic

我想这是有道理的,颜色不存储在系列的问题。即使将索引存储到颜色方案中,通常也不会起作用,因为如果添加了另一个数据系列或有人重新排序数据,Excel需要更改颜色。尽管如此,如果有某种方法可以自动识别当前的RGB值,我还是会喜欢它的

难看的变通办法

对于具有6个或更少条目的图表,一个简单的解决方法是利用主题颜色是按顺序分配的这一事实,这样我就可以做到(例如)

chrt.SeriesCollection(1).DataLabels.Format.TextFrame2.TextRange.Font.Fill.ForeColor.ObjectThemeColor_
=msotheme1

假设这可以扩展到TintAndShade,用于在主题用尽后区分条目,但这是一个非常丑陋的黑客行为

研究

有人在这里问了本质上相同的问题(如何提取主题颜色),但从未得到回答。有几个来源建议如何将已知的主题颜色转换为RGB值(例如,此处和此处),但这只是回避了问题;除了“这条线现在是什么颜色”之外,我不知道它的颜色

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

子GetLineColor()
暗海隧As图
Dim srs As系列
暗淡的颜色如细绳
变暗pt为点
Set cht=ActiveSheet.ChartObjects(1.Chart)
对于cht.SeriesCollection中的每个srs
使用srs.Format.Line
颜色=颜色&vbCrLf&srs.名称和名称;“:”&amp_
.ForeColor.RGB
以
下一个
调试。打印“线条颜色”,颜色
端接头

立即窗口随后显示:

线条颜色
系列1:16777215
系列2:16777215
系列3:16777215

但情况显然并非如此。很明显,它们都是不同的颜色。如果我不选择.RGB而选择.ObjectThemeColor,那么我会得到所有0,通过观察图表,这同样是错误的

线条颜色
系列1:0
系列2:0
系列3:0

现在这里是有趣的地方:

如果在创建图表I后更改系列颜色(甚至通过指定相同的颜色使其保持不变),则函数将显示有效的RGB:

线条颜色
系列1:5066944
系列2:12419407
系列3:5880731

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

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

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

如果我在柱状图上运行类似的过程——同样只使用自动指定的默认颜色

子getCOlumnColors()
暗海隧As图
Dim srs As系列
暗淡的颜色如细绳
变暗pt为点
Set cht=ActiveSheet.ChartObjects(2.Chart)
对于cht.SeriesCollection中的每个srs
使用srs.Format.Fill
颜色=颜色&vbCrLf&srs.名称和名称;“:”&amp_
.ForeColor.RGB
以
下一个
调试。打印“列颜色”,颜色
端接头

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

列颜色
系列1:12419407
系列2:5066944
系列3:5880731

但是:它仍然无法识别有效的对象ThemeColor。如果我更改.RGB,则输出:

列颜色
系列1:0
系列2:0
系列3:0

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

正如Tim Williams所证实的,这是一个早在2005年就存在的bug,至少与RGB有关,而且可能是该bug通过对象ThemeColor等带入Excel 2007+。。。这不太可能很快得到解决,因此我们需要一个黑客解决方案:)

更新的解决方案

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

子GetLineColor()
暗海隧As图
长型
Dim srs As系列
暗淡的颜色如细绳
Set cht=ActiveSheet.ChartObjects(1.Chart)
对于cht.SeriesCollection中的每个srs
chtType=srs.ChartType
'暂时将其转换为柱状图:
srs.ChartType=51
颜色=颜色&vbCrLf&srs.名称和名称;“:”&amp_
srs.Format.Fill.ForeColor.RGB
'将图表类型重置为其原始状态:
srs.ChartType=chtType
下一个
调试。打印“线条颜色”,颜色
端接头

发表评论