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/

请尝试下一种方式:

  1. 插入一个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
  1. 在标准模块(声明区域)之上,创建一个 Private 变量:
Private clsEventCharts() As New ChartEvClass
  1. 在同一个模块中,复制下一个过程(可以被事件调用,例如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 切片标签...

  1. 也复制下一个代码。它可以用于 运行 根据 returned 标签的东西:
Sub DoSomething(strLabel As String)
    MsgBox strLabel
    'use the label to run whatever you need...
End Sub

class 代码是动态的,它应该 return 存在多少标签。

请测试它并发送一些反馈。