如何区分以编程方式创建的 charts/shapes 与工作表上的所有 charts/shapes?

How to distinguish programatically created charts/shapes from all charts/shapes on the worksheet?

我正在寻找一种方法来区分我的代码创建的图表和用户“手动”创建的图表。 如果我为图表设置特定的 name_prefix 或其他内容,则使用 chart.name 会起作用,但此 属性 对我没有用,因为名称可以由用户动态更改。我考虑过像查看形状一样查看图表并更改其 ID,但也没有成功。 我检查了 chart/shape 对象模型,但找不到 属性,我可以用它以某种方式将“我的图表”与 sheet 集合中的所有图表区分开来。

一般的想法是我用 VBA 创建一个图表,当用户激活它时,chart.activate 事件打开一个用户窗体。当用户激活我的代码创建的图表而不是激活 sheet 上的任何图表时,该用户表单应该打开。除了如何区分图表,我什么都知道。

知道如何做到这一点吗? 提前致谢!

编辑:我也考虑过在系列名称中添加一些信息,同样是前缀类型的信息。那会起作用,但再一次 - 它可以很容易地被最终用户更改,这是我想避免的。

一个可能的想法是将你的魔法值放在 MailEnvelope.Introduction 中。这是一个 VBA 可设置的字符串 属性 您可能永远不会将其用于预期目的,并且它不会在用户创建的图表的 UI 中公开。

如果你贴出你使用的代码就好了。我(只能)假设您激活了图表事件。

请尝试下一种方法,它应该适用于激活的事件,或者不适用:

  1. 复制标准模块中的下一个代码。它是一个 Sub,将分配给所有创建的图表。它可以代替(现有的)事件使用,或与事件一起使用:
Sub CreatedChart()
   Dim ch As Chart
   Set ch = ActiveSheet.ChartObjects(Application.Caller).Chart
   'you can call the form in discussion here...
   Select Case ch.Parent.Name
    Case "CrChart1", "CrChart2"
        MsgBox "Here you can do something in case of Chart 1 or Chart 2..."
    Case "CrChart3"
        MsgBox "Here you can do something in case of Chart 3..."
   End Select
End Sub
  1. 也复制模块中的下一个代码。它将创建图表并将上面的 Sub 分配给它们:
Sub testChartsCreate()
   Dim ws As Worksheet, ch As ChartObject, i As Long
   Set ws = ActiveSheet
   For i = 1 To 3
        Set ch = ws.ChartObjects.Add(left:=1, _
                    top:=10, width:=100, height:=100)
        ch.Name = "CrChart" & i
        ws.Shapes(ch.Name).OnAction = "CreatedChart"
        ch.Chart.ChartType = xlLine
        'do here all your charts configuration...
   Next i
End Sub
  1. 您可以确定 sheet 上所有现有图表中的哪些图表是由上述代码 创建的。请注意还有一些手动创建的图表,或以编程方式创建,但不是通过上面的代码(类型)分配特定的 Sub:
Sub testIdentifCrCharts()
   Dim sh As Worksheet, ch As ChartObject, i As Long
   
   Set sh = ActiveSheet ' use here the necessary sheet
   For Each ch In sh.ChartObjects
        Debug.Print ch.Name, isCreatedChart(ch.Chart, sh)
   Next
End Sub

Private Function isCreatedChart(ch As Chart, sh As Worksheet) As Boolean
  If sh.Shapes(ch.Parent.Name).OnAction = "CreatedChart" Then
    isCreatedChart = True
  End If
End Function

我像第一个函数参数一样使用了ch As Chart,用于检查图表的情况,而不是ChartObjects...

上面的解决方案可能看起来很复杂,但实际上非常容易理解和应用。

请测试以上建议并发送一些反馈。