捕捉图表点击事件

当我点击图表时,我需要在Excel VBA中捕获事件。

我想把图表放到最前面,但是我找不到合适的事件。

对于不在表单上的图表(单独的全屏图表),有Chart_Activate()事件。

如果图表位于某个表单上,我怎样才能打电话给同一个事件?

如果你有一个图表集合自动化,无论是在特定的图纸或整个工作簿,那么我build议你使用一个类模块来捕获,而不是通过图表绑定代码图

Jon Peltier(按照常规)详细介绍了此图表代码选项,请参阅Microsoft Excel中的图表事件 。

在一个名为CEventChart的类模块中,

 Option Explicit ' Declare object of type "Chart" with events Public WithEvents EvtChart As Chart Private Sub EvtChart_Activate() EvtChart.ChartObjects msoBringToFront End Sub 

在一个正常的模块放

 Option Explicit Dim clsEventChart As New CEventChart Dim clsEventCharts() As New CEventChart Sub Set_All_Charts() ' Enable events on sheet if it is a chart sheet If TypeName(ActiveSheet) = "Chart" Then Set clsEventChart.EvtChart = ActiveSheet End If ' Enable events for all charts embedded on a sheet ' Works for embedded charts on a worksheet or chart sheet If ActiveSheet.ChartObjects.Count > 0 Then ReDim clsEventCharts(1 To ActiveSheet.ChartObjects.Count) Dim chtObj As ChartObject Dim chtnum As Integer chtnum = 1 For Each chtObj In ActiveSheet.ChartObjects ' Debug.Print chtObj.Name, chtObj.Parent.Name Set clsEventCharts(chtnum).EvtChart = chtObj.Chart chtnum = chtnum + 1 Next ' chtObj End If End Sub Sub Reset_All_Charts() ' Disable events for all charts previously enabled together Dim chtnum As Integer On Error Resume Next Set clsEventChart.EvtChart = Nothing For chtnum = 1 To UBound(clsEventCharts) Set clsEventCharts(chtnum).EvtChart = Nothing Next ' chtnum End Sub 

然后运行Set_All_Charts,并select要将图表发送到最前面的图纸,Jon使用这些图纸事件来设置和禁用特定图纸上的图表代码

 Private Sub Worksheet_Activate() Set_All_Charts End Sub Private Sub Worksheet_Deactivate() Reset_All_Charts End Sub 

如果我理解了这个问题,我也面临同样的问题。 只要有多个重叠的图表,它们的可视化优先顺序就是ZOrder

在Excel 2003中,当select一个图表时,它就出现在前台(至less对于可视化来说,我不知道它的ZOrder是否暂时改变了)。 当图表被取消select时,其可视化优先级恢复为“正常”。

从Excel 2007开始,图表在select时不会暂时显示,因此如果它们被隐藏在其他图表(或者其他Shape )的后面,唯一的select就是将它们放在前面。 这有两个缺点:1)需要更多的点击,2)(可能有意的) ZOrder丢失。

即使是Jon Peltier在2009年5月5日的一篇文章中也提到,没有解决方法。

我尝试了一个解决scheme,基于:

  1. 检测图表的激活。
  2. 存储当前的ZOrder以备后用。
  3. 把它带到前面。
  4. 取消select图表后,恢复其原始ZOrder

这是基本的想法, 这个scheme工作得很好 ,有一些小故障。 我实际上是在brettdj引用的Jon Peltier的页面上的代码。 其中一个修改是

 Private Sub EvtChart_Activate() Application.EnableEvents = False ActivatedChart = EvtChart.name If (TypeName(EvtChart.Parent) = "ChartObject") Then ' Chart is in a worksheet Dim chObj As ChartObject Set chObj = EvtChart.Parent chObj.BringToFront Else ' Chart is in its own sheet End If Application.EnableEvents = True End Sub 

EvtChart_Deactivate使用类似的EvtChart_Deactivate 。 我希望这个想法是有用的。

在工作表中创build一个处理程序:

 Public Sub ChartSelected(ByVal Name As String) Me.ChartObjects(Name).BringToFront End Sub 

右键单击图表并selectAssign macro,然后input类似的内容

'Sheet1.ChartSelected "Chart 1"'

Chart 1Chart 1的名称。

要以编程方式分配此处理程序,请使用

 ChartObject.OnAction = "'Sheet1.ChartSelected ""Chart 1""'" 

真容易。 把这个VBA过程放到一个常规的代码模块中:

 Sub ClickChart() ActiveSheet.ChartObjects(Application.Caller).BringToFront End Sub 

将macrosClickChart分配给您想要具有此行为的所有图表。

当你点击任何一个图表时,它会被移动到表格上所有其他图表的前面。

发布后,我看到@timwilliams已经在另一个答案的评论中提出了这个build议。