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.
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.
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.
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.
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,