Change shapes in Visio 2013
Visio 2013 introduces a "Change Shape" feature that enables you to swap out a selected shape or group of shapes in the drawing with another type of shape. The new shapes can retain the position, connections, formatting, shape text, and/or shape data of the originals.
For example, take a drawing like the following simple flowchart.
With the Change Shape feature, you can change the Process shape labeled "Make a decision" to a Decision shape with a single button press:
Rather than using another shape in the drawing, the Decision shape that replaces the Process is a new instance of the Decision shape from the Decision Master shape. It retains the local formatting values of the original Process shape (that is, values that the user or the program changed after the shape was dropped), including the fill color, the shape text, and the bold applied to the word "decision."
If another shape in the drawing references the original shape in a formula, Visio restores this reference after the operation and updates the reference to point towards the resulting shape. The same goes for hyperlinks: links that target the original shape will be updated to point towards the resulting shape. Connections, callout associations, shape comments, container membership, and list membership are likewise restored.
Note: You can only replace 2D shapes with other 2D shapes (like a Decision shape for a Process shape) and 1D shapes with other 1D shapes (replacing one type of connector with another). You cannot replace a connector with a rectangle, as an example.
For developers, there are two aspects of this feature that are worth examining: first, how to use this feature programmatically using the Visio 2013 APIs; and second, how to build custom shapes that interact predictably with this feature. I will take a look at each of these aspects in turn.
Before I go any further, however, I should clarify some terminology. First, I will call the shape that is being removed from the drawing (and replaced by another) the "original shape." The Master shape that is being used to replace the shape on the drawing is called the "replacement shape." Finally, the shape that remains on the drawing page after the operation has completed is called the "resulting shape."
Using the Change Shape APIs
The Visio 2013 object model includes two new APIs that implement the Change Shape feature: Selection.ReplaceShape and the Shape.ReplaceShape methods.
Using Shape.ReplaceShape, the procedure described previously could have been written as a simple VBA macro, as shown in the following code sample.
Sub ChangeToDecisionShape()
Dim vsoPage As Visio.Page
Dim vsoShapes As Visio.Shapes
Dim vsoStencil As Visio.Document
Dim vsoMaster As Visio.Master
Dim vsoOriginalShape As Visio.Shape
' Get a reference to the currently active page in Visio.
Set vsoPage = Application.ActivePage
Set vsoShapes = vsoPage.Shapes
' Get a reference to the Master to use as the replacement shape.
Set vsoStencil = Application.Documents("BASFLO_U.VSSX")
Set vsoMaster = vsoStencil.Masters("Decision")
' Iterate over every shape on the page to find the shape
' to replace by testing the text of each shape.
For Each vsoOriginalShape In vsoShapes
If (vsoOriginalShape.Text = "Make a decision") Then
'Replace the shape using the default behavior.
vsoOriginalShape.ReplaceShape vsoMaster, _
VisReplaceFlags.visReplaceShapeDefault
End If
Next vsoOriginalShape
End Sub
In the previous code sample, the Shape.ReplaceShape method is called on the original shape. The method takes a Master object as a required argument, which represents the replacement shape. Although not used in the code sample, the method returns a Shape object that represents the resulting shape.
The ReplaceShapes method has an optional parameter, ReplaceFlags, which must be a constant from the VisReplaceFlags enumeration. Passing in an argument for the ReplaceFlags parameter allows you to control the values of the resulting shape more finely. For example, you could pass in the visReplaceShapeLockText flag (2), which would assure that the original shape's text is overwritten by the text of the replacement shape.
The Selection.ReplaceShape method behaviors similarly to Shape.ReplaceShape, with a couple of differences. All shapes contained by the selection are changed to instances of the replacement shape and the return type from the method is an array of shapes.
If you call the Selection.ReplaceShape method and some of the selected shapes cannot be replaced (have a LockReplace cell value of '1' - see the section that follows), the method will replace only the shapes in the selection that can be replaced. The method then returns an array that contains only the resulting shapes from successful shape replacement.
Using the ShapeSheet to specify Change Shape behaviors
Visio 2013 includes several new ShapeSheet cells for working with the Change Shape feature: the LockReplace cell, the PageLockReplace cell, the
DocLockReplace cell, the ReplaceLockText cell, the ReplaceLockFormat cell, the ReplaceLockShapeData cell, and the ReplaceCopyCells cell.
The LockReplace cell is simple in that it determines whether a shape or Master shape can be used in a change shape operation. If the cell is set to 1 (true), the shape cannot be replaced or be used as a replacement shape. If you select a shape on the drawing page that has its LockReplace cell set to true, the Change Shape button in the Editing group on the Home tab is disabled.
The PageLockReplace and DocLockReplace cells behave similarly to LockReplace: when set to 1 (true), shape replacement operations are disabled. When disabled, the Change Shape button is dimmed when the page (PageLockReplace) or document (DocLockReplace) is active.
The following cells affect the output - the resulting shape - of a Change Shape operation. Only the values of the replacement shape, the Master shape being used to replace the shape(s) in the drawing, are used:
- The ReplaceLockText cell determines whether the text contained in the replacement shape overwrites the text of the shape being replaced. If this cell is set to 1 (true), any text contained by the replacement shape is copied to the resulting shape in the drawing.
- The ReplaceLockFormat cell determines whether the formatting values - fill formatting, line formatting, quick style, theme properties, gradients, bevels, reflection, soft edges, shadow, etc. - of the replacement shape overwrite the values o the original shape. If this cell is set to 1 (true), the formatting values of the replacement shape are copied to the resulting shape in the drawing.
- The ReplaceLockShapeData cell determines whether the shape data contained in a replacement shape overwrites all of the shape data of the original shape. If this cell is set to 1 (true), all rows and values of the shape data section of the replacement shape are copied onto the resulting shape. Any local values from the original shape are discarded.
The ReplaceCopyCells cell is a little more complicated than the other cells. The ReplaceCopyCells value of the replacement shape indicates a list of other ShapeSheet cells that are copied from the original shape to the resulting shape. The cell must contain a DEPENDSON function call where each argument in the function is a reference to another ShapeSheet cell.
Here's an example of how its used: A Master shape has its ReplaceLockFormat cell set to 1 and tis ReplaceCopyCells cell set to DEPENDSON(FillForegnd). If used as the replacement shape in a Change Shape operation, the resulting shape will take on al the formatting values of the replacement shape except the fill color (the value set in the FillForegnd cell).