Visio Constants in VisioBot3000

One of the great things about doing Office automation (that is, COM automation of Office apps) is that all of the examples are filled with tons of references to constants. A goal of VisioBot3000 was to make using those constants as easy as possible.

I mentioned the issue of having so many constants to deal with in a post over 18 months ago, but haven’t ever gotten around to showing how VisioBot3000 gives you access to some (most?) of the Visio constants.

First, here’s a snippet of code from that post:

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

which includes the following constants (except that it uses the values rather than the names):

  • visSectionObject = 1
  • visRowShapeLayout = 23
  • visSLORouteStyle = 10
  • visLORouteCenterToCenter = 16
  • visSLOLineRouteExt = 19
  • visLORouteExtStraight = 1

VisioBot3000 Constants Take 1

So, the straight-forward thing to do would be to define a variable for each of the constants like this:

$visSectionObject = 1
$visRowShapeLayout = 23
$visSLORouteStyle = 10
$visLORouteCenterToCenter = 16
$visSLOLineRouteExt = 19
$visLORouteExtStraight = 1

With those definitions (in the module, of course), we could re-write the code above like this:

$connector.CellsSRC($visSectionObject,$visRowShapeLayout,$visSLORouteStyle) = $visLORouteCenterToCenter
$connector.CellsSRC($visSectionObject,$visRowShapeLayout,$visSLOLineRouteExt) = $visLORouteExtStraight

That looks a lot less cryptic, or at least the constant names go a long way towards helping explain what’s going on.

Even better, if we had all of the Visio constants defined this way it would make translating example code (and recorded macro code) a lot easier.

Wait…there’s a problem.

There are over 2000 constants defined. Guess how long it takes PowerShell to parse and execute over 2000 assignment statements? Too long, as in several seconds.

VisioBot3000 Constants Take 2

\
So, my original approach was to take a list of Visio constants from a web page which doesn’t exist anymore (on PowerShell.com, redirects to an Idera site now). Some friendly PowerShell person had gone to the trouble of creating PowerShell assignment statements for each of the Visio constants, at least up to a point. I ended up adding a couple of dozen, but that’s a drop in the bucket. There were a whopping 2637 assignment statements.

When I added that code to the VisioBot3000 module, importing the module now took a noticeable amount of time. Another fun issue is that we just added 2637 variables to the session, which causes some fun with tab completion (think $vis….waiting…waiting).

Since that wasn’t a really good solution, I thought about what would be better.

My first thought would be an enumeration (enum in PowerShell). I thought briefly about lots of enumerations (one for each “set” of constants), but quickly discarded that idea as unusable.

A single enumeration would be an ok solution, but it would mean that VisioBot3000 only worked on PowerShell 5.0 or above. No dice (at least at this point).

I decided instead to create a single object called $Vis that had each constant as a property.

To do that, I needed a hashtable with 2637 members. I ended up using an ordered hashtable, but that doesn’t really change much.

The code in question is in the VisioConstants.ps1 file in VisioBot3000. It looks something like this:

$VIS=[Ordered]@{
#Public Enum VisArcSweepFlags 
ArcSweepFlagConcave = 0 
ArcSweepFlagConvex = 1 
#End Enum 
 
#Public Enum VisAutoConnectDir 
AutoConnectDirDown = 2 
AutoConnectDirLeft = 3 
AutoConnectDirNone = 0 
AutoConnectDirRight = 4 
AutoConnectDirUp = 1 
#End Enum 

# SNIP !!!!

#Public Enum VisDiagramServices
ServiceNone = 0
ServiceAll = -1
ServiceAutoSizePage = 1
ServiceStructureBasic = 2
ServiceStructureFull = 4
ServiceVersion140 = 7
ServiceVersion150 = 8

}
#End Enum 

$VIS=new-object PSCustomObject -Property $VIS

It turns out that the code runs quite a bit faster than the individual assignments and now there’s only one variable exposed. Intellisense is a bit slow to load the first time you do $Vis., but it’s pretty quick after that.

The re-written code above looks like this after this change:

$connector.CellsSRC($vis.SectionObject,$vis.RowShapeLayout,$vis.SLORouteStyle) = $vis.LORouteCenterToCenter
$connector.CellsSRC($vis.SectionObject,$vis.RowShapeLayout,$vis.SLOLineRouteExt) = $vis.LORouteExtStraight

It’s a tiny bit less direct, but it’s really easy to get used to.

In the spirit full disclosure, I should mention that a few of the refactored names of constants had to be quoted in order to be valid syntax in PowerShell, like these:

'1DBeginX' = 0 
'1DBeginY' = 1 
'1DEndX' = 2 
'1DEndY' = 3 

That’s enough for now. I think I’m about to start back to work on VisioBot3000…any ideas on features that would be nice to have (or are clearly missing)?

–Mike