[Update on 2012-12-23 this post is a bit outdated. First the current URL for the project is http://visioautomation.codeplex.com. Second, for command-line automation look at the VisioPS PowerShell module and the association documentation]

 

In that quiet period between midnight and 3am I write code to relax. Over the holidays I spent a lot of time cleaning-up my Visio Automation project on CodePlex. Bugs were fixed, performance improved, and the API rationalized (Thank you JetBrains Resharper), more unit tests added. So much of this library is stable that I am now able to play a bit with it.

One project I’ve always had on my mind is a command-line interface to great graphics,diagrams, charts, etc. I drew a lot of inspiration from projects like these …

It’s not that typing on the command-line is a better way of creating diagrams, but the combination of an interactive graphics canvas (Visio) and a rich command-line experience (Python and Powershell) working together – that can be very powerful.

Instead of boring you with the details. Let’s play …

NOTE: I am running Windows 7 not Vista

Step 1 – Get the bits

Download the Visio Automation project on CodePlex and compile the solution. I’ll have a binary release soon.

Step 2 – Start the Interactive Environment

Find the VisioInteractive project and launch either the Python or Powershell interactive session with the appropriate CMD file.

image

If you click on visironpython.cmd … you’ll get a python interactive session

image

image

If you click on vispowershell.cmd … you’ll get a powershell interactive session (note that this will require Powershell v2 and this comes with Windows 7)

image

image

Run the script by clicking the green button

image

The script will run and then you can begin

image

Step 3 – Launch a new instance of Visio from the command line

Python

>>> vi.Start()

Powershell

vis> $vi.Start()

image image

This will launch a new instance of Visio 2007 that is bound to the Interactive session. When Visio launches this way a new doc will be created with a single empty page. It will also load the Basic Shapes stencil – the interactive session depends on this stencil being loaded.

image

Demo 1 – Shape formatting

Draw some shapes in visio. Then select them all.

The selection is important – most of the VisioInteractive commands work on the active selection.

image

in the interactive shell, set the fill foreground color to red

Python: vi.Fill.ForegroundColor = 0xff0000

Powershell: $vi.Fill.ForegroundColor = 0xff0000

image

Technical Note: What isn’t obvious in this example is how fast this is happening. Many of the commands use Visio’s SetFormulas() – what that means is this happens really fast when you have a lot of shapes

Now let’s make these shapes have some nice formatting.

Python

>>> vi.Fill.Pattern = 40

Powershell

vis> $vi.Fill.Pattern = 40

image

Why 40? Because that’s how the fill pattern is identified in the Fill dialog.

image

At this point I’ve going to stop giving the powershell examples, it should be obvious how to use it from the Python command.

Now, let’s take advantage of transparency.

Python

>>> vi.Fill.BackgroundTransparency = 1

image

Technical Note: 0 = no transparency and 1 = completely transparent. You can pick floating point numbers in that range.

If you deselect the shapes you’ll see they still have edges…

Python

>>> vi.Select.None()

image

select them all and clear the line

Python

>>> vi.Select.All()
>>> vi.Line.Pattern = 0
>>> vi.Line.Weight = 0
>>> vi.Select.None()

image

let’s say we want all the shapes to have the same width as the topmost circle.

Select that circle

image

save its width into a variable

Python

>>> w = vi.Size.Width

Select all the shapes and set the width

Python

>>> vi.Select.All()
>>> vi.Size.Width = w

image

What this last example illustrated is that you can retrieve values from shapes – many of the commands are properties that you can set or get.

Lets see how tall one of the shapes is by selecting it

image

>>> vi.Size.Height
0.5

as you can see it is half an inch tall.

Technical Note: reading properties only works on one shape. If you select multiple shapes and retrieve a property it will retrieve it from what Visio considers as the first selected shape

This example has shown some basic usage. Now let’s do something more fun

Demo 2 – Rendering Tabular Data

 

 

I found a page on Wikipedia recently with some nice colors and I’d like to use them in Visio.

http://en.wikipedia.org/wiki/Traditional_colors_of_Japan

image

In particular I like the Violet series

image

Select the text and copy it

image

And then get it from the clipboard

Python

>>> t = vi.Clipboard.GetHTMLTable()
>>> vi.Draw.Table( t )

and you’ll see that a new page was created with the table drawn

image

Technical note: I haven’t been able to correctly get non-ascii text to work from the clipboard but if you explore VisioInteractive you’ll see that you can get a table from an excel file and have visio draw it and this will correctly keep the non-ascii text.

Let’s zoom out a bit…

Python

>> vi.Zoom.Out()

image

and then manually remove columns not needed for this example

image

Then resize the page to fit the contents.

Python

>>> vi.Page.ResizeToFitContents()

image

Now the fun part …

Select all the hex triplet shapes

image

and set each shape color to the value of the color specified by the shape text

Python

>>> for s in vi.Selection.Enumerate() :
             t= vi.Text.PlainText
             c = int( t[1:], 16 )
             vi.Fill.ForegroundColor = c

Technical Note: vi.Selection.Enumerate() will take the current selection and one-by-one select each shape (and unselect the others). This has to be done so that the shells commands (which operate on the current selection) are targeting the correct shapes.

And the result …

image

Parting Thoughts

  • This interactive shell code is very experimental – but I’d love to get feedback from anyone on it. The core VisioAutomation library is very stable though and I don’t expect much churn before I make a new release.
  • I haven’t showed you a tenth of what this code does (creating custom properties, creating connection points, exporting all pages to an image, creating movie files, automatically drawing flowcharts and hierarchies, exporting shapesheets to an Excel file, etc.)