1
votes

I am new to VBA and this is my first assignment, involving a pre-existing Visio drawing.

The Visio drawing consists of several shapes and I ultimately want a way to detect which shapes are cables (two "connector" shapes that are attached by a dynamic connector) using vba code. To do this, 1) I want to start by storing all the shape names in an array. 2) Then, I want to cross-check that array with know names of connector shapes and create a new array of just those connector shapes. 3) Next, I would check what each connector shape is connected to and that would allow me to determine what type of cable it is (I have this part of the code complete). 4) Finally, I would assign the cable's # to one of the connector shapes (I think I have working code for this too).

I am trying to figure out how to implement Steps 1 and 2 with my existing code.

Currently I am only able to detect connected shapes when one of those shapes is selected:

Public Sub ConnectedShapes()
' Get the shapes that are at the other end of
' incoming connections to a selected shape
    Dim vsoShape As Visio.Shape
    Dim allShapes As Visio.Shapes
    Dim lngShapeIDs() As Long
    Dim intCount As Integer

    If ActiveWindow.Selection.Count = 0 Then
        MsgBox ("Please select a shape that has connections.")
        Exit Sub
    Else
        Set vsoShape = ActiveWindow.Selection(1)
    End If

    Set allShapes = ActiveDocument.Pages.Item(1).Shapes
    lngShapeIDs = vsoShape.ConnectedShapes(visConnectedShapesAllNodes, "")

    Debug.Print "   Shape selected:     ";
    Debug.Print vsoShape

    Debug.Print "   Shape(s) connected: ";
    For intCount = 0 To UBound(lngShapeIDs)
        connectedItem = allShapes.ItemFromID(lngShapeIDs(intCount)).Name
        Debug.Print connectedItem
        If InStr(1, vsoShape, "USB A - top") = 1 Then
            If InStr(1, connectedItem, "USB A Female") = 1 Then
                '    write cable's number
            ElseIf InStr(1, connectedItem, "USB Mini B") = 1 Then
                '    write cable's number
            ElseIf InStr(1, connectedItem, "USB Micro B") = 1 Then
                '    write cable's number
            ElseIf InStr(1, connectedItem, "USB C Male") = 1 Then
                '    write cable's number
            End If
        End If
    Next
End Sub

Is there a built-in function for Visio vba that would help me implement steps 1 & 2? What's the easiest way to find all the shapes in the document and store them in an array?

1

1 Answers

1
votes

Understanding your desired business logic is the first step. Your steps 1 & 2 can be a single step.

Understanding your solution space is about understanding the range of tools a programming language gives you. In this case it is about how to efficiently loop (e.g. For Each) and information containers (e.g. Collection).

Here is some example code:

Option Explicit ' Always use this at the top of a module. Always.

Function ExampleFindShapes(chosenPage as Page) as Collection
Dim foundShapes as New Collection ' Note the new part, this initialised the Collection
Dim shapeLoopIterator as Shape
Dim arrayLoopIterator as Long
Dim validShapes as Variant

    validShapes = Array("Bob", "Harry", "George")
    For each shapeLoopIterator in chosenPage.Shapes ' One way to loop through an object collection
        For arrayLoopIterator = LBound(validShapes) to UBound(validShapes) ' One way to loop through an array
            If shapeLoopIterator.Name = validShapes(arrayLoopIterator) Then
                foundShapes.Add shapeLoopIterator ' store the found shape as a reference to the shape
                'Could put something in here to break out of the loop
            End If
        Next arrayLoopIterator
    Next shapeLoopIterator
    ExampleFindShapes = foundShapes
End Function

Coding from memory as I don't have Visio installed on this machine, so Page might be something else.

I have stored a reference to the shape instead of just the name, because the collection of found shapes will be easier to use in your parts 3 & 4, instead of you having to find and reference the shapes again.

The answer gets a little more complicated if you are working with grouped shapes. I suggest a new question referencing this one if this is the case as the answer will involve recursion and passing the collection down the line which a little more complex.