not sure how to do this weird iteration

Started by perry59, February 08, 2017, 12:18:56 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

perry59

so here is the scenario:
I have some shapes on a page, some of them being groups.
there is one group called "big group", inside this group is another group called "small group", inside small group is a shape called "connection" with a connection point.
now in my code I found the name of the "connection" shape by querying a dynamic connector that is connected to it, that was easy enough.
What I need now though is to get the name of the "big group" that the "connection" shape is part of (two levels down).
So even though I have the name of the "connection" shape I cant see if it is part of a group (looking at its containingshape property) because I cant do an assignment like :
connectedShape = currentPage.Shapes(connection) because even though "connection" is a shape, you don't find it in currentpage.shapes because it is hidden inside a group. That's a bummer because currentPage.Shapes("shapename") is fast and easy.
So it looks like I have to iterate through EVERY shape on the page and if the shape is a group recurse through it until I find my "connection" shape. Then, looking at "connection" shapes containingshape property I can get the name of the group that "connection" shape belongs to.
However in this case it would still not be what I want because that would return the name of the "small group" and I want the name of the "big group".
So what do I do?
I hope I explained this clear enough, I could probably make a little visio drawing that would be a lot easier to understand!
Thanks
what, me worry?

wapperdude

Visio 2019 Pro

perry59

Quote from: wapperdude on February 08, 2017, 12:38:14 AM
Check shape.parent property.  https://msdn.microsoft.com/en-us/library/office/ff767790.aspx

Wapperdude

That doesn't look much different from shape.containingshape which I have been (trying) to use
what, me worry?

perry59

here is some code I've been playing with, it works ok if the groups are nested two deep, but not more.
plus it seems to continue recursing even if I find the value I want.
It just doesn't "feel" right. Seems wasteful to drill down through ALL the shapes until I find what I want, then start "drilling" back up looking for the true parent.
Also, attached a picture that might be a lot easier to understand than my explanation!

CODE
.
.
.
For Each shp2 As Visio.Shape In currentPage.Shapes
    temp2 = findShape(shp2, wireBegin1)
    If temp2 <> String.Empty Then
       Exit For
    End If
Next
.
.
.
Private Function findShape(shape As Visio.Shape, connectedShapeName As String) As String
        Dim subshape As Visio.Shape
        Dim ShapeNameU As String = shape.NameU
        Dim temp2 As String = String.Empty
        Dim shape2 As Visio.Shape

        If ShapeNameU = connectedShapeName Then
            MsgBox("bingo")
            shape2 = shape.ContainingShape

            If shape2.CellExists("Prop.name", 0) Then
                temp2 = shape2.Cells("Prop.name").Formula
            End If
            Exit Function
        End If

        If shape.Shapes.Count > 0 Then
            For Each subshape In shape.Shapes
                findShape(subshape, connectedShapeName)
                If temp2 <> String.Empty Then
                    Exit For
                End If
            Next
        End If
        Return temp2
    End Function
what, me worry?

perry59

is there anyway to select a shape by name, even if it is in a group?
what, me worry?

Nikolay

Just use the ContainingShape/Parent property.. should work just fine:


Function GetTopLevelShape(ByVal s As Shape) As Shape
    If s.ContainingShape.Type = visTypeGroup Then
        Set GetTopLevelShape = GetTopLevelShape(s.ContainingShape)
    Else
        Set GetTopLevelShape = s
    End If
End Function

perry59

Quote from: Nikolay on February 08, 2017, 11:30:32 PM
Just use the ContainingShape/Parent property.. should work just fine:


Function GetTopLevelShape(ByVal s As Shape) As Shape
    If s.ContainingShape.Type = visTypeGroup Then
        Set GetTopLevelShape = GetTopLevelShape(s.ContainingShape)
    Else
        Set GetTopLevelShape = s
    End If
End Function


I had trouble with that Nikolay, but I did have some similar code which I tweaked a little and got to working as I wanted,
here is what I finally ended up with:


For Each shp2 As Visio.Shape In currentPage.Shapes
                    ParentName = findShape(shp2, wireBegin1)
                    If ParentName <> String.Empty Then
                        Exit For
                    End If
                Next
.
.
.
Private Function findShape(shape As Visio.Shape, connectedShapeName As String) As String
        Dim subshape As Visio.Shape
        Static ShapeNameU As String = String.Empty 'this gave all kinds of headaches until I make this VAR static!
        Dim shape2 As Visio.Shape

        If shape.NameU = connectedShapeName Then
            shape2 = GetTopShape(shape)
            ShapeNameU = shape2.NameU
            Return ShapeNameU
            'Exit Function
        Else
            If shape.Shapes.Count > 0 Then
                For Each subshape In shape.Shapes
                    findShape(subshape, connectedShapeName)
                Next
            End If
        End If

        Return ShapeNameU
    End Function

    Function GetTopShape(vsoShape As Visio.Shape) As Visio.Shape
        Dim vsoShapeParent As Object
        Dim vsoShapeParentNext As Object

        vsoShapeParent = vsoShape.Parent

        If vsoShapeParent.ObjectType = Visio.VisObjectTypes.visObjTypeShape Then
            vsoShapeParentNext = vsoShapeParent.Parent
            'If vsoShapeParent's parent isn't a page, keep going up.
            If vsoShapeParentNext.ObjectType = Visio.VisObjectTypes.visObjTypePage Then
                Return vsoShapeParent
            Else
                GetTopShape(vsoShapeParent)
            End If
        End If

        Return vsoShapeParent
    End Function
what, me worry?