Ali*_*ice 10 excel vba colors excel-vba
我想知道如何读取图表中自动指定颜色的当前RGB值,即使这需要将颜色冻结到其当前值(而不是在主题更改时更新它们,重新排序系列等)
我的实际用例是我想让数据标签与折线图中的线条/标记的颜色相匹配.如果我通过方案或显式RGB值明确设置系列的颜色,这很容易,例如
' assuming ColorFormat.Type = msoColorTypeRGB
s.DataLabels.Format.TextFrame2.TextRange.Font.Fill.ForeColor.RGB= _
s.Format.Line.ForeColor.RGB
Run Code Online (Sandbox Code Playgroud)
但是,在自动分配系列颜色时执行此操作会生成白色标签.更具体地说,以下两个等式都成立
s.Format.Line.ForeColor.Type = msoColorTypeRGB
s.Format.Line.ForeColor.RGB = RGB(255,255,255) ' White
Run Code Online (Sandbox Code Playgroud)
然而,当然这条线不是白色的,而是来自主题的自动指定颜色.这表明颜色是自动分配的
s.Border.ColorIndex = xlColorIndexAutomatic
Run Code Online (Sandbox Code Playgroud)
我想有意义的是,颜色不会与问题系列一起存储.即使将索引存储到颜色方案中也通常不起作用,因为如果添加了另一个数据系列或有人重新排序数据,则Excel需要更改颜色.如果有某种方法可以自动识别当前的RGB值,我还是会喜欢它.
对于具有6个或更少条目的图表,一个简单的解决方法是利用主题颜色按顺序分配的事实,所以我可以做(例如)
chrt.SeriesCollection(1).DataLabels.Format.TextFrame2.TextRange.Font.Fill.ForeColor.ObjectThemeColor _
= msoThemeColorAccent1
Run Code Online (Sandbox Code Playgroud)
据推测,这可以扩展到TintAndShade一旦主题用尽后用于区分条目,但这是一个丑陋的黑客.
有人(如何提取主题颜色)主要问同样的问题在这里,但它从来没有回答.有几个来源建议将已知主题颜色转换为RGB值的方法(例如此处和此处),但这只是问题; 我不知道这种颜色是先验的,除了"这条线目前的颜色是什么".
所以这很有趣.我使用所有默认值创建折线图,然后运行此过程:

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 /等)在线图上完全无法识别自动分配的颜色一样.一旦指定了颜色,它就可以读取颜色.
注意:折线图是挑剔的,因为你没有a .Fill,而是a .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属性.
正如蒂姆·威廉姆斯所证实的那样,早在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)
| 归档时间: |
|
| 查看次数: |
8828 次 |
| 最近记录: |