Excel 如何区分以编程方式创建的图表/形状与工作表上的所有图表/形状?

Excel 如何区分以编程方式创建的图表/形状与工作表上的所有图表/形状?,excel,vba,shapes,excel-charts,Excel,Vba,Shapes,Excel Charts,我正在寻找一种方法来区分由我的代码创建的图表和由用户“手动”创建的图表。 使用chart.name可以为图表设置特定的名称前缀或其他内容,但此属性对我没有用处,因为用户可以动态更改名称。我曾想过像看形状一样看图表并改变它的ID,但也没有运气。 我已经检查了图表/形状对象模型,但找不到一个属性,我可以用它来区分“我的图表”和图纸集合中的所有图表 一般的想法是,我用VBA创建一个图表,当用户激活它时,chart.activateevent会打开一个userform。当用户激活由我的代码创建的图表时,

我正在寻找一种方法来区分由我的代码创建的图表和由用户“手动”创建的图表。 使用
chart.name
可以为图表设置特定的名称前缀或其他内容,但此属性对我没有用处,因为用户可以动态更改名称。我曾想过像看形状一样看图表并改变它的ID,但也没有运气。 我已经检查了图表/形状对象模型,但找不到一个属性,我可以用它来区分“我的图表”和图纸集合中的所有图表

一般的想法是,我用VBA创建一个图表,当用户激活它时,
chart.activate
event会打开一个userform。当用户激活由我的代码创建的图表时,而不是激活工作表上的任何图表时,应打开此userform。除了如何区分图表,我什么都知道

你知道怎么做吗? 提前谢谢


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

一个可能的想法是将您的神奇价值放入
邮件信封。简介
。这是一个VBA可设置的字符串属性,您可能永远不会将其用于预期用途,并且它不会在用户创建的图表的UI中公开。

如果您发布了所使用的代码,这应该很好。我(仅)可以假设您激活了图表事件

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

  • 复制标准模块中的下一个代码。它是一个子代码,将分配给所有创建的图表。它可以代替(现有)事件使用,也可以与以下事件一起使用:
  • 也复制模块中的下一个代码。它将创建图表,并将上面的
    分配给它们:
  • 您可以识别工作表上所有现有图表中的哪些是由上述代码创建的。请注意手动创建一些图表,或以编程方式创建,但不能通过上述代码(类型)指定特定的
    Sub
  • 对于要检查的图表,我使用了与第一个函数参数类似的
    ch As Chart
    ,而不是
    ChartObjects

    上述解决方案看起来可能很复杂,但实际上很容易理解和应用


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

    将对通过编程创建的图表对象的引用添加到脚本字典中。您甚至可以使用Varptr获取一个可以用作键的内存地址,但我不确定VBA/EWxcel在后台移动对象的频率,从而使Varptr获取的值无效。这是一个有趣的想法。我对字典很感兴趣,但我以前没用过。那怎么办?我想象我将图表的特定键添加到字典中。但如果我没有弄错的话,我会把这个键和特定的图表元素联系起来,以便以后“解码”它?那本词典将存放在哪里?是否可以在会话之间检索,例如,在关闭工作簿之后?如果您需要在会话之间存储信息,那就完全不同了。我会按照@rchardtallent的建议去做。@freeflow明白了。谢谢你的想法。我一定会研究它,因为这是我还没有涉足的VBA的一部分:)也看看Chart.CodeName属性(Excel)谢谢你的想法。我试图向“MailEnvelope”赋值或从中读取值,但得到运行时错误1004“对象定义错误”。我绕不过去,也不知道这房子是干什么用的。你能再给我一些提示吗?那怎么办?我想,当我向这个属性添加值时,它会出现在这个对象中,直到它被删除为止?因此,我应该能够检查所选图表是否有mailenvelope.introduction=X,如果是真的,那么做些什么?好主意,我喜欢这种方法和创造力。我看过OnAction属性,但不知道如何使用它。但有一个问题-您是否可以在不实际运行宏的情况下将值应用于OnAction属性?您是否将其与“empty macro”一起使用,以便为该属性指定一个值,稍后可以检查该值?我只是想知道这个“空”可能会有什么潜在的问题approach@Rafa科瓦尔斯基:主要的想法是回答你的问题。我的意思是,我使用chart shape
    OnAction
    属性来区分使用上述代码创建的图表与工作表上的其他图表。但如果需要的话,它可以是二合一的。。。使用
    Application.Caller
    您可以识别按下的图表,并根据其名称执行操作,对所有图表使用一个指定的宏。我将编辑上面的
    CreatedChart()
    Sub
    ,并向您展示如何使用它来代替事件。@RafałKowalski:Updated。请单击使用上述代码创建的图表,您将看到结果。以这种(新)方式使用
    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
    
    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
    
    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