Visio 2010 Container Problems

Update : I have received a corrected response from my friends at Microsoft regarding the use of Spatial Neighbors and Containers, so I have to revise this post from its original. The changes are marked in Red.

The Structured Diagramming API in Visio 2010 is really neat, but there are a couple of problems that I think you should be aware of. The first one is about how shapes can appear to be in a container, but aren’t really; and the second is how the Container type prevents SpatialNeighbors from working … unless you use a new constant.

Let’s start with an example diagram that contains three Process shapes on a Cross Functional Flowchart. Notice that I have select the Process shape labelled A and this has caused the swimlane Function 2 to display a brown highlight … this is a good indication that the Structured Diagramming

API is working, and that Function 2 is a container shape. I have placed two more Process shapes below the swimlanes, and one of them (C) is on top of a SubProcess shape.

Now, I wrote a short VBA function to list each Process shape along with the containers that each one thinks that it is within.

Public Sub UsingStructuredDiagram() 
Dim shp As Visio.Shape 
Dim aryIDs() As Long 
Dim i As Integer 
For Each shp In Visio.ActivePage.Shapes 
 If Not shp.Master Is Nothing Then 
 If shp.Master.Name = "Process" Then 
 Debug.Print shp.Text 
 aryIDs = shp.MemberOfContainers 
 For i = 0 To UBound(aryIDs) 
 Debug.Print , shp.ContainingPage.Shapes.ItemFromID(aryIDs(i)).Name, _ 
 shp.ContainingPage.Shapes.ItemFromID(aryIDs(i)).Text 
 Next i 
 End If 
 End If 
Next 
End Sub 

 Running this function shows that Process A is within three containers … this is what I would expect because the swimlane is within a swimlane list, and there is always a phase separator.

A

Swimlane List

Swimlane Function 2

Separator Phase

B

D

 I also wrote a short VBA function to do a similar list, but using the legacy SpatialNeighbors function.

Public Sub UsingSpatialNeighbors() 
Dim sel As Visio.Selection 
Dim shp As Visio.Shape 
Dim shpIn As Visio.Shape 
Dim aryIDs() As Long 
Dim i As Integer 
For Each shp In Visio.ActivePage.Shapes 
 If Not shp.Master Is Nothing Then 
 If shp.Master.Name = "Process" Then 
 Debug.Print shp.Text 
 Set sel = shp.SpatialNeighbors( _ 
 visSpatialContainedIn, 0.001, _ 
 visSpatialIncludeHidden) 
 For Each shpIn In sel 
 Debug.Print , shpIn.Name, shpIn.Text 
 Next shpIn 
 End If 
 End If 
Next 
End Sub 

 This time, only Process D is listed as being inside a container … the Subprocess C shape.

A

B

D

Subprocess C

 Immediately, you can see that SpatialNeighbors method is not working for the swimlane, swimlane list and separator. This is the first problem.

 Now, stretched the bottom edge of Function 2 so that it covers shapes B, C and D.

Notice that I have got shape B selected, but there is no tell-tale brown outline around Function 2. This is an indication that there is something amiss … This is the second problem. Sure enough, when I ran the UsingStructuredDiagram() function, the listing was unchanged:

A

Swimlane List

Swimlane Function 2

Separator Phase

B

D

Similarly, the UsingSpatialNeighbors() function produces an unchanged listing:

A

B

D

Subprocess C

 Then I selected the three shapes and just wiggled them a little … and suddenly the tell-tale brown outline appeared:

Now when I ran the UsingStructuredDiagram() function, all three of the Process shapes recognised that they are inside the swimlane, etc.

A

Swimlane List

Swimlane Function 2

Separator Phase

B

Swimlane List

Swimlane Function 2

Separator Phase

D

Swimlane List

Swimlane Function 2

Separator Phase

 But the UsingSpatialNeighbors() function still lists the same:

A

B

D

Subprocess C

 

UNLESS you add the visSpatialIncludeContainerShapes constant:

Public Sub UsingSpatialNeighbors() Dim sel As Visio.Selection Dim shp As Visio.Shape Dim shpIn As Visio.Shape Dim aryIDs() As Long Dim i As Integer   For Each shp In Visio.ActivePage.Shapes     If Not shp.Master Is Nothing Then         If shp.Master.Name = "Process" Then             Debug.Print shp.Text             Set sel = shp.SpatialNeighbors( _                 visSpatialContainedIn, 0.001, _                 visSpatialIncludeHidden + visSpatialIncludeContainerShapes)               For Each shpIn In sel                 Debug.Print , shpIn.Name, shpIn.Text             Next shpIn         End If     End If Next   End Sub

 

A

              CFF Container Title

              Swimlane      Function 2

              Swimlane List

B

              CFF Container Title

              Swimlane      Function 2

              Swimlane List

D

              CFF Container Title

              Swimlane      Function 2

              Swimlane List

              Subprocess    C

 

As a footnote, I opened the ShapeSheet of Function 2 shape, and removed the value “Container” in the User.msvStructureType cell.

 This will, of course, stop the swimlane behaving correctly as far as the Structured Diagram is concerned, but it does allow the SpatialNeighbors() method to work, without the visSpatialIncludeContainerShapes constant, as can be seen by this output from the UsingSpatialNeighbors() function:

A

Swimlane Function 2

B

Swimlane Function 2

D

Swimlane Function 2

Subprocess C

I have made Microsoft aware of these problems, but until there is a fix, I hope this article helps you work around them  … and now that I have had an updated response, I feel a little silly!

Follow

Get every new post delivered to your Inbox.

Join 184 other followers