Excel 捕获图表上的事件单击
单击图表时,我需要在Excel VBA中捕获事件 当图表被激活时,我想把它放在前面,但我找不到合适的事件 对于不在工作表上的图表(单独的全屏图表),存在Excel 捕获图表上的事件单击,excel,vba,Excel,Vba,单击图表时,我需要在Excel VBA中捕获事件 当图表被激活时,我想把它放在前面,但我找不到合适的事件 对于不在工作表上的图表(单独的全屏图表),存在chart\u Activate()事件 当图表位于某个工作表上时,如何调用同一事件?在工作表中创建处理程序: Public子图表选中(ByVal名称作为字符串) Me.ChartObjects(名称).BringToFront 端接头 右键单击图表并选择Assign macro,然后键入如下内容 'Sheet1.Chart选中“图表1” 其中
chart\u Activate()
事件
当图表位于某个工作表上时,如何调用同一事件?在工作表中创建处理程序:
Public子图表选中(ByVal名称作为字符串)
Me.ChartObjects(名称).BringToFront
端接头
右键单击图表并选择Assign macro,然后键入如下内容
'Sheet1.Chart选中“图表1”
其中图表1
是图表的名称
要以编程方式分配此处理程序,请使用
ChartObject.OnAction = "'Sheet1.ChartSelected ""Chart 1""'"
如果您有一组图表需要自动化,无论是在特定的工作表上,还是在整个工作簿上,那么我建议您使用一个类模块来捕获,而不是逐个图表地绑定代码 Jon Peltier(按照正常情况)详细介绍了此图表代码选项,请参阅 在名为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,选中要将图表发送到前端的工作表,Jon使用这些工作表事件设置并禁用特定工作表上的图表代码
Private Sub Worksheet_Activate()
Set_All_Charts
End Sub
Private Sub Worksheet_Deactivate()
Reset_All_Charts
End Sub
如果我理解这个问题,我也会面临同样的问题。当有多个重叠图表时,它们的可视化优先级遵循
ZOrder
在Excel2003中,当一个人选择一个图表时,它出现在前台(至少为了可视化,我不知道它的ZOrder
是否被临时更改)。取消选择图表时,其可视化优先级返回“正常”
从Excel2007开始,选中图表时,图表不会临时出现在前台进行可视化,因此,如果它们隐藏在其他图表(或可能是其他Shape
s)后面,完整查看它们的唯一选项是将它们放在前面。这有两个缺点:1)需要更多的点击,2)丢失(可能是有意的)ZOrder
甚至在a中提到没有解决方法
我尝试了基于以下内容的解决方案:
ZOrder
,以备将来使用ZOrder
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\u停用使用类似的方法。
我希望这个想法有用。非常简单。将此VBA过程放入常规代码模块:
Sub ClickChart()
ActiveSheet.ChartObjects(Application.Caller).BringToFront
End Sub
将宏ClickChart
分配给您希望具有此行为的所有图表
当您单击任何图表时,它会移动到工作表上所有其他图表的前面
发帖后,我看到@timwilliams在对另一个答案的评论中提出了这一点。我不清楚你在找什么。如果用户单击了图表,则该图表必须已经位于最前面,否?您也可以只分配选中的图表,而不使用参数,然后使用sub中的Application.Caller获取图表名称。@JonPeltier I将上述代码复制到相应的模块中,并调用Set_All_Charts()。这工作正常,但当我调用Reset_All_Charts时,在Set clsEventChart.EvtChart=Nothing行上出现了一个编译器错误:“Variable not defined”。clsEventChart.EvtChart不是类的属性吗?将类属性设置为Nothing(相对于将类的对象设置为Nothing)意味着什么?为什么有必要。属性是静态成员吗?也许你可以从我的问题中猜到,我对VBA相当陌生。EvtChart并不完全是一种财产。它是类中声明的Chart类型的公共变量。作为类型图表,可以将其设置为实际图表,也可以不设置。错误在于您得到错误的行不属于,或者SetAllCharts需要更详细。如果工作表本身是图表,而不是常规工作表,则使用该行。我将把这个添加到我发布的代码中。@John Peltier。非常感谢你的帮助。我已经注释掉了冒犯性的行,这是有效的,但现在我明白了,哪一个更好。事件处理程序正在工作。工作得太好了,阿莫夫!哎呀,在幕后有很多激活和选择活动。我的代码中没有一个激活或选择,除非使用“set x=ActiveChart”计数。回答得很好!我将这里讨论的代码合并到一个工作演示工作簿中。这可能使许多人更容易理解这是如何工作的。不幸的是,我不能附加文件的答案,所以这里有一个链接