在Microsoft Visio Professional 2010中,我已经分离了我在这个小代码片段中遇到的错误。在页面上是一个容纳2个形状的容器,我想在另一个循环中迭代这些形状。但是我一直收到无效的参数错误。
我对解决方案的尝试是顶部块,但它只适用于内部循环的相同定义。在外循环的第二次迭代中似乎有些东西在变化,但我不确定。我觉得它与定义For Each循环的方式有关。
Sub Nested_Loop_Error()
Dim a As Variant
Dim b As Variant
Dim lngs() As Long
'This Works
lngs = ActiveDocument.Pages(1).Shapes.ItemFromID(1).ContainerProperties.GetMemberShapes(visContainerFlagsDefault)
For a = 0 To 1
For Each b In lngs
'Do nothing
Next b
Next a
'This does not work
For a = 0 To 1
For Each b In ActiveDocument.Pages(1).Shapes.ItemFromID(1).ContainerProperties.GetMemberShapes(visContainerFlagsDefault)
MsgBox "In Loop for a=" & a
Next b
Next a
End Sub
编辑: 我一直在玩它并让它发挥作用,但我真正感兴趣的是它的工作原理。当a = 1时,第二个代码块失败,在docMyDoc.Pages行中给出一个无效参数......
以下是显示使用变量或文档变量在循环中定义ActiveDocument的区别的代码。使用调试器我无法看到docMyDoc或varMyDoc的定义方式有所不同。
Sub Nested_Loop_Error2()
Dim a As Variant
Dim b As Variant
Dim docMyDoc As Visio.Document
Dim varMyDoc As Variant
'This works
For a = 0 To 1
Set varMyDoc = ActiveDocument
For Each b In varMyDoc.Pages(1).Shapes.ItemFromID(1).ContainerProperties.GetMemberShapes(visContainerFlagsDefault)
MsgBox "Using variant, a=" & a
Next b
Next a
'This does not work
For a = 0 To 1
Set docMyDoc = ActiveDocument
For Each b In docMyDoc.Pages(1).Shapes.ItemFromID(1).ContainerProperties.GetMemberShapes(visContainerFlagsDefault)
MsgBox "Using document, a=" & a
Next b
Next a
End Sub
答案 0 :(得分:1)
使用Variant类型对编译器没有多大帮助:名为“b”的变量应为Long类型,而“a”类型为Integer。
这就是说,你没有使用“a”变量,而是重复两次你在内循环中做的事情(Msgbox),但没有其他变化。
此外,您需要引用ID为b的形状,即您没有做的。
另一个提示:不要在类型之后命名变量,而是在它们的语义之后命名。
我认为你打算做的事情就像GetMemberShapes method's reference in MSDN中的例子:
Sub Nested_Loop()
Dim lngMemberID as Long
Dim vsoShape as Visio.Shape
Dim j as Integer
For j = 0 to 1
For Each lngMemberID In ActiveDocument.Pages(1).Shapes(1).ContainerProperties.GetMemberShapes(visContainerFlagsDefault)
Set vsoShape = ActivePage.Shapes.ItemFromID(memberID)
Debug.Print vsoShape.ID
Next lngMemberID
Next j
End Sub
在这里,你的vsoShape变量将首先引用一个,然后引用另一个形状。即使您的页面中有更多形状,它也会起作用。
这是Collections和For Each循环的好东西:集合是由其他对象列表组成的特殊对象。它们有自己的方法,如Item,Count和快捷方式,例如在括号之间使用数字从集合中检索单个对象(如Pages(1))。
您对For Each的处理方法是遍历集合中的所有对象(或数组中的所有值)。
出于您的目的,我将尝试以下一般结构:
dim oPage as Visio.Page
dim oShape as Visio.Shape
dim oInnerShape as Visio.Shape
For each oPage In ActiveDocument.Pages
For each oShape in oPage.Shapes
If oShape.Master.Name = "xxx" Then ' You can check the type of the shape
For each oInnerShape In oShape
' set and compute width and height
Next oInnerShape
' set and compute width and height of the containing shape
End If
Next oShape
' Rearrange shapes
Next oPage
您可以构建一个存储形状ID,宽度和高度的数组,同时迭代形状,然后使用该数组重新排列形状。
此致
答案 1 :(得分:0)
我的计算机上没有Visio,但您确定第一个嵌套循环有效吗?
我怀疑lngs = ActiveDocument.Pages(1)...
Dim lngs() As Long
:
Excel VBA会在尝试使用arr = Array(1,2)
存储Dim arr() As Long
时抛出“类型不匹配”错误。最好关闭Dim lngs As Variant
,即使你知道它是一个Long返回的数组。
第二个嵌套循环在理论上起作用。