Visio Insights
The official blog of the Microsoft Visio product team

Smarter Paste between Pages

Smarter Paste between Pages

  • Comments 10

The Visio Product Team uses Visio for a number of tasks.  A common task is creating storyboards to show how a user might construct a diagram.  If you’ve ever seen one of those “behind the scenes” documentaries for a movie, you’ve seen the storyboarding process.  Each step the user takes is captured on a separate page in a Visio drawing.  Then the entire document is shown as a presentation to replay the construction of the diagram.

It seems that quite a few people use Visio for this sort of task.  Visio is a pretty good tool for mocking up application or web interfaces.  One common request is to make copying between pages work better.  In these types of documents, each page is almost identical to the one before it.  One of the nicer touches in PowerPoint is that objects copied from one page (slide) to another are pasted in exactly the same position.  In Visio objects are pasted to the center of the screen making repositioning a chore.  Visio needs a smarter paste behavior.

A little bit of code can solve the problem for Visio.  Actually, there are two ways to solve the problem.  You could write your own procedures to perform copy and paste with better logic for positioning.  Alternatively, you could handle the event notifications from Visio when copy and paste occur and fix up the positioning after the fact.  The attached Visio document has VBA code to illustrate both methods.

Create your own copy / paste commands

When invoking Visio’s Copy and Paste command through automation, Visio allows you to specify whether the position of the selection on the page should be preserved using the visCopyPasteNoTranslate flag.  Thus you can create your own macros that do copy and paste:

Public Sub CopyNoTranslate()

   

    Application.ActiveWindow.Selection.Copy (visCopyPasteNoTranslate)

 

End Sub

 

Public Sub PasteNoTranslate()

   

    Application.ActivePage.Paste (visCopyPasteNoTranslate)

 

End Sub

In fact you can assign Ctrl-C and Ctrl-V as the accelerator keys for these macros to override Visio’s copy / paste.  If the real goal is to support copying to a new page, this macro will perform the necessary steps:

Public Sub CopyToNewPage()

   

    Dim vsoSelection As Visio.Selection

   

    'Make sure we are in a drawing window

    If Application.ActiveWindow.Type = Visio.VisWinTypes.visDrawing Then

   

        'If there is no selection, select all shapes on the page

        Set vsoSelection = Application.ActiveWindow.Selection

        vsoSelection.IterationMode = 0

        If vsoSelection.Count = 0 Then

            vsoSelection.SelectAll

        End If

       

        'Copy selection to new page

        vsoSelection.Copy Visio.visCopyPasteNoTranslate

        Application.ActiveDocument.Pages.Add

        Application.ActivePage.Paste Visio.visCopyPasteNoTranslate

       

    End If

   

End Sub

Respond to Visio’s copy / paste events

This method uses an event handler to detect copy and paste actions.  The position of the selection is read during the copy action.  The new position of the selection (which will be placed in the center of the window) is read during the paste action.  The current page is recorded during each action as well.  If the copy and paste actions occur on different pages, the code moves the selection back to its previous coordinates following the paste action.

Private Sub vsoApp_EnterScope(ByVal app As IVApplication, ByVal nScopeID As Long, ByVal bstrDescription As String)

 

    'Check for Copy action in a drawing window

    If nScopeID = 1021 And app.ActiveWindow.Type = Visio.VisWinTypes.visDrawing Then

   

        Dim vsoSelection As Visio.Selection

        Set vsoSelection = app.ActiveWindow.Selection

       

        If vsoSelection.Count > 0 Then

       

            'Find the shape in the selection at the bottom of the z-order

            Dim bottomShape As Integer

            bottomShape = GetBottomShape(vsoSelection)

           

            'Record scope ID and selection information

            nCopyScopeID = nScopeID

            gCopyPageID = app.ActivePage.PageSheet.UniqueID(Visio.visGetOrMakeGUID)

            dShapePosX = vsoSelection(bottomShape).CellsU("PinX").ResultIU

            dShapePosY = vsoSelection(bottomShape).CellsU("PinY").ResultIU

           

        End If

   

    End If

   

End Sub

 

Private Sub vsoApp_ExitScope(ByVal app As IVApplication, ByVal nScopeID As Long, ByVal bstrDescription As String, ByVal bErrOrCancelled As Boolean)

 

    'Check for Paste action in a drawing window

    If nScopeID = 1022 And app.ActiveWindow.Type = Visio.VisWinTypes.visDrawing Then

   

        If nCopyScopeID <> 0 Then

       

            Dim vsoSelection As Visio.Selection

            Set vsoSelection = app.ActiveWindow.Selection

           

            Dim activePageID As String

            activePageID = app.ActivePage.PageSheet.UniqueID(Visio.visGetOrMakeGUID)

           

            If vsoSelection.Count > 0 And gCopyPageID <> activePageID Then

           

                'Find the shape in the selection at the bottom of the z-order

                Dim bottomShape As Integer

                bottomShape = GetBottomShape(vsoSelection)

           

                'Fix up position of selection by offsetting from the bottom shape

                Dim posX As Double, posY As Double

                posX = vsoSelection(bottomShape).CellsU("PinX").ResultIU

                posY = vsoSelection(bottomShape).CellsU("PinY").ResultIU

               

                vsoSelection.Move dShapePosX - posX, dShapePosY - posY

               

            End If

       

        End If

       

    End If

       

End Sub

The full code for this method is found in the attached document.  We use the EnterScope and ExitScope events to detect the copy and paste actions.  The key problem to solve is recording the current position of the selected shapes.  Visio selections do not have coordinates associated with them, so the coordinates of one of the shapes within the selection must be used.  The trick is to make sure that the same shape is scanned in both the copy and paste actions.  Visio does not necessarily preserve the order of shapes in the selection during paste.  This code finds the bottommost shape in the z-order (layering order) to ensure that the same shape is scanned each time.

To use this method, open the SmartPaste.vsd file in Visio along with the other documents you are working on.  Once you enable macros for the file, SmartPaste will work with your regular Copy  and Paste actions.

If you find this type of behavior useful or find it counter-productive, please let us know.

Attachment: SmartPaste.vsd
Leave a Comment
  • Please add 5 and 6 and type the answer here:
  • Post
  • Hi there,

    This is definitely useful behaviour! I've always been annoyed at how the paste action always uses the wrong location (in my mind, at least :-). Actually, exactly because of what you;re describing, I have created two macros that allow me to copy a page (one for CopyPage in same document, one for CopyPage to a different (open) document). This has saved me a lot of time over the last two years or so. Is there a good reason why these functions have not appeared in Visio?

    (BTW, I have a number of utility macros like these, they're included in swipr, a stencil & set of macros to help Information Architects become more productive and help them communicate their ideas. Check it out at www.swipr.com, it's free and open source!)

    Jacco

  • unfortunately visCopyPasteNoTranslate is not a valid argument for .copy on visio 2000

  • Hi Michael,

    You are correct.  The Copy / Paste arguments and the Selection.Move method are capabilities of Visio 2003 or later.

    Mark Nelson

  • Hi,

    Thank you for the great macros - they are really useful as the Visio lacks some basic functionalites as these added by you.

    You wrote "In fact you can assign Ctrl-C and Ctrl-V as the accelerator keys for these macros to override Visio’s copy / paste." --- how do you actually do this with Visio?

  • Hi Maija,

    With the SmartPaste document open in Visio, go to Tools > Macro > Macros.  Select the CopyNoTranslate macro and click Options.  There you can enter the accelerator key.  Do the same for PasteNoTranslate.

    Mark Nelson

  • I have yet to try the above method (I'm unfamiliar with how to change the programming for macros), but was wondering if installing the above will help with my problem --- I cannot copy and paste exactly (or duplicate my page as it looks like) .

    i.e. when I copy and paste, the component tags that I had changed to text gets reverted to numbers, so I have to change everything again, very tedious.

    wonder if anybody has any solutions?

    Thanks!

    Rachel

  • I had hoped that the above would be a solution to my problem of moving one page from a Visio file to another Visio file resulting in two pages in the second file.  Unfortunately Visio will copy all of the objects over but will not maintain the size and location of the objects.  Visio is not designed to maintain the formatting of the shapes.  You will need to format everything manually.

  • Hello,

    Thank you very much for the macros. They work wonderfully.

    I'm wondering if there is a way to keep the original copy and paste functionality when I'm editing the shape's text and copy and paste the entire shape when the shape is selected and text is not being edited? When the accelerator keys of ctrl+c and ctrl+v are assigned, I can no longer use ctrl+c and ctrl+v when I'm editing text, it just pastes the entire shape on top, instead of appending new text into the textblock being edited.

    Thanks!

  • Macro works great and saves a lot of fiddling with position when creating story boards.

  • Has it been fixed in more recent versions of Visio? What about copying an entire page/sheet/tab from a file to another, together with page margins, print options, et. al?

Page 1 of 1 (10 items)