Every Visio shape must have a unique name in the collection that it belongs to, and to ensure this, Visio automatically one using the master name or just “Sheet”, if not an instance of a master, followed by a period (“.”) and the ID. However, a user can rename a shape, and Visio will then also update the universal name (NameU) to be the same as the Name. If a user chooses to re-name a shape a second time, then thee universal name is not updated … it remains as the original name.
To demonstrate this I drew a rectangle, then named, and re-named it:
This is the simple VBA code that was called by an Action in the shape:
Public Sub ShapeNames(ByRef shape As Visio.shape)
Dim txt As String
txt = "ID = " & shape.ID
txt = txt & vbCrLf & "Name = " & shape.Name
txt = txt & vbCrLf & "NameID = " & shape.NameID
txt = txt & vbCrLf & "NameU = " & shape.NameU
MsgBox txt
End Sub
So, there can be several ways to reference a shape, but be aware when they can be used. For example, the Name cannot be directly typed into a ShapeSheet formula, but the NameU can.
If the NameID is used in a ShapeSheet formula, then it will be automatically re0displayed with the NameU.
Interestingly, either the NameID, NameU or Name can be used if using the EVALTEXT(…) function is used.
In VBA, or other code, then the shape can be referenced by either the NameID or Name, but not by the NameU value. The shape can also be referenced with ID value using the ItemFromID function.
?ActivePage.Shapes("Sheet.1").NameU
Shape A
?ActivePage.Shapes("Shape B").NameU
Shape A
?ActivePage.Shapes.ItemFromID(1).NameU
Shape A
If the Name is deleted using the Shape Name dialog, then the Name is reverted to the NameID, but the NameU still remains unchanged.
The universal name, NameU, was created so that the Visio UI could display a language specific Name value whilst maintaining a language independent NameU in the background.
Code can be used to update the NameU, provided that it is a unique name within the collection.
Every shape can also have a globally unique id (guid for short), which can be created, read or deleted with the various parameters passed to the UniqueID property of a shape (or PageSheet or DocumentSheet). This could be used to name a shape, as in the following VBA code:
Public Sub NameShapesOnPageWithGuid() Dim shp As Visio.Shape For Each shp In ActivePage.Shapes shp.Name = shp.UniqueID(Visio.VisUniqueIDArgs.visGetOrMakeGUID) Debug.Print shp.ID, shp.NameU, shp.Name Next End Sub
This could display something like the following in the Immediate Window:
1755 {04168AB4-2442-40AC-85A2-402B6B6EB97B} {04168AB4-2442-40AC-85A2-402B6B6EB97B}
2067 WBS_2 {14FA6C60-3476-4904-A35C-B4F8568E8EDF}
2070 WBS_2.5 {F7BE8598-C994-4E4B-8691-EDA7573D9D88}
2097 WBS_2.5.2 {53651EEF-1D5D-4C76-8E6B-E09BE036A922}
2112 WBS_2.5.2.1 {E318FC1A-00E5-4062-A62C-480A6E37C77A}
2143 WBS_2.5.2.2 {0DC8C127-5767-430A-B3A2-147E74F50EC6}
2174 WBS_2.5.2.3 {D11417B7-1DAA-4716-AF97-1FC0005E8C12}
2189 WBS_2.5.2.4 {558E05C0-9443-47AA-82E4-4D45866E0CE2}
2073 TASK_1016991 {81F75F38-6AC3-4864-A175-1270F1094EE5}
2077 TASK_1016994 {8CEBD7FE-757D-4A06-816F-3FB112CD0314}
2081 TASK_1017013 {B314B362-7451-4EE3-B9C8-4A38E6DDCDFB}
Notice that the first shape in the list above has the same NameU and Name, but the rest of shapes already had a custom Name, so a second attempt to create a custom Name will not update the NameU property simultaneously. The NameU property can be set in code again, if required, but remember that the Name and NameU values must be unique in the shapes collection that they are part of. In addition, they cannot be a zero-length string.
Synchronizing Visio Shape Fill Color (or almost any cell) across pages
I was recently asked how the color of one shape can be changed and for other shapes to be automatically updated to the same color … even if they are on different pages! Well, it is possible with Microsoft Visio’s awesome ShapeSheet formulas. In fact, this capability is not limited to the FillForegnd cell ……
Positioning Visio Shape Text Block with a Control Handle
I was recently asked how a control handle can be added to a Visio shape so that it can be used to re-position the text block. Fortunately, it is extremely easy to setup, and requires just two formulas to be updated in the ShapeSheet. This is a great use of the SETATREF(…) function. (more…)
Understanding Segments of Visio Geometry
I recently had to revise my understanding of the POINTALONGPATH(…) function in Visio because I was getting a #REF! error in some cases. My particular scenario requires a line with a number of vertices that are initially all in a straight line but can be moved by dragging controls around that each vertex is bound…
Custom Color Themes in Visio?
I was recently looking into custom color themes for corporate branding in desktop Microsoft Visio and became re-aware how different Visio still is from the rest of the Microsoft Office applications. A Visio page or document does not need to have any theme applied, but the documents of the other Office applications always have a…
When is a Visio Callout not a Callout?
I have been a Visio user/developer since the mid-1990’s and seen the word “callout” used as part of the name of many master shapes in Visio. The images below show five ways that the term “callout” has been applied to the name of Visio master shapes. Generally, each evolution has been an advance on the…
Using Visio Color by Value on Connectors
Data Graphics in Visio Plan 2 and Visio Professional is great, but it only enables us to use them with 2D shapes in Visio, i.e. not on connectors. So, what if you want to change the line colour of the connectors between the 2D shapes because of the data flowing between them? Well, it is…
G. Carl says
Hi. That’s interesting and might be connected to a problem I ran into. Our Visio drawing is exported to SVG, writing the shape’s Name into Title elements. Since only some Titles are wanted, we tried to reset all shape Names to an empty string via Visio VBA, but failed. Obviously, the Name property is read-only. So, one can change the Name property in the GUI, so ist should be possible with VBA, too. Could you give a hint, how that works?
David Parker says
I have added a little to the end of the post with some sample VBA code, but in short, the Name (or NameU) properties cannot have a zero-length value.
G. Carl says
Thanks a lot. So, in short, if we require the exported Title elements to be empty, it cannot be done by clearing the shape Names.
Brian says
I am importing org chart data into Visio, and want to a) rename each page of the results using the imported data, based on the portion of the organization represented, and b) use the imported data to assign shapes to specified containers on certain pages. Can either/both of these be done using VBA? I am not familiar with VBA, but I did find one site that gave some sample code to let me do a simple replacement of static parts of the page name, which makes me think perhaps more sophisticated code could do more?
David Parker says
You can certainly re-name each page in VBA. If you have an Org Chart on each page, are you wanting to use a value in the Shape Data of the top most shape to use?
Bill says
I have an Org Chart consisting of 50+ pages.
I am trying to figure out how to use shape data (Department, Manager Last name) from the top shape on each page to rename that page.
I changed the default shape that got imported using the Organization Chart wizard and the top shapes all have different Shape 1 numbers.
Any assistance in explaining how to loop through all pages and rename the page using the top shape data would be greatly appreciated!
David Parker says
You mean something like this?:
Public Sub NamePages()
Dim shp As Visio.Shape
Dim pag As Visio.Page
Dim lngShapeIDs() As Long
For Each pag In ActiveDocument.Pages
For Each shp In pag.Shapes
If shp.CellExistsU(“User.msvReplaceClass”, Visio.visExistsAnywhere) <> 0 Then
If shp.CellsU(“User.msvReplaceClass”).ResultStr(“”) = “visOrgChart” Then
lngShapeIDs = shp.ConnectedShapes(visConnectedShapesIncomingNodes, “”)
If UBound(lngShapeIDs) < 0 Then pag.Name = shp.CellsU("Prop.Name").ResultStr("") Exit For End If End If End If Next Next End Sub
Bill says
David,
Thanks for your reply! My VBA skills basically comprise of “borrowing” the code of others. Do I need to replace references in the CellExitsU(“User…” lines?
When I step thru the code, I get a 424 error on this line. I apologize for my ignorance.
For Each shp In pag.Shapes
If shp.CellExistsU(“User.msvReplaceClass”, Visio.visExistsAnywhere) 0 Then
David Parker says
Copy and pasting code can cause issues sometimes.
Check that the double quotes are plain ones. I usually go via Notepad to check that “ and ” are replaced with ” characters. Subtle but essential.
Bill says
Wow. I never would have thought to check that! Thank you – I did need to replace them.
I really appreciate your assistance.
Bill says
David,
One more question…
Do you have a recommendation of where I can find documentation to help me understand the objects and references used in Visio VBA? For example, I’ve been searching and cannot find any information regarding msvReplaceClass. What you provided to me is magic… I’d like to be able to analyze it and try to understand it but am not sure where to start.
CellExistsU(“User.msvReplaceClass”
David Parker says
Bill,
You could start by watching a couple of videos from my frind John Goldsmith: Visio, a flyby for Developers
As for a list of the reserved User-defined cell names … we have asked many times to get a list from Microsoft… Here are some of them : Custom Containers, Lists and Callouts in Visio 2010
Bill says
I have a Visio Org Chart that was imported from Excel and I did a custom import of the external data to make it available. The org chart contains 71 pages. I can’t figure out how to link data for all the pages. From the Data Tab, when I select LINK DATA, it gives the option of Selected shapes or all shapes on the page.
Is there a way to link data for the entire chart in a single step or does it require a VBA script?
Thanks.
Paul S says
Is there a way to reference another shapesheet from a text reference without using VBA? I am trying to modify the custom callouts in the Callouts stencil and need query information from the Parent Shapesheet. In the shapesheet for the callout, the User.ccParentName cell gets populated with the name of the shape that the callout is pointing to. Lets say I want to make the Leader line of the callout the same color as what it is connected to. How do I use the text that is in the User.ccParentName cell to reference that shapesheet and pull a value from a cell in that shapesheet. It would be something like the INDIRECT function in Excel, e.g. =INDIRECT(User.ccParentName & “!LineColor”).
Thanks.
David Parker says
Have checked out Adding Configure Callout functionality to Visio Callouts ?
I think you want to do the reverse?
I just tried the reverse, ie adding the new callout functionality to the older ones, and it will work.
Checkout CalloutTargetRef() Visio ShapeSheet Functions A-C ?
Paul S says
I was able to do what I wanted by using the formula:
=SETF(GETREF(Scratch.D1,User.ccParentName&”!LineColor”)
Your answer pushed me in that direction. I appreciate your very quick reply.
Thank You
David Parker says
Well done!