VBA - 点击饼图的不同切片到运行不同的宏
VBA - Click on different slices of pie chart to run different macros
不确定 VBA 是否可行,但我想将饼图的每个部分用作 运行 四个不同宏的按钮。
此外,饼图每次都会在值发生变化时重新创建(代码如下所示),因此切片的大小不固定。因此,我不认为我可以在切片顶部放置一个类似的形状并为其分配一个宏。
Public Sub CreatePieChart()
Dim ws As Worksheet
Dim ch_shape As Shape
Dim lab As DataLabel
Dim x As Long, y As Long, w As Long, h As Long
Dim circ As Shape
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set ch_shape = ws.Shapes.AddChart2
With ch_shape.Chart
With .ChartArea
.Format.Fill.ForeColor.RGB = RGB(244, 244, 244)
.Height = 300
.Width = 450
.Left = 0
.Top = 350
End With
.ChartType = xlPie
.SetSourceData ws.Range("D14:E17")
.HasTitle = False
.HasLegend = False
.ApplyDataLabels xlDataLabelsShowLabel, , , , , True, , True, , vbLf
With .FullSeriesCollection(1).DataLabels
.Position = xlLabelPositionOutsideEnd
.NumberFormat = "0.0%"
End With
End With
End Sub
您可以将其设为图表 sheet 并使用 Chart_select 事件。
Select 您的数据范围并按 F11。
将图表类型更改为圆形。
打开 VBA 编辑器并打开图表代码并粘贴以下内容:
Private Sub Chart_Select(ByVal ElementID As Long, ByVal Arg1 As Long, ByVal Arg2 As Long)
Debug.Print ElementID
Debug.Print Arg1
Debug.Print Arg2
Debug.Print ""
End Sub
这三个参数告诉您您按下了图表的哪一部分。
当我单击黄色的较大图表对象时,我得到:
3
1
4
还有蓝色:
3
1
1
我没有在其中进行更多调试,但我假设 3 是图表区域,因为如果我单击白色区域,我会得到 2,0,0。
无论如何,我认为您会找到解决您的工作案例的方法。
找到一个包含图表事件一些信息的页面https://peltiertech.com/chart-events-microsoft-excel/
请尝试下一种方式:
- 插入一个class模块并将其命名为“ChartEvClass”。复制其模块中的下一个代码:
Option Explicit
Public WithEvents EvtChart As Chart
Private Sub EvtChart_MouseUp(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long)
Dim elementId As Long, arg1 As Long, arg2 As Long
Dim arrDL, i As Long
ReDim arrDL(1 To ActiveChart.SeriesCollection(1).DataLabels.count)
For i = 1 To ActiveChart.SeriesCollection(1).DataLabels.count
arrDL(i) = Split(ActiveChart.SeriesCollection(1).DataLabels(i).Text, vbLf)(0)
Next i
With ActiveChart
.GetChartElement x, y, elementId, arg1, arg2
Call DoSomething(Application.Index(arrDL, arg2))
End With
End Sub
- 在标准模块(声明区域)之上,创建一个
Private
变量:
Private clsEventCharts() As New ChartEvClass
- 在同一个模块中,复制下一个过程(可以被事件调用,例如
Sheet_Activate
):
Sub ActivateChartsEvent()
If ActiveSheet.ChartObjects.count > 0 Then
ReDim clsEventCharts(1 To ActiveSheet.ChartObjects.count)
Dim chtObj As ChartObject, i As Long: i = 1
For Each chtObj In ActiveSheet.ChartObjects
Set clsEventCharts(i).EvtChart = chtObj.Chart
i = i + 1
Next
End If
End Sub
以上Sub
可以将事件分配给所有现有的图表。 运行 它并尝试点击图表切片进行播放。该事件将 return 切片标签...
- 也复制下一个代码。它可以用于 运行 根据 returned 标签的东西:
Sub DoSomething(strLabel As String)
MsgBox strLabel
'use the label to run whatever you need...
End Sub
class 代码是动态的,它应该 return 存在多少标签。
请测试它并发送一些反馈。
不确定 VBA 是否可行,但我想将饼图的每个部分用作 运行 四个不同宏的按钮。
此外,饼图每次都会在值发生变化时重新创建(代码如下所示),因此切片的大小不固定。因此,我不认为我可以在切片顶部放置一个类似的形状并为其分配一个宏。
Public Sub CreatePieChart()
Dim ws As Worksheet
Dim ch_shape As Shape
Dim lab As DataLabel
Dim x As Long, y As Long, w As Long, h As Long
Dim circ As Shape
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set ch_shape = ws.Shapes.AddChart2
With ch_shape.Chart
With .ChartArea
.Format.Fill.ForeColor.RGB = RGB(244, 244, 244)
.Height = 300
.Width = 450
.Left = 0
.Top = 350
End With
.ChartType = xlPie
.SetSourceData ws.Range("D14:E17")
.HasTitle = False
.HasLegend = False
.ApplyDataLabels xlDataLabelsShowLabel, , , , , True, , True, , vbLf
With .FullSeriesCollection(1).DataLabels
.Position = xlLabelPositionOutsideEnd
.NumberFormat = "0.0%"
End With
End With
End Sub
您可以将其设为图表 sheet 并使用 Chart_select 事件。
Select 您的数据范围并按 F11。
将图表类型更改为圆形。
打开 VBA 编辑器并打开图表代码并粘贴以下内容:
Private Sub Chart_Select(ByVal ElementID As Long, ByVal Arg1 As Long, ByVal Arg2 As Long)
Debug.Print ElementID
Debug.Print Arg1
Debug.Print Arg2
Debug.Print ""
End Sub
这三个参数告诉您您按下了图表的哪一部分。
当我单击黄色的较大图表对象时,我得到:
3
1
4
还有蓝色:
3
1
1
我没有在其中进行更多调试,但我假设 3 是图表区域,因为如果我单击白色区域,我会得到 2,0,0。
无论如何,我认为您会找到解决您的工作案例的方法。
找到一个包含图表事件一些信息的页面https://peltiertech.com/chart-events-microsoft-excel/
请尝试下一种方式:
- 插入一个class模块并将其命名为“ChartEvClass”。复制其模块中的下一个代码:
Option Explicit
Public WithEvents EvtChart As Chart
Private Sub EvtChart_MouseUp(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long)
Dim elementId As Long, arg1 As Long, arg2 As Long
Dim arrDL, i As Long
ReDim arrDL(1 To ActiveChart.SeriesCollection(1).DataLabels.count)
For i = 1 To ActiveChart.SeriesCollection(1).DataLabels.count
arrDL(i) = Split(ActiveChart.SeriesCollection(1).DataLabels(i).Text, vbLf)(0)
Next i
With ActiveChart
.GetChartElement x, y, elementId, arg1, arg2
Call DoSomething(Application.Index(arrDL, arg2))
End With
End Sub
- 在标准模块(声明区域)之上,创建一个
Private
变量:
Private clsEventCharts() As New ChartEvClass
- 在同一个模块中,复制下一个过程(可以被事件调用,例如
Sheet_Activate
):
Sub ActivateChartsEvent()
If ActiveSheet.ChartObjects.count > 0 Then
ReDim clsEventCharts(1 To ActiveSheet.ChartObjects.count)
Dim chtObj As ChartObject, i As Long: i = 1
For Each chtObj In ActiveSheet.ChartObjects
Set clsEventCharts(i).EvtChart = chtObj.Chart
i = i + 1
Next
End If
End Sub
以上Sub
可以将事件分配给所有现有的图表。 运行 它并尝试点击图表切片进行播放。该事件将 return 切片标签...
- 也复制下一个代码。它可以用于 运行 根据 returned 标签的东西:
Sub DoSomething(strLabel As String)
MsgBox strLabel
'use the label to run whatever you need...
End Sub
class 代码是动态的,它应该 return 存在多少标签。
请测试它并发送一些反馈。