Pieter van der Westhuizen

Visio 2010: Writing COM add-ins in C# and VB.NET

The beauty about Add-in Express for Office is that it allows you to write add-ins for those Microsoft Office applications that you wouldn’t even have thought it possible.

In this post I’ll show you how to create an add-in for MS Visio 2010 that automatically builds an Organizational chart for Northwind Traders. Northwind has a fairly large staff turn-around, so rebuilding the organogram is a time consuming task. Using Add-in Express 2010, we’ll make this a one button-click task.

First, start a new Visual Studio 2010 ADX COM Add-in project.

Creating a COM Add-in for Visio

Complete the wizard, by selecting Visual C# as the programming language, Microsoft Office 2010 as the minimum supported Office version and Microsoft Visio as the supported application. Once the wizard has completed, switch to the AddinModule designer and add a new ADXRibbonTab component. Add a RibbonGroup to the RibbonTab and a RibbonButton to the RibbonGroup. Your Ribbon tab will look like this:

Ribbon tab

I’ve added an ImageList control to the AddinModule designer and associated it with the RibbonButton in order to set the icon for the button. The next step would be to create code to retrieve the Northwind employees from a database and to draw the organisational structure.

To do this, add the following code:

private void CreateOrganogram()
{
    double startX = 5.433071;
    double startY = 7.559055;
 
    using (SqlConnection conn = 
              new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=True"))
    {
        SqlCommand cmd = new SqlCommand("SELECT EmployeeID,FirstName,LastName, Title,ReportsTo FROM [Employees] Order By ReportsTo", 
              conn);
        conn.Open();
        SqlDataReader DataReader = cmd.ExecuteReader();
        if (DataReader.HasRows)
        {
            while (DataReader.Read())
            {
                if (DataReader.IsDBNull(4))
                {
                    Visio.Page currpage = (Visio.Page)VisioApp.ActiveWindow.Page;
                    Visio.Shape droppedShape = 
                        currpage.Drop(VisioApp.Documents["ORGCH_M.VSS"].Masters.ItemU["Executive"], startX, startY);
                    droppedShape.Text = String.Format("{0} {1}{2}{3}", DataReader.GetString(1), 
                        DataReader.GetString(2), Environment.NewLine, DataReader.GetString(3));
                    Marshal.ReleaseComObject(currpage);
                    Marshal.ReleaseComObject(droppedShape);
                    AddSubordinate(DataReader.GetInt32(0), startX, startY);
                }
            }
        }
    }
}
 
private void AddSubordinate(int employeeId, double posX, double posY)
{
    SqlConnection conn = 
             new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=True");
    SqlCommand cmd = new SqlCommand(String.Format("SELECT EmployeeID,FirstName,LastName, Title,ReportsTo" +
             " FROM [Employees] Where ReportsTo = {0} Order By ReportsTo", employeeId), conn);
    conn.Open();
 
    SqlDataReader DataReader = cmd.ExecuteReader();
    while (DataReader.Read())
    {
        if (DataReader.GetInt32(4) == 5)
        {
            posX = 7.795;
            posY = 6.73;
        }
        Visio.Page currpage = (Visio.Page)VisioApp.ActiveWindow.Page;
        Visio.Shape droppedShape = 
                       currpage.Drop(VisioApp.Documents["ORGCH_M.VSS"].Masters.ItemU["Position"], posX, posY);
        droppedShape.Text = String.Format("{0} {1}{3}{2}", DataReader.GetString(1), DataReader.GetString(2), 
                       DataReader.GetString(3), Environment.NewLine);
        Marshal.ReleaseComObject(currpage);
        Marshal.ReleaseComObject(droppedShape);
        AddSubordinate(DataReader.GetInt32(0), posX, posY);
    }
}

You need to call the CreateOrganogram method from the RibbonButtons’ OnClick event. In order to generate its OnClick handler, select the buttons’ designer and double-click on the OnClick event in the properties window. The code for the button should look like this:

private void btnCreateOrganogram_OnClick(object sender, AddinExpress.MSO.IRibbonControl control, bool pressed)
{
    CreateOrganogram();
}

Build and register your product and start up MS Visio. Create a new drawing by selecting the Organization Chart Template. Click on the Create Northwind Organogram button. The result will look like this:

Northwind Organogram

There you have it… a one-click solution in generating the Northwind organisational structure.

Thank you for reading. Until next time, keep coding!

Available downloads

Sample Visio add-in (C# and VB.NET)

You may also be interested in:

22 Comments

  • https://secure.gravatar.com/avatar/eb2ac638c1d8677414cb57b32d2f207d?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G William says:

    Im trying to build an windows application using C# .net that makes an organization chart, i was trying with Visio, and i saw its very easy using that program, the fact is that i want to display in my program with C# the Menu of the Organization Chart of Visio inside of my program, i was draging the Microsoft Visio 14.0 Drawing and i can drag the file of Visio who contains the Organization chart inside that application but once i want to modify i have necessary to open the Visio program, and i cant modify inside of my program of C# cause i dont got the menu of Visio Inside…how can i put that menu inside of my program in C#??! Am i Being understand?! Let me know any possible idea plz…
    Best regards…

  • https://secure.gravatar.com/avatar/70b9d8d2d8b0618036e606c4de7712f4?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi William,

    If I understand you correctly, it sounds like you want to use the Visio Drawing Control on a winform and show it’s toolbars/menus. Unfortunately, as far as I know, it is not possible to show the Visio toolbars and menus with winforms. I could not find any resources on the internet to prove otherwise.

    Please see item 2 on this post http://blogs.msdn.com/b/mailant/archive/2004/09/24/233928.aspx for more information.

    Good luck!

    Kind regards,
    Pieter

  • https://secure.gravatar.com/avatar/5f449cc124e21a437b95e760f8ae0e28?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Janine says:

    Hello

    please help me
    where is initialized VisioApp

    kind reggards
    janine

  • https://secure.gravatar.com/avatar/70b9d8d2d8b0618036e606c4de7712f4?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Janine,

    The VisioApp object is a property that is automatically added when creating an Add-in Express project in Visual Studio and selecting Visio as one of the supported Office applications.

    Hope this answers your question.

    Kind regards,
    Pieter

  • https://secure.gravatar.com/avatar/91d1be0a1003465c112fcaf8e8ded42d?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Luis Fernando says:

    This code doesn’t work. It doesn’t make hierarchy by “Reports to” field

  • https://secure.gravatar.com/avatar/bbd979ae5b772d0bc1f82065aa4ba146?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Eugene Astafiev says:

    Hello Luis,

    Did you try to debug the code? Do you get any exceptions?

    BTW Do you develop a standalone application or a COM add-in?

  • https://secure.gravatar.com/avatar/9f064edaffaca44aeecfdb9626cf4806?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Francisco Fernandes says:

    Hi,
    The same code does not work with Visio 2013.
    We are picking the template document path from
    string templatePath;
    if (VisioApp.Version.ToString() == “15.0”)//VIsio 2013
    templatePath = @VisioApp.Path.ToString() + “VisioContent\\1033\\ORGCH_M.VSTX”;
    else
    templatePath = @VisioApp.Path.ToString() + “1033\\ORGCH_M.VST”;
    Also have done the following changes
    Master position;
    if (VisioApp.Version.ToString() == “15.0”) //VIsio 2013
    position = doc.Masters.get_ItemU(box.Type.ToString().Replace(“Position”, “Position Belt”));
    else
    position = doc.Masters.get_ItemU(box.Type.ToString());

    However the chart is not getting displayed in VIsio 2013.
    Any tip would be appraciated.

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Francisco,

    In Visio 2013, you can use the following snippet as a starting point to build the organogram:

    private void Create()
    {
    Visio.Window activeWindow = null;
    Visio.Page currpage = null;
    Visio.Shape droppedShape = null;
    Visio.Documents documents = null;
    Visio.Document document = null;
    Visio.Masters masters = null;
    Visio.Master master = null;

    double startX = 5.433071;
    double startY = 7.559055;

    try
    {
    activeWindow = VisioApp.ActiveWindow;
    currpage = activeWindow.Page as Visio.Page;
    documents = VisioApp.Documents;

    string templatePath = VisioApp.Path + “Visio\\Content\\1033\\ORGBLT_M.VSSX”;
    document = documents.Add(templatePath);
    masters = document.Masters;
    master = masters.get_ItemU(“Executive Belt”);
    droppedShape = currpage.Drop(master, startX, startY);
    }
    finally
    {
    if (master != null) Marshal.ReleaseComObject(master);
    if (masters != null) Marshal.ReleaseComObject(masters);
    if (document != null) Marshal.ReleaseComObject(document);
    if (documents != null) Marshal.ReleaseComObject(documents);
    if (droppedShape != null) Marshal.ReleaseComObject(droppedShape);
    if (currpage != null) Marshal.ReleaseComObject(currpage);
    if (activeWindow != null) Marshal.ReleaseComObject(activeWindow);
    }
    }

    Hope this helps!

  • https://secure.gravatar.com/avatar/9f064edaffaca44aeecfdb9626cf4806?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Francisco Fernandes says:

    Hi,
    The addin needs the template file although it draws the Executive Belt

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Francisco,

    Andrei sent you an email about using the organization chart wizard via the command line.
    Please give that a try and let us know the result.

  • https://secure.gravatar.com/avatar/396d8aa64e2ae02216d78e6406f668bc?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Bahar says:

    Hi

    I just wanted to ask where can I find this code in vb.net?

  • https://secure.gravatar.com/avatar/ab4ec2858cfdf1e44dadf8c50fae314d?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Dmitry Kostochko (Add-in Express Team) says:

    Hi Bahar,

    We don’t have a VB.NET version of this code sample. Please use the following online converter to get VB.NET code:
    http://www.developerfusion.com/tools/convert/csharp-to-vb

    Let me know if you face any difficulties.

  • https://secure.gravatar.com/avatar/396d8aa64e2ae02216d78e6406f668bc?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Bahar says:

    Dear Dmitry Kostochko

    Hi

    Thanks a lot.I’ll give it a try and inform you the result.

    Regards

  • https://secure.gravatar.com/avatar/396d8aa64e2ae02216d78e6406f668bc?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Bahar says:

    Dear Dmitry Kostochko

    Hi
    the link didn’t work for me, instead I used other websites and for this part

    Visio.Page currpage = (Visio.Page)VisioApp.ActiveWindow.Page;

    I used both

    Dim currpage As Visio.Page = CType(VisioApp.ActiveWindow.Page,Visio.Page)

    and

    Dim currpage As Visio.Page = DirectCast(VisioApp.ActiveWindow.Page, Visio.Page)

    but I received this error: “Object reference not set to an instance of object”

    so I tried this one:

    Dim currpage As new Visio.Page
    currpage = CType(VisioApp.ActiveWindow.Page, Visio.Page)

    and again I received this error: “Microsoft.Office.Interop.Visio.PageClass.Friend Sub New()is not accessible in this context because it is friend”

    Any advice would be appreciated.

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Bahar,

    I’ve created a VB.Net version of the sample project for you. You can download it here. Before you click the “Create Northwind Organogram” button, you must create a new Visio diagram using the “Organization Chart” template.

    Hope this helps!

  • https://secure.gravatar.com/avatar/396d8aa64e2ae02216d78e6406f668bc?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Bahar says:

    Dear Pieter

    Thank you so much for your help. the sample was really helpful and my previous problem was solved.
    Since I have Visio 2013 on my computer,there is only one point, I realized that I had to change Stencil name and masters name. For example I changed droppedshape dim as below:

    Dim droppedShape As Visio.Shape = currpage.Drop(VisioApp.Documents(“ORGBLT_M.VSSX”).Masters.ItemU(“Executive Belt”), startX, startY)

    but i got this error : “Invalid document identifier”

    could you tell me what I should do

    thank you in advance

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Bahar,

    I’ve created an updated sample for you that contains code for this sample in both VB.Net and C#. I’ve tested the code with Visio 2013 and it does create the diagram.
    You can download the updated sample here.

    Hope this helps!

  • https://secure.gravatar.com/avatar/396d8aa64e2ae02216d78e6406f668bc?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Bahar says:

    Dear pieter

    Thank you so so much.new sample was fine and worked very well.

    Bahar

  • https://secure.gravatar.com/avatar/aa20d59d64b10073a9a278d9c9a0609e?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Paula says:

    Hi pieter,
    Thank your for the sample.
    I created Add-In project and added ribbon as you have outlined.
    When I run the project using F5 from Visual Studio 2010, the Viso Opens but the ribbon doesn’t show up. Is there anything else I need to do?

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Paula,

    Did you right-click on your project inside the Visual Studio Solution Explorer and select “Register ADX Project” from the context-menu?

  • https://secure.gravatar.com/avatar/a27cc09739ad9671fb40dbd3e666dad5?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Jess says:

    I tried this. it is .But how can we add images in shapes. i tried this one but i didn’t get actual solutions. Plz help me

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello Jess,

    I’m not sure what you mean exactly. But you can record a VBA macro while performing some actions in the UI and then study the macro as it reveals the objects and members involved in the actions.

Post a comment

Have any questions? Ask us right now!