Excel VBA: Index = ZOrderPosition en una colección de Shapes?
¿Es el índice de una forma en una colección de formas de una hoja de trabajo siempre el mismo que su ZOrderPosition? (En principio, no se puede preguntar directamente sobre el Índice de una Forma dada).
He verificado que esto es cierto en algunos casos (con hasta 3000 formas), pero no encontré documentación sobre esto.
He recorrido toda la colección, preguntando sobre posibles diferencias entre Index y 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
Las funciones utilizadas para la consulta se muestran a continuación. Dado que la advertencia en MsgBox'es nunca apareció, eso significa que Index = ZOrderPosition, para los casos evaluados.
' 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
PD: He adaptado las funciones para la colección ChartObjects de una hoja de trabajo, y también se verificó el índice de equivalencia = ZOrder.
PS2: Uno puede preguntar si esto es típico de (o incluso está garantizado) para cualquier colección. EnExcel VBA: numeración no secuencial de la colección ZOrderPosition in Shapes Informé un caso donde, no solo esto no es cierto, sino que Index y ZOrderPosition ni siquiera son permutaciones (tenga en cuenta que era la colección de Formas de la Forma asociada con un objeto ChartObject, un caso diferente al mencionado anteriormente).
Editar: Ver Editar enExcel VBA: cómo obtener una referencia a una forma desde el objeto ChartObject.