Listing Connections in Visio 2010

One of the best bits of Visio is the connections between shapes, but it has always been difficult to understand these connections in code.  There are connections to and from shapes, which require you to understand where you are and which way to look … at the begining or the end of a 1D connector. Visio 2010 has added some useful extra methods to the shape object which makes understanding connections much easier.  This post will show you how you can use the new GluedShapes() and ConnectedShapes() methods.

Take, for example, a network diagram where there are connections between servers and routers:

image

You may wish to list the connections at the start and end of each cable.  Previously, this would have meant inspecting the connected cell to see if was at the beginning or end of the line, but now you can use the GluedShapes() method of a shape to retrieve an array of the 2D shapes connected at one end or another with the the relevant arguments, visGluedShapesIncoming2D or visGluedShapesOutgoing2D.  The ListGluedConnections macro below displays the following in the immediate window:

Connector     Dynamic connector
              >             Router.45     router-02
              <             Server        server-01
Connector     Dynamic connector.107
              >             Router.45     router-02
              <             Server.30     server-02
Connector     Dynamic connector.108
              >             Router        router-01
              <             Server.75     server-03
Connector     Dynamic connector.109
              >             Router.91     router-03
              <             Server.30     server-02
Connector     Dynamic connector.110
              >             Router.91     router-03
              <             Server        server-01

Public Sub ListGluedConnections()
Dim shp As Visio.Shape
Dim connectorShape As Visio.Shape
Dim sourceShape As Visio.Shape
Dim targetShape As Visio.Shape
Dim aryTargetIDs() As Long
Dim arySourceIDs() As Long
Dim targetID As Long
Dim sourceID As Long
Dim i As Integer

For Each shp In Visio.ActivePage.Shapes
    If shp.OneD Then
        Debug.Print "Connector", shp.Name
        arySourceIDs = shp.GluedShapes(visGluedShapesIncoming2D, "")
        For i = 0 To UBound(arySourceIDs)
            Set sourceShape = Visio.ActivePage.Shapes.ItemFromID(arySourceIDs(i))
            If sourceShape.CellExists("Prop.NetworkName", Visio.visExistsAnywhere) Then
                Debug.Print , ">", sourceShape.Name, sourceShape.Cells("Prop.NetworkName").ResultStr("")
            End If
        Next
        aryTargetIDs = shp.GluedShapes(visGluedShapesOutgoing2D, "")
        For i = 0 To UBound(aryTargetIDs)
            Set targetShape = Visio.ActivePage.Shapes.ItemFromID(aryTargetIDs(i))
            If targetShape.CellExists("Prop.NetworkName", Visio.visExistsAnywhere) Then
                Debug.Print , "<", targetShape.Name, targetShape.Cells("Prop.NetworkName").ResultStr("")
            End If
        Next
    End If
Next

End Sub

Similarly, you may want to simply list the next connected 2D shape, effectively ignoring the cable.  In this case, you can use the new ConnectedShapes() method, with the relevant arguments visGluedShapesIncoming2D or visGluedShapesOutgoing2D, to produce an output like the following ( using the ListNextConnections macro below):

Shape         Server        server-01
              >             Router.45     router-02
              >             Router.91     router-03
Shape         Router        router-01
              <             Server.75     server-03
Shape         Server.30     server-02
              >             Router.45     router-02
              >             Router.91     router-03
Shape         Router.45     router-02
              <             Server        server-01
              <             Server.30     server-02
Shape         Server.75     server-03
              >             Router        router-01
Shape         Router.91     router-03
              <             Server        server-01
              <             Server.30     server-02

Public Sub ListNextConnections()
Dim shp As Visio.Shape
Dim connectorShape As Visio.Shape
Dim sourceShape As Visio.Shape
Dim targetShape As Visio.Shape
Dim aryTargetIDs() As Long
Dim arySourceIDs() As Long
Dim targetID As Long
Dim sourceID As Long
Dim i As Integer

For Each shp In Visio.ActivePage.Shapes
    If Not shp.OneD Then
        If shp.CellExists("Prop.NetworkName", Visio.visExistsAnywhere) Then
            Debug.Print "Shape", shp.Name, shp.Cells("Prop.NetworkName").ResultStr("")
            arySourceIDs = shp.ConnectedShapes(visConnectedShapesOutgoingNodes, "")
            For i = 0 To UBound(arySourceIDs)
                Set sourceShape = Visio.ActivePage.Shapes.ItemFromID(arySourceIDs(i))
                If sourceShape.CellExists("Prop.NetworkName", Visio.visExistsAnywhere) Then
                    Debug.Print , "<", sourceShape.Name, sourceShape.Cells("Prop.NetworkName").ResultStr("")
                End If
            Next
            aryTargetIDs = shp.ConnectedShapes(visConnectedShapesIncomingNodes, "")
            For i = 0 To UBound(aryTargetIDs)
                Set targetShape = Visio.ActivePage.Shapes.ItemFromID(aryTargetIDs(i))
                If targetShape.CellExists("Prop.NetworkName", Visio.visExistsAnywhere) Then
                    Debug.Print , ">", targetShape.Name, targetShape.Cells("Prop.NetworkName").ResultStr("")
                End If
            Next
        End If
    End If
Next

End Sub

I think this makes interrogation of connected diagrams, of all flavours, much simpler, though I would love to have similar ShapeSheet functions too!

5 Responses to “Listing Connections in Visio 2010”

  1. Constantin Says:

    Hi,

    sorry but I cannot understand why the following code give us the SOURCE IDs and not the TARGET IDs?

    > arySourceIDs = shp.ConnectedShapes(visConnectedShapesOutgoingNodes, “”)

    I think, you asking the VISIO API for all the shapes, that are connected via outgoingnodes with shp.
    Consider shp1 –> shp –> shp2

    When I say shp.ConnectedShapes(visConnectedShapesOutgoingNodes, “”), then the method returns the shp2.ID thought? And shp2 is target and not source?

    • davidjpp Says:

      Well, it’s been a while since I wrote this, but looking back at the code now, I think that you are correct – my Outgoing and Incoming could be the wrong way round.

  2. Constantin Says:

    Thank you for the answer, as a newsbie I wasn’t sure, whether I understand the Connectivity API methods.
    I would besides this like to know am I right in a following considerations. If I want to convert a BPMN diagramm(created with Visio 2010 Premium BPMN) to a *.xpdl or *.bpmn file, I could do this with the following “utilities”:
    – VISIO Connectivity API methods( e.g. iterating through shapes and query whether a shape is event, task or gateway)
    – For each Shape –> Read Visio Shape Data Information from “Shape Data” Section. There are many additional informations like Prop.BpmnTaskType etc.
    – of course I must first check, if the BPMN diagramm is correct, because it must have one start event and one end event etc., but I bought your book about VISIO Diagramm validation and this is a good reading
    What do you think about my considerations, are they correct, or am I wrong?
    Many thanks
    Constantin

    • davidjpp Says:

      I think that you could do as you intend …. provided all of the information that you need is stored in the Shape Data. In fact, I was a little surprised that an export wasn’t included for BPMN.

  3. Constantin Says:

    Maybe export will be included as soon as the BPMN xml format is stable/final and there are process engines processing the BPMN files.

    I’m doing a little bit of trial and error winth VISIO 2010 and I have for example the following shapes:

    Shape1->dragged as Task from BPMN Template,
    Shape2->dragged as Task from BPMN Template. Then changed to Standard Loop Task(UI or right click context menu)
    Shape3->dragged as Standard Loop Task from BPMN Template

    When I try to get the shape.NameU, shape.Master.NameU and shape.MasterShape.NameU for each of theese shapes, I get for

    Shape1: shape.NameU: Task, shape.Master.NameU: Task and shape.MasterShape.NameU: Sheet.5
    Shape2: shape.NameU: Task.15, shape.Master.NameU: Task and shape.MasterShape.NameU: Sheet.5
    Shape3: shape.NameU: Standard Loop Task, shape.Master.NameU: Standard Loop Task and shape.MasterShape.NameU: Sheet.5

    Maybe I could get the index from Prop.BpmnLoopType Cell, but why Shape2 property is not changed to Standard Loop Task?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

davecra.wordpress.com/

Microsoft Office Development, and more...

PowerShell.Amsterdam

Automate, Accelerate, Accurate

johnvisiomvp

Life with Visio and other Microsoft Toys!

Title (Required)

Windows Server Essentials Tips & Tricks

Nilsandrey's Weblog

Just another WordPress.com weblog

Things that Should be Easy

Every so often (too often in the IT industry) I encounter things that should have been very easy to do but turned out to be far too complicated. My favorite topics include SharePoint, .Net development, and software architecture, especially distributed systems.

Visio Guy

Shapes, Stencils, Drawings Templates, Tutorials, Tips & Developer Info for Microsoft Visio

Hannes's Virtual Earth

Tips & Tricks around Mapping and Cloud Computing

Pluralsight blog

be smart, be clear, be visual ...

%d bloggers like this: