Mike's PowerShell Musings

Menu

PowerShell And Visio Part 5 – Connections (updated)

It’s been a while since the last post. I decided that if I had to chose between writing PowerShell and writing about PowerShell, I should favor the former.

In this episode, I’ll talk about how to create connections between objects in a Visio diagram. Turns out it’s not really that hard (just like most things with Visio so far), but there some interesting things we can do with the connections once they exist.

So, to start with, let’s get a some shapes on a page. If this doesn’t look familiar, refer back to the earlier posts in this series here:

Now, we have 2 shapes ($rect1 and $rect2). To connect them, we’ll use the AutoConnect() method on one of the 2 shapes. Since Visio connectors are directional (that is, they have a start and an end), it matters which one we use.

$rect1.AutoConnect($rect2,0)

The AutoConnect() method takes three arguments:

The shape you want to connect to

The direction (relative to the first shape) you want to move the connected shape to (0 means don’t move the second shape)

The shape you want to use as a connector

In this example, we chose to not move the second shape, and used the default connector.

The result looks like this:

There are several interesting things about this connector:

It doesn’t indicate direction (you can’t tell which way the connector goes)

It’s dynamic (it will move/route as you move the two shapes)

We didn’t get a reference to it as a result of the AutoConnect() method

We’ll start by addressing the last point. Since we didn’t get a reference to the connector, how can we find it? It turns out that just about everything in Visio is a shape, so we can look at the Shapes collection on the page:

$Visio.ActivePage.Shapes | Select-Object Name

In the output, you will see (at the end) a shape called “Dynamic connector”. That’s our new connector (duh).

I picked the last one in the collection in case there were others. Visio adds to this collection as shapes are added to the list, so this should be safe.

Now that we’ve got a reference to the connector, how can we designate which end is which? In the Visio GUI, we would click the Line drop-down on the ribbon and select the arrows (or dots) that we wanted. In PowerShell, it’s a different story altogether.

First of all, there’s not an Arrows property that we can use. That would be too easy. It turns out that in Visio, everything has what’s called a ShapeSheet, which is kind of like a bunch of little spreadsheets that control every aspect of how the object behaves in Visio. Accessing cells in the ShapeSheet can be done several ways, but typically you either use the Section, Row, Column reference (SRC) or a special Named Cell. These references look something like this:

$Shape.CellsSRC($section,$row,$column)

and

$Shape.Cells('CellName')

To set the ending arrow for a connector, there’s a “named cell” called EndArrow which tells Visio what symbol to draw at the end of the connector. We’re going to set the cell to 4. The number can apparently be anywhere from 1-45 to display different arrows.

$connector.Cells('EndArrow')=4

And the resulting arrow (zoomed in so you can see it):

If we wanted the arrow to be bi-directional, we could also set the “BeginArrow” cell.

$connector.Cells('BeginArrow')=4

Ok. Now for #2. Can we change how the connector routes? I often like to use straight lines because they’re easier to follow. Change the connector to be straight, we have to resort to the ShapeSheet again. However, there’s no named cell this time (see P.S…I found names). Now, we have to know the SRC to where the cell is. In fact, for this there are 2 cells that we have to set, so we need to know both SRCs.

$connector.CellsSRC(1,23,10) = 16
$connector.CellsSRC(1,23,19) = 1

That’s pretty cryptic, right? Absolutely. It turns out with Visio, there are about 40 bajillion different constants to use. This link will help you with some, but they aren’t organized much. This page is organized a little better, but it’s still hard to know where to look. The constants in this example are:

visSectionObject = 1

visRowShapeLayout = 23

visSLORouteStyle = 10

visLORouteCenterToCenter = 16

visSLOLineRouteExt = 19

visLORouteExtStraight = 1

So that’s a mess (at least to me). How in the world do we figure these out? The easiest way is to record a macro and do what you want to find out about, then look at the VBA. The VBA code for setting a connector to a straight line looks like this:

So first of all, “Application” is the reference to the Visio instance, which we’ve been calling $Visio. ActiveDocument is a property of $Visio, so that should be easy. The rest of the fun is decoding the “vis” constants.

thanks for your prompt reply. I trolled through the reference sheets and managed to also determine that I need to set routestyle and placestyle to 6 and 16. my problem is I am unsure how to do so, i keep getting errors. I have tried

#$pages.CellSRC(1,24,8)=6
#$pages.pagelayout.Cells(‘RouteStyle’)=16

should it be $Visio.CellsSRC(1,24,8)=16 or
or $Visio.Cells(‘RouteStyle’)=16 and similar for the placestyle

It’s hard to know what’s going on without seeing the whole bit of code.

Here’s a snippet that works (in terms of not generating errors) from start to finish:
$Visio=new-object -com Visio.Application
$Visio.Documents.Add(”)
$Visio.ActivePage.Shapes(‘ThePage’).Cells(‘RouteStyle’)=16

for what it’s worth, there’s another way to get to the page’s shape sheet:
$Visio.ActivePage.PageSheet.Cells(‘RouteStyle’)=16

Hope that helps.

If it doesn’t, just email me ([email protected]). No point carrying on this extended conversation in comments.