Site icon bVisual

Enhancing the Built-In Containers in Visio

The concept of Structured Diagrams was introduced in Visio 2010 to provide core functionality for a variety of the templates in Visio, such as the Cross-Functional Flowchart, BPMN Diagram and Wireframe Diagram. This is primarily evident as Containers, Lists and Callouts and they can be customized (see Custom Containers, List and Callouts ), as shown in some of my previous articles ( see https://blog.bvisual.net/?s=container). One example of this extension can be found in all of the flowchart shapes that placed into a swimlane in a cross-functional flowchart. They have a Shape Data row, Function, that automatically inherits the text entered into the header of the swimlane. In another example, a Visio user can use Insert / Diagram Parts / Container to visually group other shapes together, and update the header text of the container. Well, I often do want my custom shapes to inherit the text of a container, so, in this article, I show how the built-in containers can be enhanced to provide this ability.

You should be aware that I often exploit the fact that Visio creates a local copy of each master shape that it uses within a document. This can be modified and set to match master by name on drop, to ensure that it is the one to use, even if the original Microsoft provided version is used. In this case, I use this trick to create hidden, enhanced versions of the containers that are available in the gallery of containers. Microsoft also do this with the Dynamic connector shape in a number of their own templates.
If you examine the Function Shape Data row of any of the flowchart shapes, then you will find the formula:

=IFERROR(CONTAINERSHEETREF(1,"Swimlane")!User.VISHEADINGTEXT,"")

This formula will get the value of the User.visHeadingText cell in the first container, that it is within, with the category “Swimlane“.
This is possible because there is a User-defined Cell row, with the reserved name msvShapeCategories, in the Swimlane shape. This cell can store a semi-colon separated list of categories. In fact, the formula for the User.msvShapeCategories cell in the Swimlane shapes is:

="Swimlane;DoNotContain"

This means that it belongs to two categories, Swimlane and DoNotContain.
The reason why the Function Shape Data row references the User.visHeadingText cell is because the Swimlane is a group shape, and the text is actually in one if the sub-shapes, with the value in User.msvStructureType = “Heading”. Therefore, the reference is to another cell, User.visHeadingText that gets the text of a sub-shape with the following formula (where n is the ID of the sub-shape):

=SHAPETEXT(Sheet.n!TheText)

This means that the formula in any other shape just needs to get a reference to the known User.visHeadingText cell. Well, all of the built-in containers are a very similar structure to the Swimlane shape, but the User.visHeadingText cell is not always present. Therefore, my bit of VBA code below simply enhances any containers with a Heading sub-shape, so that the User.visHeadingText cell is present, and it returns the text that it finds.
It is not essential that the containers are filtered by a category, so the following formula is also valid, and would return the value in the first container, if it has a User.visHeadingText cell (casing is not important):

=IFERROR(CONTAINERSHEETREF(1)!User.VISHEADINGTEXT,"")

 
Now, all of the containers in the ribbon have the following formula in the User.msvShapeCategories cell:

="ContainerStyleDefaults"

This can be edited to store any other custom category too. So the following formula would make the container have two categories, either of which could be used as a filter:

="ContainerStyleDefaults;My Container"

It is easy to add all of the built-in containers quickly because the ribbon gallery will replace the currently selected container shape with the gallery item. The container masters will be added to the document stencil, as in the following example.

Then the EnhanceContainers macro will update all of these copies in the document stencil, and hide them from the normal stencil view too.

All that remains is to prepare the Shape Data row of any master that needs to inherit the value of the container text with the following formula:

=IFERROR(CONTAINERSHEETREF(1,"My Container")!User.VISHEADINGTEXT,"")

For example, I added the above formula into the Owner Shape Data row in the Process master shape.

 

The VBA Code

Insert one or more containers from Insert / Diagram Parts / Container into your document, delete them (not using Undo), then run the following macro. It will enhance them all.

Public Sub EnhanceContainers()
'Author : David Parker, Jul 2018, No rights reserved
'Purpose: To enhance any container masters in the active document
' to regularise the reference to the heading text
'Usage : Add the following ShapeSheet function to Shape Data rows
' =IFERROR(CONTAINERSHEETREF(1,opt_category)!User.VISHEADINGTEXT,"")
' where opt_category is an optional category,
' listed in the User.msvShapeCategories cell of the container
On Error GoTo errHandler
Dim mst As Visio.Master
Dim mstEdit As Visio.Master
Dim shp As Visio.Shape
Dim subShp As Visio.Shape
Dim strType As String
Dim strSubType As String
Dim headingSheet As String
Dim categories As String
Dim aryCats() As String
Dim newCategories As String
Dim i As Integer
Dim catExists As Boolean
Const ROWTYPE As String = "User.msvStructureType"
Const CELHDR As String = "visHeadingText"
Const ROWCAT As String = "User.msvShapeCategories"
Const CONTAINERCAT As String = "My Container"   'Optional category
Const UDCSECT As Integer = Visio.VisSectionIndices.visSectionUser
Const FLGEX As Integer = Visio.VisExistsFlags.visExistsAnywhere
For Each mst In ActiveDocument.Masters
  If mst.Shapes(1).CellExists(ROWTYPE, FLGEX) <> 0 Then
    headingSheet = ""
    strType = mst.Shapes(1).Cells(ROWTYPE).ResultStr("")
    If strType = "Container" Then
      'Open the master to edit it
      Set mstEdit = mst.Open
      Set shp = mstEdit.Shapes(1)
      For Each subShp In shp.Shapes
        If subShp.CellExists(ROWTYPE, FLGEX) <> 0 Then
          strSubType = subShp.Cells(ROWTYPE).ResultStr("")
          If strSubType = "Heading" Then
            'Get the NameID of the Heading sub-shape
            headingSheet = subShp.nameId
            Exit For
          End If
        End If
      Next subShp
      'If necessary, update the container categories
      categories = shp.Cells(ROWCAT).ResultStr("")
      If Len(CONTAINERCAT) > 0 Then
        If Len(categories) > 0 Then
          aryCats = Split(categories, ";")
          For i = 0 To UBound(aryCats)
            If aryCats(i) = CONTAINERCAT Then
              catExists = True
              Exit For
            End If
          Next I
          If catExists = False Then
            newCategories = categories & ";" & CONTAINERCAT
          End If
        Else
          newCategories = CONTAINERCAT
        End If
      End If
      shp.Cells(ROWCAT).FormulaForceU = "=""" & newCategories & """"
      If Len(headingSheet) > 0 Then
        'Create the visHeadingText cell
        If shp.CellExists("User." & CELHDR, FLGEX) = 0 Then
          shp.AddNamedRow UDCSECT, CELHDR, 0
        End If
        'Set the fomula for the visHeadingText cell
        shp.Cells("User." & CELHDR).FormulaForceU = _
          "=SHAPETEXT(" & headingSheet & "!TheText)"
        End If
        'Close the master edit object
        mstEdit.Close
        mst.matchByName = True
        mst.Hidden = 1
      End If
    End If
Next mst
exitHere:
  Exit Sub
errHandler:
  MsgBox Err.description, vbExclamation, "EnhanceContainers"
  Resume exitHere
End Sub

 
BTW, I always put this sort of code in a macro-enabled stencil that I save into the My Shapes folder.
Caution! Do not specify “Swimlane” as a category for your containers because the Microsoft BASFLO add-on behaves badly, and won’t let you edit the text in the header!
A macro-enabled stencil with the above code can be downloaded from here
An enhanced sample diagram can be downloaded here
 

Moving Phases/Separators in Visio Cross-Functional Flowcharts?

I use Visio Cross-Functional Flowcharts a lot, but there is one thing that really bugs me … you can move function bands\swimlanes around, but you can’t move the phases\separators in the same way. The phases/separators are containers just like the function bands\swimlanes, so why can’t I move them? Actually, it is quite understandable when you…

A Visio List Shape is also a Container

Structured diagrams have been around in Microsoft Visio since 2010 and I have always known that list shapes are a specialized container shape, however it still came as a surprise to me recently that a list shape can simultaneously act as a container shape! There are a few examples of both container and list shapes…

Referencing Container Data in Visio

Microsoft Visio has a useful Structured Diagramming concept that consists of Containers, Callouts and Connectors. The first of these features make it possible for shapes to know what they are contained within, as a better option to grouping shapes together. Grouping can hide or break the grouped shapes smartness, so Visio provides two ways of…

Understanding Morse Clicks with Visio

A few years ago, I wrote an article about messaging and encryption inspired by a visit to the National Museum of Computing in the UK. I developed a Morse Click shape to demonstrate how Visio can be used to represent and learn Morse Code. However, I never published the shapes here, and my good friend…

Visio 2010 MVP Session videos reprise

Back in 2012, my fellow Visio MVPs, Scott Helmers and Chris Roth, and I recorded a series of 24 videos about Visio 2010. They were first hosted on Microsoft’s web site, then they put them up on YouTube, they they got deleted :-(. Well, we have managed to retrieve them, and put them back up…

Preventing Deletion of Container Members in Visio

The concept of Structured Diagrams was introduced in Visio 2010 and is featured in many of the templates supplied with Microsoft Visio, and in some third-party solutions, like mine. Connectors, callouts, containers and lists are the key parts of a structured diagrams, and there are times when preventing the deletion of members of a container…

Exit mobile version