Automating Page.DropLegend in Visio 2010

Visio 2007 introduced Data Graphics but, in my opinion, didn’t provide any automatic legends for the icons and colour by value options. That is why I wrote DataLegends (see http://www.bvisual.net/Products/DataLegends.aspx ) as an add-in for Visio 2007 several years ago. This oversight was remedied in Visio 2010 when Microsoft introduced their own legends (which were not totally dissimilar to my own), and also added a method (Page.DropLegend) for programmers to automate this task.

image

Visio also has VBA built-in, and you can record actions with it too, so I recorded dropping a Vertical legend into my page, and here is the recorded macro:

Public Sub AddLegend()

    'Enable diagram services
    Dim DiagramServices As Integer
    DiagramServices = ActiveDocument.DiagramServicesEnabled
    ActiveDocument.DiagramServicesEnabled = visServiceVersion140

    Dim vsoDoc1 As Visio.Document
    Set vsoDoc1 = Application.Documents.OpenEx(Application.GetBuiltInStencilFile(visBuiltInStencilLegends, visMSMetric), visOpenHidden)
    ActivePage.DropLegend vsoDoc1.Masters.ItemU("Outer list"), vsoDoc1.Masters.ItemU("Field container"), visLegendPopulate
    
    vsoDoc1.Close

    'Restore diagram services
    ActiveDocument.DiagramServicesEnabled = DiagramServices

End Sub

So, then I deleted the legend that I had just dropped, and ran the macro. It dropped a horizontal legend … not quite what I wanted. So, I recorded dropping a horizontal legend too see if there was any difference … nope, just the same. So, the macro would be great if I always wanted a horizontal legend, but almost useless if I want a vertical one.

I examined the ShapeSheet of the containers for each orientation of the legend, and found that User.msvSDListDirection is 2 for vertical, and 1 for horizontal. However, just changing the value of after the legend has been created is no good because it has already been populated.

image

I tried using the Event Monitor from the Visio SDK to see if there was any additional parameters being passed from the ribbon, but I could not spot one, so I needed a different strategy. Closer examination of the VBA code shows that a built-in stencil is opened hidden, then two masters are used, “Outer list” and “Field container”, before the stencil is closed. Sure enough, those two masters now exist in my local document stencil, so I could modify them, and the code.

I edited the Outer list master and put the formula =GUARD(2) in the User.msvSDListDirection value cell, and then I ensured that the Match master by name on drop Behavior property was ticked. In fact, I did this for Field container, Inner list, CBV item, Icon item and Text item too. This tells Visio to use these named masters rather than add new versions in the future. The GUARD(..) function is required because it prevents the DropLegend action from forcing a 1 value into the cell.

image

I then amended the macro so it used the local copy of the masters in the DropLegend action :

Public Sub AddLegend()

    'Enable diagram services
    Dim DiagramServices As Integer
    DiagramServices = ActiveDocument.DiagramServicesEnabled
    ActiveDocument.DiagramServicesEnabled = visServiceVersion140

    ActivePage.DropLegend ActiveDocument.Masters.ItemU("Outer list"), ActiveDocument.Masters.ItemU("Field container"), visLegendPopulate
    
    'Restore diagram services
    ActiveDocument.DiagramServicesEnabled = DiagramServices

End Sub

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

I now have a macro that drops me a vertical legend as required. QED.

image

One Response to “Automating Page.DropLegend in Visio 2010”

  1. Konstantin Dolgitser Says:

    This is excellent. I was trying to solve this riddle but to no avail. Brilliant solution!! I just implemented in macro to automate generation of Org.Chart with vertical legend on a page,


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: