Reputation: 23
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?
Upvotes: 1
Views: 1984
Reputation: 2438
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.
Upvotes: 1