Creating Automation Friendly Visio diagrams

About a week ago I was asked if it was possible to save the information from a hand drawing Orgchart (one done without the wizard). The simple answer was yes, but with a few caveats. It would not be an easy task to extract all the information from the diagram.


Visio allows the user two views of their diagram; the one most people are familiar with is the one that appears on the screen or the printed page; the second is what a program can “see” of the drawing through automation. What may appear logical in the diagram, may not actually be the true representation. For example, the ethernet shape in the network stencil has only eight connection points. By dropping a second ethernet shape on top of the first, it appears that there is a single ethernet shape with sixteen connection points. From the automation side, there would still be two seperate ethernet shapes.


So here are some guidelines for creating Visio diagrams, not necessarily orgcharts, so that they are more automation friendly.


The first suggestion is to standardize on the shapes. It is a lot easier for an automation routine to understand a drawing if all similar shapes have the same master. For example, most diagrams contain extra shapes in addition to the ones used for the connected diagram. There may be legends, title blocks, side comments and company identifiers. Thses shapes can be identified by the fact that they are unconnected, but it would be easier if the automation routine was looking for specific shapes.


Background pages would reduce the number of unconnected shapes on the foreground pages. It would add consistency to the drawings by making sure that common information appears in the same location on each page.


If you are creating your own shapes, keep them as simple as possible. Do not avoid grouped shapes, but make sure they are necessary. Each group shape is a collection of shapes and once one is found, this new collection of shapes has to be processed. Most shape features (connection points, custom properties and various geometry sections) can be contained in a single shape. The only real need for grouping shapes is to add secondary colours, line formats or text blocks.


One of the caveats on the drawing I saw was how was it possible to extract the name and position as seperate items from the OrgChart. Luckily in the example, though the two pieces of information are in the same text block, each had a different format (One was in bold). Using the Characters collection in Visio makes it possible to seperate the two strings. If starting from scratch, it would have been easier to use custom properties and reference the custom properties from the text block.


When connecting shapes, make sure the connection goes to the connection point on the logical shape. I have seen some shapes that appear to connected, but in fact, the free end of it’s connecting line is just sitting near one of the other lines. In another example, a group of vertically stacked individuals appear to be connected to a supervisor, but in fact each shape is connected to the shape above it rather than to the logical shape, the supervisor.


Connecting lines are 1-d shapes and have a beginning and an end. Be consistent as to whether the supervisor is at the beginning or the end of the line. I’ll leave it to the academics as to which one it should be.

Visio’s Most Useful Tool – The Macro Recorder

Finally, with the release of Visio 2003, came Visio’s most useful tool for development; the macro recorder. By clicking the record button it is possible to quickly see how various Visio tasks can be translated into VBA. The Help file that comes with Visio is useful for explaining the details of a command, but there is not enough examples explaining how to string several commands together, the macro recorder fills in this gap.


For example, to simply answer the question; “How do you create two shapes  and connect them together using VBA?” The macro recorder will generate the following macro.


Sub Macro1()


    Application.ActiveWindow.Page.DrawRectangle 1#, 10#, 2#, 9#


    Dim vsoCharacters1 As Visio.Characters
    Set vsoCharacters1 = Application.ActiveWindow.Page.Shapes.ItemFromID(1).Characters
    vsoCharacters1.Begin = 0
    vsoCharacters1.End = 0
    vsoCharacters1.Text = “John”


    Application.ActiveWindow.Page.DrawRectangle 3#, 10#, 4#, 9#


    Dim vsoCharacters2 As Visio.Characters
    Set vsoCharacters2 = Application.ActiveWindow.Page.Shapes.ItemFromID(2).Characters
    vsoCharacters2.Begin = 0
    vsoCharacters2.End = 0
    vsoCharacters2.Text = “Mary”


    Dim UndoScopeID3 As Long
    UndoScopeID3 = Application.BeginUndoScope(“Drop On Page”)
    Application.Windows.ItemEx(“atest.vsd”).Activate
    Application.ActiveWindow.Page.Drop Application.Documents.Item(“C:\DOCUME~1\John\MYDOCU~1\VISIOC~1\atest.vsd”).Masters.ItemU(“Dynamic connector”), 0#, 0#
    Dim vsoCell1 As Visio.Cell
    Dim vsoCell2 As Visio.Cell
    Set vsoCell1 = Application.ActiveWindow.Page.Shapes.ItemFromID(3).CellsU(“BeginX”)
    Set vsoCell2 = Application.ActiveWindow.Page.Shapes.ItemFromID(1).CellsSRC(1, 1, 0)
    vsoCell1.GlueTo vsoCell2
    Set vsoCell1 = Application.ActiveWindow.Page.Shapes.ItemFromID(3).CellsU(“EndX”)
    Set vsoCell2 = Application.ActiveWindow.Page.Shapes.ItemFromID(2).CellsSRC(1, 1, 0)
    vsoCell1.GlueTo vsoCell2
    Application.EndUndoScope UndoScopeID3, True


End Sub


That sure looks like a mouthful, but it can quickly reduced to a more manage size by a few simple edits.


The macro recorder will record the actions taken and the extra code required to undo the changes. This extra code is easily identified and can be quickly removed. Each block of undo code uses a variable with a name like UndoScopeIDn, where n is a number that gets incremented for each undo bloc. Each block contains three commands; a Dim, Application.BeginUndoScope and a Application.EndUndoScope statement. These statements can be removed.


The references to Application.ActiveWindow.Page can be replaced with a reference to ActivePage.


The macro recorder uses the more formal form of Shapes.ItemFromID(1), but this can be simplified to Shapes(1).


For text handling you will probably find something like:


    Set vsoCharacters1 = ActivePage.Shapes(1).Characters
    vsoCharacters1.Begin = 0
    vsoCharacters1.End = 0
    vsoCharacters1.Text = “John”


This is useful if you are manipulating the shapes text, but if, as in this case, you are replacing the entire text, this long winded block of text can be replaced with:


     ActivePage.Shapes(1).Text = “John”


Now, the macro looks like:
   
Sub Macro1()


    ActivePage.DrawRectangle 1#, 10#, 2#, 9#
    ActivePage.Shapes(1).Text = “John”


    ActivePage.DrawRectangle 3#, 10#, 4#, 9#
    ActivePage.Shapes(2).Text = “Mary”


    Application.Windows.ItemEx(“atest.vsd”).Activate
    ActivePage.Drop Application.Documents.Item(“C:\DOCUME~1\John\MYDOCU~1\VISIOC~1\atest.vsd”).Masters.ItemU(“Dynamic connector”), 0#, 0#
    Dim vsoCell1 As Visio.Cell
    Dim vsoCell2 As Visio.Cell
    Set vsoCell1 = ActivePage.Shapes(3).CellsU(“BeginX”)
    Set vsoCell2 = ActivePage.Shapes(1).CellsSRC(1, 1, 0)
    vsoCell1.GlueTo vsoCell2
    Set vsoCell1 = ActivePage.Shapes(3).CellsU(“EndX”)
    Set vsoCell2 = ActivePage.Shapes(2).CellsSRC(1, 1, 0)
    vsoCell1.GlueTo vsoCell2


End Sub


This makes it a lot easier to understand the generated code and relate it back to the information that is provided in the help file.


John… Visio MVP