Edit Visio Masters Programmatically…the Right Way!
If you are busy developing a Visio solution, you might run into the situation where you need to edit a Visio master using code.
Like any application that has survived the ages, Visio has its share black-magic techniques that lurk in dusky corners of the netherworld. And if you need to edit masters programmatically, be warned! You’re heading down a dark alley…
If you’ve already run into problems with this, don’t feel bad. Even experienced Visio developers get tripped-up by this one! And that’s because the correct way to do this isn’t obvious, and the obvious way to do it isn’t correct!
The Obvious Way Doesn’t Work…Kind-of
When you peruse the Visio object model, you’re likely to think that the obvious way to edit a master shape is something like this:
Dim mstCopy As Visio.Master
Dim shp As Visio.Shape
' Get a master named "Bob" from our Document stencil:
Set mst = Visio.ActiveDocument.Masters.Item("Bob")
' Get the shape inside of the master:
Set shp = mst.Shapes.Item(1)
But what happens when you run this code? Your masters change, but those changes don’t seem to percolate down to shapes on the page!
If you are programmatically altering the masters in the Document Stencil of a Visio drawing, then the instances of those masters (ie: the shapes dropped on the page) won’t reflect your changes!
However, if you save your drawing, close it, then re-open, you’ll see that your changes did indeed take effect. Yes something is happening, but not in an ideal way.
Create a Master Editing Session…duh!
Now, we don’t want to edit masters, then programmatically close and open the drawing. That just wouldn’t do! So…
The proper way to get the job done is to start an editing session. The situation is very similar to what you do when you edit a master by hand:
- Open a master window (double-click a master, or right-click and choose Edit Master > Edit Master Shape)
This creates a temporary copy of the master - Make your changes manually: format, resize, edit text, etc.
- Close the master window
- Accept your changes by responding Yes to the prompt: Update master and all of its instances?
Step 4 is the key for manual editing. You consciously must push the changes to the instances.
This is missing from our code above. It never tells Visio to push the changes to the instances in the drawing. For that matter, that simple code never really creates a copy to fiddle with in the first place!
And that’s because the right way is all very, very non-obvious!
So we mimic the manual sitaution by using the Master.Open method to create a copy of our original master, then we push the changes to the drawing by calling Master.Close. The sample code below says it all:
Sub EditMaster( ByRef mst As Vis.Master )
Dim mstCopy As Visio.Master ' an object to hold a copy of mst...
Dim shp As Visio.Shape
Set mstCopy = mst.Open
Set shp = mstCopy.Shapes(1)
' Do stuff to shp here...
shp.Text = "Example stuff"
Set shp = Nothing
mstCopy.Close()
Set mstCopy = Nothing
Set mst = Nothing
End Sub
The code above works for VB6 and VBA. Dot-netters can just remove all of the Set statements, and probably don’t really need the = Nothing stuff either, since .NET is supposed to handle clean-up all by itself.
So make use of those Master.Copy and Master.Close methods to create a master editing session. Your on-the-fly programmatic changes to Visio masters will then work just fine, and you’ll be a hero at that next status meeting!



Hi,
Nice site…
I m using com object to create org. chart and want to change color of different shape/node. How can i achieve it?
Thanks in advance
Hi Chris,
You can program Visio to change the color of a Visio shape by setting cell-formulas in the FillForegnd section of the ShapeSheet. Go to Window > Show ShapeSheet to see what I’m talking about.
Fill color cells are: FillForegnd and Fillbackgnd.
This code will change the fill of the first selected shape in a window to red:
ActiveWindow.Selection(1).Cells(“FillForegnd”).Formula = “rgb(255,0,0)”
That should get you started!
- Chris
Hello Guy,
I’m looking for a way to find out the master of a selected shape and use this name to select the same shape on another page. how can I read the name of the Master (and the position of the selected shape) and use this to select the same shape on another page?
Perhaps you have an idea or can write an article about. I would like to move or delete a shape which is on all pages on the same position with one action.
best regards,
Lisa
Hello Visio Guy,
You have very good knowledge in Visio programming and i am sure you can help me with my problem. I am creating an orgchart using Visio.Application.ActivePage.Drop(vShape, dblXLocation, dblYLocation). The chart is fine but I wanted to “arrange subordinates” “side by side” “Double Side” programmatically. How can I do so?
If it’s not possible, is there a way of mentioning the default subordinate positioning type as “side by side” “Double Side”
Jacob
Hi Jacob,
What you want to do is possible, but it’s hard to describe in just a comment. I’ll try and give you some hints here.
You need to (programmatically) select the shape that is the parent of the children to be arranged, then call the appropriate OrgChart add-on commands.
For Visio 2007, the add-on is called “OrgC11″, but you have to know which arguments to pass to it. And the arguments have changed in the past and might change in the future, so you need to be sure which version of Visio is being used.
These are found by examining the Visio UIObject, looking at the actions for the buttons in the “Organization Chart” toolbar.
A few code examples would then be:
Call Visio.Application.Addons(“OrgC11″).Run(“/toolbar_horiz1″)
Call Visio.Application.Addons(“OrgC11″).Run(“/toolbar_sidebyside2″)
Again, that is with the superior shape selected. The arguments for Run() were found by digging through the document’s CustomToolBarSets to find the AddOnName and AddOnArgs for the Organization Chart toolbar. I don’t know if those arguments will work in Visio 2003, though.
Get the Visio 2007 SDK to find out more about analyzing the User Interface.
Alternatively, you can figure out which shapes are “child” shapes of a particular org-chart box, then do your own layout on them. To determine which shapes are connected to which shapes, you’ve got to do some work. Have a look at this thread in the Visio Guy forums to get started:
How to Identify the Shapes Connected by a Specific Connector
Hi Visio Guy,
Thank you very much for your help. It worked. I searched for this in Microsoft sites and in several other sites. But only your solution worked.
Based on your advice, I tried examining the Visio UIObject, looking at the actions for the buttons in the “Organization Chart” toolbar but could not figure out how to do it. Can you throw some lights on it? I could reach up to the UIObject in object browser.
I also need to insert picture to my orgchart shape. I went through your example. It works fine from Macro. I am using VB.NET 2005. How can I do it from VB.NET. The main problem I faced is there is no “sendkey”, the sendkeys.Send function does not accept argument false after the {Enter}.
Hope I did not confuse you.
Once again Thanks for the help
Jacob
Hi Visio Guy,
Do you have any suggestions for inserting picture into visio shape from vb.net
Jacob
Hi Jacob,
Shape objects have an Import method. Just call shp.Import(filepath)
Cheers,
Chris
Hi Chris,
Thankyou for the quick response. Shape.Import(filename) is importing the file to the page not into the shape. Am i doing something wrong
Jacob
If your shape is a group (ie: shp.Shapes.Count > 0) the image should be imported into the group.
You are right. It’s getting imported. How do I achieve the same behaviour of InsertPicture i.e. when I use shape.import(…), it does not resize the picture to the height of the shape nor it aligns the picture to the left of the shape. Please help.
This is one solution I found while searching for this. It works from VBA / Macro. But I am opening Visio from my VB.NET application and setting the OrgChart.
——————————————————————————————————————————-
Dim shp As Visio.Shape
Dim adn As Visio.Addon
Set adn = Visio.Addons(“OrgC11″)
‘Loop thru your shapes
Set shp = Visio.ActivePage.Shapes(“Assistant”)
Visio.ActiveWindow.DeselectAll
Visio.ActiveWindow.Select shp, Visio.VisSelectArgs.visSelect
SendKeys “C:\Users\davidp\Pictures\anypicture.jpg{ENTER}”, True
adn.Run “/cmd=InsertPicture”
‘end loop
——————————————————————————————————————————–
Also in your previous post you have mentioned about examining the Visio UI object. Do you use some tools for it? Can you share with me how to do it?
Hi Visio Guy,
Do you have any suggestions for me
Jacob
How want to edit visio shape data programatically plz reply.
Sam,
Maybe this will help.
Also have a look around the forum, there’s a topic about something that might come close here. Good luck
Visio experts, please help!
I would like to create a macro to run the add-ons. Can someone please tell me how? Thanks!
Hi Anna,
The Visio.Application object has an add-ons collection. You can start there…
Also, for general questions, not related to the Visio Guy article, please try our forum: http://www.visguy.com/vgforum
Cheers,
Chris
Hi Visio Guyz,
I am working on a project where in I need to save the properties of master in to SQL DataBase, is there any way to accomplish this. I have done allot of googling for but did’nt any useful article hope you can help me.
Its Urgent..
Please reply
Hi,
i’m new with vba and macro. I tried to run your code but it requires me the insert macro. Can u please explain to me how to run the code. Thanks.
Hi F3,
Try this article: Just For Starters
Hi,
I draw a picture in visio. I would like to save the picture as master in stencil. Is there a way to create a new stencil and add the picture as master in it? I tried to google it and still couldnt find any way to do it. I also try to make a dummy stencil and try to edit it as what u shown above. But it still doesn’t work. Can anyone please help me out. I’m sort of stuck in here.
Thanks in advance…
Hi F3G,
This article is about programmatically editing masters.
To manually create a master, you just drag from the drawing to a stencil. It’s best to group whatever you draw first into a single shape first (Shape > Grouping > Group or Ctrl + G)
You can create a new stencil in which to create the master via:
File > Shapes > New Stencil
Or you can put the master in the “local” stencil of a document:
File > Shapes > Show Document Stencil
Stencils that open with Visio templates (as purchased from Microsoft) are non-editable. Stencils that you create open read-only when opened with a template. But you can click on the icon in the top-left corner of the stencil and choose “Edit Stencil” to make it writable.
Hi Visio Guy,
I would like to program it automatically using vba.
Hi Visio Guy,
This is a great macro concept but there is one little bit still missing and I cant seem to figure it out. I have custom built shapes with some basic stencil icons. Well when I change the Masters at the shapesheet level, manually or programicly, my icon is reduced to a garbled mess.
How do I keep my icon from changing?
Hi Robert,
1. Right click a master
2. Choose Edit Master > Master Properties…
3. Un-check: Generate icon automatically from shape data
hi
I just want to create a visio application using .net with a textbox and a image insertion. Please anyone can help me.
Hi aannuu,
That’s a pretty small question that requires a really big answer!
You might try posting your question on our Visio Guy Forum and try to be a bit more specific as to what you need to do, and what you don’t understand.