工作表的Shapes集合中的Shape的索引是否始终与其ZOrderPosition相同? (原则上不能直接查询给定形状的索引)。
我已经在少数情况下验证了这一点(最多有3000个形状),但我没有找到相关文档。
我已遍历整个集合,询问Index和ZOrderPosition之间可能存在的差异:
Sub dump_shapes()
' Dump information on all shapes in a Shapes collection
Dim shc As Shapes
Set shc = ActiveSheet.Shapes
Dim shp As Shape
For Each shp In shc
Dim sh2 As Shape
Set sh2 = sh2idxzosh_shc(shp)
Dim zoidx As Long
' The second argument is not actually the Index, but since we are traversing the
' whole collection, and Index and ZOrderPosition are at most permutations, we are
' covering all of the possible Indexes.
zoidx = idx2zo_shc(shc, shp.ZOrderPosition)
Next shp
End Sub
用于查询的功能如下所示。由于MsgBox中的警告从未弹出,这意味着Index = ZOrderPosition,用于评估的案例。
' Functions between the set of shapes S and the set of natural numbers N.
' O=ZOrderPosition : S -> N (function exists)
' D=From Index : N -> S (function exists)
' D^-1=Index : S -> N (function does not exist)
' f=OoD : N -> N (can be constructed; this is expected to be only a permutation,
' i.e., bijective)
' g=DoO : S -> S (can be constructed)
Function sh2idxzosh_shc(ByRef sh As Shape) As Shape
Dim shc As Shapes
Set shc = sh.Parent.Shapes
Dim zo As Long
zo = sh.ZOrderPosition
Dim sh2 As Shape
Set sh2 = shc(zo)
' g=DoO : S -> S
' Test Shape : g(S)=S for all s? If so, g=DoO=I ; D=O^-1 ; D^-1=O. Thus, the Index
' is equal to the ZOrderPosition.
' Use ZOrderPosition to test Shape : O(g(s))=O(s) for all s? I.e., OoDoO=O? If so,
' given that O is bijective, OoD=I ; D=O^-1 ; D^-1=O. Thus, the index is equal to
' the ZOrderPosition.
Dim zo2 As Long
zo2 = sh2.ZOrderPosition
If (zo2 <> zo) Then
MsgBox ("Compound ZOrderPosition: " & zo2 & ", ZOrderPosition: " & zo)
End If
Set sh2idxzosh_shc = sh2
'Set sh2 = Nothing
End Function
Function idx2zo_shc(ByRef shc As Shapes, idx As Long) As Integer
Dim sh As Shape
Set sh = shc(idx)
Dim zo As Long
zo = sh.ZOrderPosition
' f=OoD : N -> N
' Test index : f(i)=i for all i? If so, f=OoD=I ; D=O^-1 ; D^-1=O. Thus, the Index is
' equal to the ZOrderPosition.
If (zo <> idx) Then
MsgBox ("Index: " & idx & ", ZOrderPosition: " & zo)
End If
idx2zo_shc = zo
End Function
PS:我已经调整了Worksheet的ChartObjects集合的函数,并且还验证了等价Index = ZOrder。
PS2:有人可能会问这是否是任何集合的典型(或甚至保证)。在Excel VBA: non sequential numbering of ZOrderPosition in Shapes collection我报告了一个案例,其中不仅不是这样,而且Index和ZOrderPosition甚至不是排列(注意它是与ChartObject关联的Shape的Shapes集合,与上面提到的情况不同) )。
修改:请参阅Excel VBA: How to obtain a reference to a Shape from the ChartObject中的修改。
答案 0 :(得分:1)
如果您制作一组形状,则Excel表格形状的规则“ZOrderPosition = index”为** NOT **为真。例如,如果您在Zorder 1到6中具有形状“A”,“B”,“C”,“D”,“E”,“F”,那么您将形状“B”,“C”,“D”分组在一起,您将打破形状“E”和“F”的“ZOrderPosition = index”规则。如果列出形状(i),您将获得以下内容:
index ZOrder Name 1 1 "A" 2 2 "Group 1" 3 *6* "E" 4 *7* "F"
这里是获取上一个信息的代码:
Sub DebugListInfoOfShapes()
Dim i As Long
Debug.Print "Index ZOrder Name"
For i = 1 To ActiveSheet.Shapes.Count
Debug.Print i & " " _
& ActiveSheet.Shapes(i).ZOrderPosition _
& " " _
& ActiveSheet.Shapes(i).Name
Next i
End Sub
希望这能澄清你的问题!
此致,Andres
PD:如果你想看到形状“B”,“C”,“D”,你必须在组内循环,例如:ActiveSheet.Shapes(2).GroupItems(i)
用于上述情况。