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