Creating PolyLines From Existing Shapes in Visio

A couple of posts in the Visio newsgroups got me thinking this weekend.  One was from an Autocad conversant user who would prefer Visio to draw a continuous line between points rather than doing the normal click, hold and drag with line tool because he has tendonitis; and the other wanted to draw a circle centered on a vertex because he is drawing land boundaries.

Visio has a PolyLine line type, but, as far as I am aware, it can only be created in code – there is no menu or toolbar button to enable you to use it.  It was introduced for converting CAD lines, and is simply a series of X and Y co-ordinates in a single cell, rather than the normal co-ordinate per row.

Visio has a Stamp Tool, which used to be on a toolbar out-of-the-box, but it seems to have disappeared in Office Visio 2007.  Fortunately, it is simple to put it back by selecting Add or Remove Buttons / Customize from the down arrow at the end of any of the toolbars.  This will open the Customize dialog, and then you can navigate to the Drawing Tools category, and scroll down to Stamp Tool.  You can then click and drag it onto any toolbar, such as the Drawing toolbar in the example below.

image

The Stamp Tool enables you to drop a master shape instance with each click of the mouse.  For example, I have selected the Sector – graphical master from the Visio Extras / Drawing Tool Shapes stencil, then I have selected the Stamp Tool and clicked seven times in the page.

image

To stop the Stamp Tool, simply Pointer Tool on the Standard toolbar. 

I have included the CreatePolyLine VBA macro in this post, which has a boolean argument to optionally delete the existing shapes.  To run the macro, simply select the first shape in the sequence that you want to trace a line between.  I have assumed that you would put down a sequence of shapes, then select my macro immediately after re-selecting the first shape in the sequence. Then I selected my macro DrawPolyLineBetween to draw a line between each of the

image

The Sector – graphical shapes can be modified to snap to the geometry of the new polyline shape, if desired.

image

Alternatively, you can run the DrawReplacementPolyLine macro to create a polyline shape that automatically deletes the original shapes.

image

The new polyline shape has a single geometry section in the ShapeSheet, which uses the PolyLineTo row type, as follows:

image 

In the following code, I have tested the vertex shapes to see if they are 1D or not.  If they are 1D, then I have used the BeginX and BeginY co-ordinates as the vertex position, but if they are not 1D, then I have use the PinX and PinY co-ordinates.  I have assumed that you are trying to create a closed shape – that is one where the line returns to where it started from.

Public Sub DrawPolyLineBetween()
    CreatePolyLine False
End Sub

Public Sub DrawReplacementPolyLine()
    CreatePolyLine True
End Sub

Private Sub CreatePolyLine(ByVal deleteOriginalShapes As Boolean)
‘Author: David J Parker, bVisual – Dec 2007
‘Usage : Draw a poly line between existing shapes
‘Params: Optionally delete existing shapes
    If Visio.ActiveWindow.Selection.Count = 0 Then
        ‘Nothing selected
        Exit Sub
    End If
Dim pag As Visio.Page
Dim shp As Visio.Shape

    Set shp = Visio.ActiveWindow.Selection.PrimaryItem
    Set pag = Visio.ActivePage

    If pag.Shapes.Count = shp.Index Then
        ‘No subsequent shapes to loop thru’
        Exit Sub
    End If
Dim shpIndex As Integer
Dim vertexShape As Visio.Shape
Dim lineShape As Visio.Shape
Dim vertices As Integer
Dim xyArray() As Double

    For shpIndex = shp.Index To pag.Shapes.Count
        Set vertexShape = pag.Shapes(shpIndex)
        vertices = vertices + 1
        setVertices xyArray(), vertexShape, vertices
    Next shpIndex

    ‘Close the line
    Set vertexShape = pag.Shapes(shp.Index)
    vertices = vertices + 1
    setVertices xyArray(), vertexShape, vertices
    Set lineShape = pag.DrawPolyline(xyArray(), 0)
    If deleteOriginalShapes = True Then
        For shpIndex = pag.Shapes.Count – 1 To shp.Index Step -1
            pag.Shapes(shpIndex).Delete
        Next shpIndex
    End If
End Sub

Private Sub setVertices(ByRef xyArray() As Double, _
    ByVal vertexShape As Visio.Shape, ByVal vertices As Integer)
    ReDim Preserve xyArray((2 * vertices) – 1)
    If vertexShape.OneD = 0 Then
        xyArray((2 * vertices) – 2) = vertexShape.CellsSRC( _
            Visio.VisSectionIndices.visSectionObject, _
            Visio.VisRowIndices.visRowXFormOut, _
            Visio.visXFormPinX).ResultIU
        xyArray((2 * vertices) – 1) = vertexShape.CellsSRC( _
            Visio.VisSectionIndices.visSectionObject, _
            Visio.VisRowIndices.visRowXFormOut, _
            Visio.visXFormPinY).ResultIU
    Else
        xyArray((2 * vertices) – 2) = vertexShape.CellsSRC( _
            Visio.VisSectionIndices.visSectionObject, _
            Visio.VisRowIndices.visRowXForm1D, _
            Visio.vis1DBeginX).ResultIU
        xyArray((2 * vertices) – 1) = vertexShape.CellsSRC( _
            Visio.VisSectionIndices.visSectionObject, _
            Visio.VisRowIndices.visRowXForm1D, _
            Visio.vis1DBeginY).ResultIU
    End If
End Sub

Note to Microsoft Visio team:-

In preparation for this blog entry, I noticed that the Stamp Tool has a bug, or at least it behaves differently from normal usage. – if the page is scaled then the stamped master instances are scaled, but the same master, when dragged from the stencil, are sometimes not.  Thus the two operations do not produce a shape of the same size:-

image

In my limited testing, this behavior is limited to more complex 1D masters.

Posted in Visio. 2 Comments »

2 Responses to “Creating PolyLines From Existing Shapes in Visio”

  1. Unknown Says:

    I discovered for stamp tool (Visio 2003), that if I drag before letting go of the new object, that drag will change the shape size on the fly for that object but next stamp is same as the stencil original.

  2. Chris Says:

    Hi David,On a related note, I have an article + code about making Visio shapes with lots of vertices more efficient by converting them to PolyLines. See: Polyline Shape Maker- Chris (aka Visio Guy)


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

davecra.wordpress.com/

Microsoft Office Development, and more...

PowerShell.Amsterdam

Automate, Accelerate, Accurate

johnvisiomvp

Life with Visio and other Microsoft Toys!

Title (Required)

Windows Server Essentials Tips & Tricks

Nilsandrey's Weblog

Just another WordPress.com weblog

Things that Should be Easy

Every so often (too often in the IT industry) I encounter things that should have been very easy to do but turned out to be far too complicated. My favorite topics include SharePoint, .Net development, and software architecture, especially distributed systems.

Visio Guy

Shapes, Stencils, Drawings Templates, Tutorials, Tips & Developer Info for Microsoft Visio

Hannes's Virtual Earth

Tips & Tricks around Mapping and Cloud Computing

Pluralsight blog

be smart, be clear, be visual ...

%d bloggers like this: