Hi,
this method should return an selection object:
https://docs.microsoft.com/de-de/office/vba/api/visio.selection.duplicate
But the demo code below returns Nothing.
I would expect a selection of the created shapes.
Any idea?
Best regards,
Thomas
Sub testDuplicate()
Dim sel As Visio.Selection
Set sel = ActiveWindow.Selection.Duplicate
MsgBox sel.Count 'sel = Nothing
End Sub
Well, the code is mostly working. It does duplicate the selection. If you view the drawing page and the VBA window, step thru code with <f8>, you see that your selection gets duplicated when the line Set sel = is executed. The sel.count doesn't work.
Here's link to selection.duplicate: https://docs.microsoft.com/en-us/office/vba/api/visio.selection.duplicate (https://docs.microsoft.com/en-us/office/vba/api/visio.selection.duplicate)
Note: the code line: Debug.Print ActiveWindow.Selection.Count works either before or after the set as the former gives count of the original selection and the latter gives count of the duplicated selection.
Hi,
the small testDuplicate sub is only to demonstrate the error.
Regarding to the documentation that you linked the return value of Duplicate() should be a selection.
But actually the method returns Noting.
Even though the duplicate operation itself works.
So I guess that this is a bug in the Visio API.
Using ActiveWindow.Selection after duplicate() can only be a workaround for some cases.
Maybe the following example illustrates the problem better.
You need minimum 2 pages and minimum 1 shape per page.
Sub testDuplicate()
Dim pge As Visio.Page
Dim shp As Visio.Shape
Dim sel As Visio.Selection
Dim selCopy As Visio.Selection
Set sel = ActivePage.CreateSelection(visSelTypeEmpty)
For Each pge In ActiveDocument.Pages
If pge <> ActivePage Then Exit For
Next pge
For Each shp In pge.Shapes
sel.Select shp, visSelect
Exit For
Next shp
Set selCopy = sel.Duplicate
'This will crash because selCopy is Nothing.
Debug.Print selCopy.Count
End Sub
I interpret it more like <cntl>+ D. Granted, the "selection" protocol seems to give quantities, but not in this case.
So, in your code, the "set" line actually executes a duplicate command. It can either be a specified shape or a selection of shapes. In this case, "selection" is treated like a singular, temporary, physical object. Whatever it is, is duplicated, & remains selected. Hence, ActiveWindow.Selection.Count does give quantity of interest. Just change the code for the debug.print, (or msgbox as you initially used), and you'll get the count and no errors.
Well, the ".duplicate" is what it is.
In my last example the selection contains only one shape from another page, not the ActivePage.
So ActiveWindow.Selection cannot be used.
The Visio.Selection object has nothing to do with the selected items in the Visio drawing window.
The Visio.Shape object also implements a duplicate method. And here the return value is functional.
The following function does what I expect from the Selection.Duplicate() method.
It duplicates a selection and returns the copy as selection object, so that can be processed by further code.
Public Function Duplicate(selection As Visio.selection) As selection
Dim shp As Visio.Shape
Dim sel As Visio.selection
Set sel = selection.ContainingPage.CreateSelection(visSelTypeEmpty)
For Each shp In selection
sel.Select shp.Duplicate, visSelect
Next shp
Set Duplicate = sel
End Function
Sub testDuplicate()
Dim sel As Visio.selection
Set sel = Duplicate(ActiveWindow.selection)
sel.Group
End Sub
Sorry...failed to recognize that you went to non-active window. My bad.
Here's an alternative approach to leverage the .duplicate method. Yes, it requires making the selected page active. Was lazy, didn't declare everything...
Sub testDuplicate()
Dim pge As Visio.Page
Dim shp As Visio.Shape
Dim sel As Visio.Selection
Dim selCopy As Visio.Selection
For Each pge In ActiveDocument.Pages
If pge <> ActivePage Then Exit For
Next pge
Set sel = pge.CreateSelection(visSelTypeAll) 'again lazy, didn't try to filter the selected shapes.
Debug.Print sel.Count
ActiveWindow.Page = pge 'this needs to be before the sel.Duplicate line, otherwise, Visio will "forget" what's selected upon page change. This could be a bug.
Set selCopy = sel.Duplicate 'Visio remembers what was duplicated, but, window needs to be active for this to be useful.
Set vsoSel = ActiveWindow.Selection
Debug.Print vsoSel.Count
End Sub
Hope this is helpful.