Share:

" /> Visio Guy » Create Visio Flowcharts Programmatically
Home » Code

Create Visio Flowcharts Programmatically

Submitted by on September 13, 2006 – 3:05 am | | 98369 views 43 Comments

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!

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.
CreateFlowchart.zip (28.59 KB) - 555

43 Comments »

  • 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

  • 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

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

  • 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

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

  • 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

  • Sean McPoland says:

    Wonderful….

    just what I’ve been looking for

    regards
    Sean

  • 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

  • Visio Guy says:

    Hey Thirumal,

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

    – Chris

  • 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;
    
  • 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;
            }
        }
    
  • Rakesh Kumar says:

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

    Thanks

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

  • Giancarlo says:

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

  • 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

  • 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

  • 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 | |

  • Harvey says:

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

    :(

  • Harvey says:

    Ter, I found this link:

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

    :( no more TXT or CSV in 2003 onward

  • 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 :)

  • 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

  • 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

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

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

  • 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?

  • […] 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 […]

  • Other than using the db wizards I haven’t done this kind of automation but I can see it would be worthwhile. Looks like I have something else to read about.

  • Chaitanya says:

    Hi,
    > I have an excel spreadsheet with more than 1000 lines. Basically the
    > spreadheet shows all the connections between my network elements, i.e.:Site A
    > connects to Site B with a Capacity C.
    > I want to make a visio drawing showing all the network connections between
    > all the sites and show also the capacity for each connection. The site will
    > be represented by boxes and the connections will be represented by lines with
    > a text showing the capacity.
    > Is there anyway that I can automate this in visio using my excel spreadheet.
    > I’m not very familiar with visio. I only do simple diagrams manually. If I
    > do this task manually, it will take me a long time so I would really
    > appreciate it if you can provide me tips on how to automate this.
    > Thanks
    Chaitanya

  • Sam says:

    Chaitanya,

    Wondering if you get any solutions for your case. I have kind of same situation and love to know how you did it.

    – Sam

  • wasif ali says:

    I am using Microsoft Visio as a COM object in my C# application. I want to auto arrange shapes on a Visio page. What should I code for this task? The shapes are database entities.

    userView.Shapes.SomeMethod();

    userView is name of COM object but what should SomeMethod be?

  • Visio Guy says:

    Hi Wasif,

    Try using the Layout method on a selection or a page.

    Ie:

    visPg.Layout;
    visApp.ActiveWindow.Selection.Layout;

  • Al says:

    Do you by any chance have code that creates an OrgChart from Excel of a database? Appreciate you.

    AL

  • genoki says:

    I created org chart with 300+ departments eg one Visio file with one dept org chart per page of 300+ pages .. how can I create a separate Visio file for each dept/page? I can use VBA. What would be a good process to follow? I don’t wnat to create each dept separate as that will take a very long time and this process will be repeated as people/positions come and go.

  • Swamy says:

    Hey visio guy,

    i’m trying to create network diagram using c# based on your idea.
    I like to change the page orientation from horizontal to vertical. can this be done through c# program.

    thanks in advance

  • monuogbe says:

    Hey VisioGuy,

    I’m looking for a way to generate flowcharts from data and “Create Flowchart.vbs” is my starting point. Thanks for the hard work.

    I’m using Visio 2010 professional in Developer mode. However, when I run the code, from the button or from the VBA console, I get the following error:

    Run-time error ‘-2032466967 (86db03e9)’
    Unexpected end of file.

    When I hit the “Debug” button, the code points to:

    shpNew.Cells(“Prop.Duration”). _
    Result(Visio.VisUnitCodes.visElapsedHour) = i

    Any idea what I’m doing wrong?

    Thanks again.

  • Visio Guy says:

    @monuogbe,

    Does your target shape, shpNew really have a Prop.Duration? Remember, shape data fields have a Label and a (row) Name property. “Prop.Duration” is the name. Default names are, e.g. Row_1, Row_2, Row_3.

    Name is usually hidden from the user, and Label is displayed. But when you use automation, you have to work with Name. With Developer mode on, the Define Shape Data dialog shows both Name and Label. Generally, you should make them the same, except Name can’t have spaces or special characters, so you might do something like this:

    Label: Task Duration
    Name: Task_Duration

  • Rod Visio says:

    Hi! nice sample code,
    I have run it on Visio 2013 and noticed some modifications (two) to do to run it without the Run-time error and the error 91.
    you need to change the “BASFLO_M.VSS” with “BASFLO_M.VSSX” and notice that in Visio 2013 the flowchart shape have not the Duration data on their shape data (this last remark is valid for the 2010 version).

    Now, I going beyond to Create Visio Flowcharts Programmatically based on Excel sheet.

    Please Chris,
    what is the role of “$” and “%” placed at the end of the variable
    Const FlowchartTemplateName$ = “Basic Flowchart.vst”
    Const NumShapes% = 7

    Best REgards,

  • Visio Guy says:

    % and # and $ are used to give constants types of integer, double or string.

    In VB.NET, you can declare constants with types:

    Const PI as double = 3.14159265358

    In VBA, you can’t specify the type with a reserved word. But you can do this:

    Const PI# = 3.14159265358

    Now, you can use PI or PI# in your code, it doesn’t matter as far as I know.

    Similarly:

    Const BlogTitle$ = “VisGuy”
    Dim s as String
    s = “Hello ” & BlogTitle$

  • Rod Visio says:

    Thanks so much for the explanation!

  • tejfl says:

    Hi,

    I would like to generate flow chart diagrams from my c# project. How can I do it automatically with Visio? I have ~ 100 functions, so I do not want to do it by hand.

    Thank you for your answer.

  • Adnan Haider says:

    Hi Visio Guy,
    I am doing a project for automation of entity relationship diagram in c-sharp , and I have extracted entities and their relationship from text of data requirement, and I am required to use Visio for displaying the ERD. How can I put entities in a Chen’s or crow’s foot template. And how to connect the entities with relations? Any help will be appreciated.

    Thanks for your answer in advance.

  • Kaustubh says:

    Hi Visio Guy,

    I am adding a shape on a visio page programmatically using X and Y positions. But the problem is when the visio document page orientation is landscape, shape is placed on a different position.
    I want to know if there is any way to know the orientation of page programmatically so that I can place the shape accordingly.
    I am working in C#.Net

    Thanks.
    Kaustubh

  • Visio Guy says:

    Hey Kaustubh,

    There’s no “horizontal” or “vertical” bit associated with a page, since pages can have any orientation, but you can look at the dimensions:

    Dim pw As Double, ph As Double
    Dim pg As Visio.Page
    
    Set pg = Visio.ActivePage
    pw = pg.PageSheet.CellsU(&quot;PageWidth&quot;).ResultIU '//...width in inches
    ph = pg.PageSheet.CellsU(&quot;PageHeight&quot;).ResultIU '//...height in inches
    
    If (pw > ph) Then
      Debug.Print "Landscape-ish"
    Else If (ph < pw)
      Debug.Print "Portrait-ish"
    Else '//...pw = ph
      Debug.Print "Square"
    End If
    

Leave a comment!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

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>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.

*