ワークシートのシェイプ コレクション内のシェイプのインデックスは、常にその ZOrderPosition と同じですか? (原則として、特定の Shape の Index について直接問い合わせることはできません)。
いくつかのケース (最大 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: Shapes コレクション内の ZOrderPosition の非連続番号付けこれが正しくないだけでなく、Index と ZOrderPosition が順列でさえないケースを報告しました (ChartObject に関連付けられた Shape の Shapes コレクションであることに注意してください。上記とは異なる場合があります)。
編集: Excel VBA で編集: ChartObject から Shape への参照を取得する方法を参照してください。