【问题标题】:Elegant way to highlight chart data series in Excel在 Excel 中突出显示图表数据系列的优雅方式
【发布时间】:2009-07-02 08:46:48
【问题描述】:

我想在表格中勾勒图表数据范围源,就像单击图表数据系列时 GUI 将勾勒出蓝色范围一样。用户可以选择各种图表视图,每个数据系列的范围突出显示颜色需要与图表中显示的颜色相匹配。

作为记录,以下是我考虑过的方法:

  1. 解析图表系列值字符串并提取数据范围
  2. 查找存储有关要使用的范围和颜色信息的表

最后我选择了选项 2,因为它似乎更易于实施和正确管理颜色,无论如何我可能不得不为方法 1 存储它们,从而否定了它的好处。

Worksheet_Change 事件中调用突出显示过程,查找图表名称、从表格中提取的范围和颜色,然后执行单元格格式设置。此方法的局限性在于必须预先计算每个新图表视图的范围/颜色数据。这对我当前的实现来说不是什么大问题,但我会成为未来使用图表可能更加动态的限制因素。

因此,虽然我有一个可以正常工作的版本,但我确信一定有更优雅的方式来实现这一点。

有什么建议吗?

【问题讨论】:

    标签: vba excel charts


    【解决方案1】:

    编辑:

    好的,这似乎可以更好地处理更多案件。触发代码相同,但这里是模块的新代码:

    Function SeriesRange(s As Series) As Range
        Dim sf As String, fa() As String
    
    
        sf = s.Formula
        sf = Replace(sf, "=SERIES(", "")
    
        If sf = "" Then
            Set SeriesRange = Nothing
            Exit Function
        End If
    
        fa = Split(sf, ",")
    
    
        Set SeriesRange = Range(fa(2))
    
    End Function
    
    Sub x(c As Chart)
        Dim sc As Series
        Dim sr As Range
    
        If SeriesRange(c.SeriesCollection(1)) Is Nothing Then
            Exit Sub
        End If
    
        Set sr = SeriesRange(c.SeriesCollection(1))
    
        sr.CurrentRegion.Interior.ColorIndex = xlNone
        For Each sc In c.SeriesCollection
            If sc.Interior.Color > 1 Then
                SeriesRange(sc).Interior.Color = sc.Interior.Color
            ElseIf sc.Border.ColorIndex > 1 Then
                SeriesRange(sc).Interior.Color = sc.Border.Color
            ElseIf sc.MarkerBackgroundColorIndex > 1 And sc.MarkerBackgroundColorIndex < 57 Then
                SeriesRange(sc).Interior.ColorIndex = sc.MarkerBackgroundColorIndex
            ElseIf sc.MarkerForegroundColorIndex > 1 And sc.MarkerForegroundColorIndex < 57 Then
                SeriesRange(sc).Interior.ColorIndex = sc.MarkerForegroundColorIndex
            Else
                MsgBox "Unable to determine chart color for data series " & sc.Name & " ." & vbCrLf _
                        & "It may help to assign a color rather than allowing AutoColor to assign one."
            End If
        Next sc
    
    End Sub
    

    /编辑

    这可能比优雅更野蛮,但我认为它可以满足您的需求。它涉及从Series 对象获取范围的第一个要点,以及一个遍历图表SeriesCollection 中所有Series 对象的子点。这是在Chart_DeActivate 上激活的。大部分代码都被劫持了 - 请参阅 cmets 获取源代码。

    在一个模块中:

    Function SeriesRange(s As Series) As Range
        Dim sf As String, fa() As String
        Dim i As Integer
        Dim result As Range
    
        sf = s.Formula
        sf = Replace(sf, "=SERIES(", "")
    
        fa = Split(sf, ",")
    
        Set SeriesRange = Range(fa(2))
    End Function
    
    Sub x(c As Chart)
        Dim sc As Series
        Dim sr As Range
    
        Set sr = SeriesRange(c.SeriesCollection(1))
    
        sr.CurrentRegion.Interior.ColorIndex = xlNone
    
        For Each sc In c.SeriesCollection
            SeriesRange(sc).Interior.Color = sc.Interior.Color
        Next sc
    
    End Sub
    

    ThisWorkbook 对象模块中:

    ' Jacked from C Pearson http://www.cpearson.com/excel/Events.aspx '
    Public WithEvents CHT As Chart
    
    Private Sub CHT_Deactivate()
        x CHT 
    End Sub
    
    Private Sub Workbook_Open()
        Set CHT = Worksheets(1).ChartObjects(1).Chart 
    End Sub
    

    【讨论】:

    • 这比我为选项 1 拼凑的代码要简洁得多,直接使用图表系列颜色是如此明显,我完全忽略了它!
    • 这个问题的一个问题是它只适用于具有interior.color 的图表类型——折线图和散点图不适用。我想我可以先测试一下图表类型。
    • 我对此进行了一些研究,从线条和区域中获取颜色很容易,但如果它只是标记,那就有点挑战了。问题归结为自动着色。使用线条和区域,您可以检查 ColorIndex,如果它是自动颜色,请查看颜色。使用标记,颜色似乎与自动颜色具有相同的值。所以,我想,只要用户总是会实际选择一种颜色,它是可行的。如果我有时间,我可能会为这种特殊情况写一些东西,如果他们不这样做,可能会抛出一个提示,迫使他们这样做。
    【解决方案2】:

    您是否尝试过使用条件格式?

    【讨论】:

    • 我没有,但我真的看不出它像其他两个选项一样灵活。对于几个简单的图表,它可能工作得很好,但是一旦范围可能重叠,我就会发现它变得有点管理起来的噩梦。
    • 您可以创建一个附加列,一种键,用于锚定每一行,使其始终是唯一的。然后,您可以基于此列执行约束,并在需要时将其隐藏以用于美学目的。
    猜你喜欢
    • 2017-01-31
    • 2015-11-19
    • 2016-04-16
    • 1970-01-01
    • 2013-03-10
    • 2020-09-04
    • 2023-01-20
    • 1970-01-01
    • 2017-12-27
    相关资源
    最近更新 更多