• Categories

  • Archives

  • Subscribe

  • Meta

Create Visio Flowcharts Programmatically

Posted by Visio Guy on September 13th, 2006 8214 views

Read Full ArticleI hear quite often the question; "How do I do something in Visio programmatically?" Since many of those requests pertain to flowcharts and organizational charts, I thought I'd conjure up a fairly simple example that illustrates the creation of a flowchart with Visual Basic for Applications (VBA) code.

This isn't the simplest example, because I thought it would be important to show how a decision-branch might be handled.

Nevertheless, it doesn't stray too far from the core concepts that you'll need to understand in order to automate Visio diagram creation:

  • Open a template
  • Get stencils and master objects
  • Drop shapes on the page
  • Set shape text and Custom Properties
  • Connect the shapes

If you inspect the code, you'll see that the program flow directly follows the outline above.

When you run the code, you'll the code will create a simple flowchart that looks something like this:

Simple Flowchart

The decision step is artificially created at step #3. By artificially, I mean that there is no data-source or supreme ethereal logic that dictates "that a decision should be here." It's simply the product of our defined constant:

Const DecisionStepNumber% = 3

which you can change at your leisure. Just be sure that it is at least 2 less than NumShapes, or you will run in to errors!

The more complicated bits involve the decision branch. This unfortunately required some If and Select Case blocks that clutter the code to some extent. These decision blocks control how the connections are programmed, to which shapes the connections are glued, how x- and y-offsets are specified, and what the text on the connectors should be. For instance, the "No" connector connects to the right-connection point of the Decision shape, whereas the rest of the connections connect dynamically to the shapes.

Hopefully the comments in the code will explain this more clearly. Below, I've included a link to a Visio diagram with more instructions, a convenient "Draw" button in place, and a ready-to-go VBA project that you can inspect and alter to your liking!

(Download Visio file with VBA Code: CreateFlowchart.zip)

Here's the code:

Sub CreateFlowchart()

'// Step 1: get the flowchart template and stencil.
'// -------------------------------------------------
'// Define some name-constants.
'// We use 'universal names', which are usually U.S.
'// english, or short filenames, and will work for
'// non-english versions of Visio:
Const FlowchartTemplateName$ = "Basic Flowchart.vst"
Const FlowchartStencilName$ = "BASFLO_M.VSS"
Const MasterProcessName$ = "Process"
Const MasterDecisionName$ = "Decision"

'// Open a new document:
Dim doc As Visio.Document
Dim docFlowTemplate As Visio.Document
Dim docFlowStencil As Visio.Document
Set docFlowTemplate = Visio.Documents. _
Add(FlowchartTemplateName)

'// Search open documents for our flowchart stencil:
For Each doc In Visio.Documents
If (doc.Name = FlowchartStencilName) Then
Set docFlowStencil = doc
Exit For
End If
Next
Set doc = Nothing

'// Step 2: get the masters and connect.
'// ------------------------------------------------
Dim mstProcess As Visio.Master
Dim mstDecision As Visio.Master
Dim conn As Variant '//...note - not a Visio.Master

'// Get masters for Process and Decision:
Set mstProcess = _
docFlowStencil.Masters.ItemU(MasterProcessName)
Set mstDecision = _
docFlowStencil.Masters.ItemU(MasterDecisionName)

'// Get the built-in connector object. Note, it's
'// not typed as a master!
Set conn = Visio.Application.ConnectorToolDataObject

'// Step 3: Drop the masters
'// -----------------------------------------------

Const NumShapes% = 7

'// Test case to illustrate adding a decision shape.
'// Must be at least 2 less than NumShapes.
Const DecisionStepNumber% = 3

Dim i As Integer
Dim x As Double, y As Double '//...drop locations

Const dx# = 1.5
Const dy# = 1

Dim pg As Visio.Page
Dim shpNew As Visio.Shape
Dim shpLast As Visio.Shape
Dim shpConn As Visio.Shape
Dim shpDec As Visio.Shape

'// We'll draw on the first page of the document,
'// which is probably the only page in the document!
Set pg = docFlowTemplate.Pages.Item(1)

'// Note: if we use auto-layout (see end of this
'// procedure), then x- and y aren't super-critical.
'// However, some rough positioning will help auto-
'// layout to do a better job.

'// Get the center, top of the page:
x = pg.PageSheet.CellsU("PageWidth").ResultIU / 2
y = pg.PageSheet.CellsU("PageHeight").ResultIU - 1

For i = 1 To NumShapes

'// Drop a new shape - either a Process or a
'// Decision shape:
If i = DecisionStepNumber Then
Set shpNew = pg.Drop(mstDecision, x, y)
shpNew.Text = i & "?"
Set shpDec = shpNew '//...save dec. for later
Else
Set shpNew = pg.Drop(mstProcess, x, y)
shpNew.Text = "do step " & i
End If
'// Set custom properties, illustrating
'// two methods: ResultIU and Result:
shpNew.Cells("Prop.Cost").ResultIU = i
shpNew.Cells("Prop.Duration"). _
Result(Visio.VisUnitCodes.visElapsedHour) = i
'// Connect shapes:
If (i <> 1) Then
'// Drop a connector on the page:
Set shpConn = pg.Drop(conn, 0, 0)
'// Glue the connector to shpLast and shpNew:
'// Note about glueing: By glueing to the PinX
'// or PinY of a shape, we get 'Dynamic Glue'
'// automatically. For the 'No' on the Decision
'// shape, we specifically glue to the
'// connection point on the right side of
'// the shape.
'// First, the Begin cell of the connector,
'// glued conditionally to shpLast:
If (i = DecisionStepNumber + 1) Then
'// Glue to the right side:
Call shpConn.CellsU("BeginX"). _
GlueTo(shpDec.CellsU("Connections.X2"))
Else
'// Glue dynamically:
Call shpConn.CellsU("BeginX"). _
GlueTo(shpLast.CellsU("PinX"))
End If
'// Second, the End cell of the connector,
'// glued dynamically to shpNew:
Call shpConn.CellsU("EndX"). _
GlueTo(shpNew.CellsU("PinX"))
End If
'// Set-up variables for the next round.
Set shpLast = shpNew
'// x, y, and shpLast depend on our
'// decision-branch:
Select Case i
Case DecisionStepNumber
x = x + dx
Case (DecisionStepNumber + 1)
x = x - dx
y = y - dy
shpConn.Text = "No"
Set shpLast = shpDec
Case Else
y = y - dy
End Select
Next i

'// Step 4: Layout the shapes and deselect.
'// ------------------------------------------------

'// Page-layout is one simple call, but look and
'// see what our x and y drops have done first,
'// then uncomment the next line:
'pg.Layout

'// Deselect all shapes, so it looks better:
Visio.ActiveWindow.DeselectAll

'// Tile the windows so the user doesn't freak out!
Call Visio.Windows. _
Arrange(Visio.visArrangeTileVertical)
End Sub

Interesting flowchart links:

  • CVF 3.0 Code Visual to Flowchart. A source-code flowcharting tool from Fatesoft.
  • Fast Flowcharts An article from Mai-lan's blog about using Visio's mutli-form "Flowchart shapes" master.
  • Unistep Software for animating process flow, uml sequence and other types of Visio flowcharts.
  • John Marshall's excellent collection of Visio 3rd Party links. Search for 'flow' and you'll get lots of results!
  • A nice user tutorial from Informit.com on creating Visio flowcharts and using custom properties, but also dabbles in ShapeSheet and report-generation.
Share this article!

These icons link to social bookmarking sites where readers can share and discover new web pages.

  • StumbleUpon
  • Digg
  • del.icio.us
  • Technorati
  • YahooMyWeb
  • Slashdot

Related Posts:

26 Responses to “Create Visio Flowcharts Programmatically”

  1. eLiz Says:

    Hallo Chris,

    Lob für die klasse Seite und die hilfreichen Tipps immer.
    Ich habe hier die Automation für ein Flowchart gefunden und bin gerade auf der Suche für ein ähnliches Problem. Ich möchte noch einen Schritt weiter gehen und die nach dem Flowchart (für einen Applikation) entstandenen Wireframes automatisch als Miniaturen in einem Screenflow abbilden. Momentan muss jede Seite einzeln in eine externe Visio-Datei gebettet werden.
    Gibts da einen Trick -> Ohne VBA zu können?

    vielen Dank und weiter so
    eLiz

  2. Visio Guy Says:

    Hallo Eliz,

    Wie ich das verstehe, du moechtest jedes Blatt eines Dokus als Shape in einem Flussdiagramm verwenden.

    Ich wuerde das so machen:

    1. Ein ganzes Blatt kopieren
    2. Als metafile paste-n. (Ueber die Menues: Bearbeiten > Paste Special > Als Picture)
    3. Als metafile kann mann das Resultat als Shape benutzen. Ist sehr einfach klein anzupassen.

    Hoffentlich hilft’s!

    - Chris

  3. Dirk Says:

    This works for connecting one shape to one other shape. How would you create a flow diagram that has the following. When step 1 is done, steps 2, 3 and 4 can all start. They are not dependant on each other.

  4. Visio Guy Says:

    Hey Dirk,

    Look at the decision diamnond — “3?”. There are two connectors coming out of that going to different shapes. Is that what you are talking about?

    Or perhaps you need to use a “Parallel mode” shape on the “Basic Flowchart Shapes” stencil. This shape has four built-in connectors that change the automation picture slightly. Attaching them per-code is a little bit different. Let me know if that’s what you want to use.

    - Chris

  5. Dirk Says:

    Chris,

    Using you diagram, if I want to connect step 4 to step 5 how do I connect them without having to save the shape information like in “Set shpDec = shpNew ‘//…save dec. for later”. In my application I have a few hundred shapes to connect and would like to not have to store the shape information of all of them in case I need it later to connect two shapes.

  6. Visio Guy Says:

    Hi Dirk,

    You would have to have some sort of way to identify the shape on the Visio page. One way to do this is to save a shape’s ID (ala: visShp.ID — integer) That’s perhaps a bit less overhead than keeping the whole shape object around.

    You can then find the shape like this: visPg.Shapes.Item(id)

    Or you could search all the shapes on a page and find their text using the visShp.Text property.

    Hope this gets you started anyway…

    - Chris

  7. Sean McPoland Says:

    Wonderful….

    just what I’ve been looking for

    regards
    Sean

  8. Thirumal Says:

    Unable to download CreateFlowchart.zip.
    Appreciate, if you could email this zip file, so that I can test it and use.

    Thanks.
    Thiru

  9. Visio Guy Says:

    Hey Thirumal,

    Try it again. There was a case-sensitive problem with the link. Should work now.

    - Chris

  10. Rakesh Kumar Says:

    Hi, nice example.

    I am working on a .NET application that uses Visio to show flowcharts. I want the dynamic grids to be seen once a shape is dropped. I am doing the following but it doesn’t work.

    Page.Document.SnapEnabled = true;
    Page.Document.GlueEnabled = true;
    Page.Document.DynamicGridEnabled = true;
    Page.Document.GlueSettings = VisGlueSettings.visGlueToGuides |
    VisGlueSettings.visGlueToConnectionPoints;
    Page.Document.SnapSettings
    VisSnapSettings.visSnapToGrid | VisSnapSettings.visSnapToGeometry |
    VisSnapSettings.visSnapToGuides | VisSnapSettings.visSnapToRulerSubdivisions |
    VisSnapSettings.visSnapToConnectionPoints;
    Page.Document.SnapExtensions
    VisSnapExtensions.visSnapExtCenterAxes | VisSnapExtensions.visSnapExtLinearExtension;

  11. Visio Guy Says:

    Hi RK,

    Looks fairly good to me. I’m not sure what your “Page” object is, and it appears you are missing a few “=”, but this might just be the blog software…?

    I tried this slight-modification of your code, and it seemed to work. Note the addition of: pg.Application.Settings.DrawingAids = true; to get the drawing aids to function.

    //…

    using Vis = Microsoft.Office.Interop.Visio;

    //…

    public partial class Form1 : Form
    {

    private void Form1_Load(object sender, EventArgs e)
    {
    this.axDrawingControl1.Src = “”; //Basic Flowchart.vst”;

    Vis.Page pg = this.axDrawingControl1.Window.PageAsObj;

    // Make some sample shapes to test if the dynamic grid is working:
    pg.DrawRectangle(2, 2, 3, 2.5);
    pg.DrawRectangle(2.5, 4, 3.5, 4.5);
    pg.DrawLine(5, 5, 7, 7);

    pg.Document.SnapEnabled = true;
    pg.Document.GlueEnabled = true;
    pg.Document.DynamicGridEnabled = true;
    pg.Document.GlueSettings = Vis.VisGlueSettings.visGlueToGuides |
    Vis.VisGlueSettings.visGlueToConnectionPoints;

    pg.Document.SnapSettings =
    Vis.VisSnapSettings.visSnapToGrid | Vis.VisSnapSettings.visSnapToGeometry |
    Vis.VisSnapSettings.visSnapToGuides | Vis.VisSnapSettings.visSnapToRulerSubdivisions |
    Vis.VisSnapSettings.visSnapToConnectionPoints;

    pg.Document.SnapExtensions =
    Vis.VisSnapExtensions.visSnapExtCenterAxes | Vis.VisSnapExtensions.visSnapExtLinearExtension;

    // Turn on the Drawing Aids as well for line extensions, etc:
    pg.Application.Settings.DrawingAids = true;
    }
    }

  12. Rakesh Kumar Says:

    Yeah, it’s working.
    I missed - pg.Application.Settings.DrawingAids = true

    Thanks

  13. Giancarlo Says:

    Does anybody know or have an idea if this can be implemented with a database easily? What I’m trying to do is create a drawing from a database of relational tables for requirements gathering. So for a example a User Requirement might fulfill 1-to-many Business Requirements, and I have an table in between to show this relationship. So it looks like this:
    [BusinessRequirement]—-[BusinessToUserLink]—-[UserRequirement]

    An example of the drawing might be:

    B1–U1
    |______U2
    |__________U3

    How could I use Visio to create a visual representation of the database RECORDS, not the table design. Thanks.

  14. Giancarlo Says:

    You can also have:
    B2——
    |
    B1–U1 |
    |______U2
    |__________U3

  15. Ter Says:

    Hello,

    I came across an article that talked about Visio 2000 being able to import a .csv file from the File-Open and would create a Flowchart for you.
    The data in the excel file would look like the following:
    Shape 6.1 Global Office Locations
    Shape 6.2 Media Relations
    Shape 6.3 Business Proposals
    Shape 10 Manager Profile
    Link 1 2
    Link 1 3
    Link 1 4

    I am using Visio 2003 and it dosn’t support this ? How can i do something similar using visio 2003 ?

    -ter

  16. Harvey Says:

    Great work Visio Guy - Thanx.

    Ter, could you post the link you found regarding .csv imports?

    I’ve written some code to extract the dependencies from Microsft Access Queries and would like to integrate this into a Visio Flow Chart program.

    —-> ——> ——-> ——-
    | | ^ |
    | | | |
    Left Join Left Join Right Join Inner Join
    | | | |
    V V | |

    Of course this diagram is very simplistic compared to the 300+ interdependant objects in my Database - this is why a flow chart is necessary.

    The new Object Dependency tool in Access 2007 is helpful but not what I need. I need to see the entire chart relativity. For instance, in the above - Query 5 has a source as does Query 4 and this relationship would need to be charted as well.

    Happy hunting,

    Harvey

  17. Harvey Says:

    oops, dont put objects inside &lt or and &gt or it deletes them :(
    and the white space is removed :(
    Trying again with the code tag:

    —-> ——> ——-> ——->
    | | ^ |
    | | | |
    Left Join LJ RJ Inner Join
    | | | |
    V V | |

  18. Harvey Says:

    You may as well delete the comments they bear little meaning without the diagram.

    :(

  19. Harvey Says:

    Ter, I found this link:

    http://office.microsoft.com/en-us/visio/HA010857571033.aspx

    :( no more TXT or CSV in 2003 onward

  20. Visio Guy Says:

    CVS People,

    Go to John Marshall’s Visio page, under VBA Information. Search the page for the “Read Text” example. This might get you started. If I had any brains I’d write a CVS importer and sell it as Donate-Ware for $7.50 :)

  21. Sourabh Says:

    Hi Chris

    Your FC is looking wonderful. I got what I exactly want.
    I have two questions:

    1. I had download your utility but when I tried to run it, says that the macros are not enabled. Contact the download site.

    2. If I want to first draw the Visio Flowchart and then I want to link or play with those process boxes using VB, Do you know how to do it? If yes then please send one sort of utility which works in this way.

    Thanks
    –Sourabh

  22. SHAJIPD Says:

    Hi,

    I would like to know; how can create Container type VISIO SHAPE JUST LIKE GANTT CHART, WHICH HAS CHILD ELEMENTS ATTACHED TO PARENT FRAME. Can any one can guide me in this……..

    Thanks N Advance

    SHAJI

  23. Silly Questions Says:

    Hello Visio Guy,
    My team and I are just starting to use Visio. Some of us have never used it before, and we are having a hard time finding the meanings behind the shapes, for example what is a paper tape, a card, a loop limit? We have looked in two different books and no answers. Are these terms that are commonly used in a different world then ours? Or is there a place where I can find out this information? Thank you for your help.

  24. Nilesh Says:

    hello,

    I want to add custom properties to visio shape. i get some idea using this VB code, but in C# its not working.
    Can anybody tell me, how to add custom properties in C#.

    Thanks,
    Nilesh.

  25. John Says:

    The code you’ve got here works wonderfully, and I can tie to to a database using an array variable to populate the box names. However, how can I accommodate multiple decisions in a single flowchart (i.e., box 1 flows to box 2, which is a decision. No terminates, and yes goes to box 4, which is another decision. No for that decision terminates, and yes continues to box 5. Box 5 is another decision. No flows to Box 6, and Yes skips Box 6 and goes to 7, where Box 6 also flows.

    How much more code would I need to make that happen?

  26. Saveen Reddy's blog : Visio: Using MSAGL to Create Visio Flowcharts Programmatically Says:

    […] by Chris Roth’s post on creating flowcharts programmatically and my original post on MSAGL with Visio 2007, I’ve uploaded a new version of the VisioAutoExt […]

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

  • Tag Cloud

  • Recent Comments on Visio Guy

  • RSS The Latest from the Visio Guy Forum

  •