使用Chart BeforeDoubleClick与工作表中的图表对象


1

我试图使用Chart.BeforeDoubleClick事件让宏在工作表中的图表上工作。

我已经能够在独立的图表中使用BeforeDoubleClick事件(不使用类模块)。但我想让它在嵌入作为工作表中的对象的图表中工作。我们的想法是在单个工作表中复制多个图表。

按照本书中的建议(第172-3页),我做了以下工作:

  1. 创建了新的工作簿。在工作表Sheet1中添加了2列随机数据,并在数据旁边的同一工作表中添加了散点图。

  2. 使用代码插入名为“cl_ChartEvents”的类模块:

    Public WithEvents myChartClass As Chart
  3. 使用代码创建了一个标准模块:

    Dim myClassModule As New cl_ChartEvents
    Sub InitializeChart()
    Set myClassModule.myChartClass = _ 
    Worksheets("Sheet1").ChartObjects(1).Chart
    End Sub
  4. 在VBA编辑器中,双击“Sheet1(Sheet1)对象并插入代码:

    Private Sub MyChartClass_BeforeDoubleClick(ByVal ElementID As Long, _
        ByVal Arg1 As Long, ByVal Arg2 As Long, Cancel As Boolean)
    
    Select Case ElementID
        Case xlLegend
            Me.HasLegend = False
            Cancel = True
        Case xlAxis
            Me.HasLegend = True
            Cancel = True
        End Select
    End Sub  
  5. 单击“运行”并运行InitializeChart宏。

当我双击图表上的图例时,没有任何反应,Excel只是像往常一样打开格式图例属性框。

我已经完成了在线查看论坛等的作业,但是无法找到任何其他提示,可以实现BeforeDoubleClick事件如何在常规工作表中使用图表。书中的方法似乎表明这是可行的。

任何帮助,将不胜感激!让这个工作可以帮助很多其他人在网上看到类似的问题。谢谢。


没有接受者..想知道是否有人尝试或有任何想法?
2014年

Answers:


2

很清楚列表项#4 myChartClass中的Sheet1代码需要在类模块中,而不是在代码中。

编辑(解决'未找到成员'错误):将第4步代码修改为:

Private Sub MyChartClass_BeforeDoubleClick(ByVal ElementID As Long, _
    ByVal Arg1 As Long, ByVal Arg2 As Long, Cancel As Boolean)

    Select Case ElementID
    Case xlLegend
        Me.MyChartClass.HasLegend = False
        Cancel = True
    Case xlAxis
        Me.MyChartClass.HasLegend = True
        Cancel = True
    End Select
End Sub

唯一的变化是它们发生在两个位置MyChartClass之间Me和之间的插入HasLegend

为什么这样做:Me指的是包含类模块的实例cl_ChartEvents,它不是绑定到感兴趣的图表的实例。对象MyChartClass是绑定的对象Chart。(一个更好的名字MyChartClass可能是MyChartObj,或者某种东西。)因此,必须向下钻取Me.MyChartClass以操纵边界Chart

编辑2(提供将自定义事件处理应用于工作簿中的每个图表的代码):使用以下代码替换第3步代码:

Dim ChartColl As New Collection

Sub LinkCharts()
    Dim workCls As cl_ChartEvents
    Dim ws As Worksheet
    Dim ch As Chart, chob As ChartObject

    ' Link all standalone charts
    For Each ch In ActiveWorkbook.Charts
        ' Must create a new instance of the class for each chart
        Set workCls = New cl_ChartEvents
        ' Link each chart to the myChartClass member of the new class instance
        Set workCls.myChartClass = ch
        ' Add the new instance of the class into the Collection object
        ChartColl.Add workCls
    Next ch

    ' Link all charts in objects in sheets
    For Each ws In ActiveWorkbook.Worksheets
        For Each chob In ws.ChartObjects
            Set workCls = New cl_ChartEvents
            Set workCls.myChartClass = chob.Chart
            ChartColl.Add workCls
        Next chob
    Next ws
End Sub

Sub UnlinkCharts()
    ' Removing the cl_ChartEvents instances from the Collection causes 
    '  causes them to be destroyed by garbage collection
    Do Until ChartColl.Count = 0
        ChartColl.Remove 1
    Loop
End Sub

如果您只想要修改工作簿中的某些图表,那么解决方案就更复杂了 - 您必须找到一些方法来标记您想要修改的图表,或者您不想修改的图表,并检查每个图表当你遇到标记时,你会看到图表。但是很可行。


暖和!至少它似乎在单击图表时调用第4步代码。但是,它在“Me.HasLegend = False”上出错,编译错误说“找不到方法或数据成员”。想法?
2014年

非常感谢。你的答案中的调整工作!我实际需要的双击图表功能与此示例略有不同,但该方法似乎在正确的轨道上。将用更精细的宏进行测试并跟进。剩下的一个问题是如何使这个工作适用于多个图表/表格。它只需添加另一个模块和类模块对(将InitializeChart替换为带有ChartObjects(2)的InitializeChart2)和类模块cl_ChartEvents2。想知道是否有比每个图表复制2个模块更优雅的方法?
AS

编辑2做到了!宏只需要一个类模块和一个标准模块即可使用所有图表。非常感谢!一旦有足够的代表,也会投票。
2014年

嗨@Brian,如果你有兴趣还有另一个相关的问题:superuser.com/questions/859070 / ...
AS
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.