Hi there
What I want to achieve is that all shapes that are not assigned to any layer get selected so that the user can see them and go for further action.
I've tried for hours but I can't figure out to do it and couldn't find code snippets. I also tried to record a macro which invokes the built in select shapes on layers and the top option which selects the shapes on no layer. That didn't work either.
Hints and code snippets are very welcome. Thank you in advance.
Just write from phone:
You must iterate all shapes and check property LayerMembership LayerMember, if it is empty then shape not assigned to any layer.
(https://i.imgur.com/7G7aEig.png)
PS also you can use property LayerCount (https://docs.microsoft.com/en-us/office/vba/api/visio.shape.layercount)
Dim sh As Shape
For Each sh In ActivePage.Shapes
If sh.LayerCount = 0 Then MsgBox sh.NameID & " not assigned to any layer"
Next
Thanks to Surrogate for your swift assistance.
I'm not sure if I miss objects with my solution below (subshapes, grouped shapes) or if anything else might lead to an undesired outcome. I mainly struggled with the selection object but now it seems to work. Now, i can use the selection for further action to make sure that there are no shapes that are not on any layer.
Sub SelectShapesNotAttachedToAnyLayer()
Dim vsoSelection As Visio.Selection ' create Selection Object to build selection in memory (not to be seen by user)
Set vsoSelection = Application.ActiveWindow.Page.CreateSelection(visSelTypeEmpty)
Application.ActiveWindow.Selection = vsoSelection ' cancel selection in ActiveWindow
Dim shpObj As Visio.Shape
For Each shpObj In ActivePage.Shapes ' iterate over all shapes on ActivePage
If shpObj.layerCount = 0 Then ' if shape not assigned to any layer
vsoSelection.Select shpObj, visSelect ' Add this shape to the selection in memory
End If
Next shpObj
Application.ActiveWindow.Selection = vsoSelection ' present the selection to the user
End Sub
At first I startet by recording a macro and changed it a bit. Also here, this seems to work and needs almost no code but I guess this only works with my current German language setting and there are different user settings. Is there a constant for {keine Ebene} {no layer} as in the respective dialog?
Sub SelectShapesNotAttachedToAnyLayerFromMacroRecorder()
Dim vsoSelection As Visio.Selection
' This seems to be a problem with different language settings. GER = {Keine Ebene} / ENG {No Layers}
Set vsoSelection = Application.ActiveWindow.Page.CreateSelection(visSelTypeByLayer, visSelModeSkipSuper, "{Keine Ebene}")
Application.ActiveWindow.Selection = vsoSelection
End Sub
(https://support.content.office.net/de-de/media/b3f7152d-7110-4a0c-a901-09bff85692f0.png)
And it is crashing again and i finally found out why. It happens if there are guide lines on the page that are not visible and I try to show the selectionObject in the activewindow.
I therefore changed the code which now just ignores guide lines (shpObj.Type = visTypeGuide). Is there an easier (one line) approch to solve my problem which is to select all shapes that are not assigned to any layer?
Sub SelectShapesNotAttachedToAnyLayer()
Dim vsoSelection As Visio.Selection ' create Selection Object to build selection in memory (not to be seen by user)
Set vsoSelection = Application.ActiveWindow.Page.CreateSelection(visSelTypeEmpty)
Application.ActiveWindow.Selection = vsoSelection ' cancel current selection in ActiveWindow
Dim shpObj As Visio.Shape
For Each shpObj In ActivePage.Shapes ' iterate over all shapes on ActivePage
If shpObj.layerCount = 0 Then ' if shape not assigned to any layer
If shpObj.Type = visTypeGuide Then
Debug.Print "--> Guide: " & shpObj.Name ' visTypeGuide would throw error, not when added to vsoSelection,
' but when presenting to user if guide lines are not visible.
Else
Debug.Print " Shape: " & shpObj.Name
vsoSelection.Select shpObj, visSelect ' Add this shape to the selection in memory
End If
End If
Next shpObj
Application.ActiveWindow.Selection = vsoSelection ' present the selection to the user
End Sub
Quote from: DanWild on September 08, 2021, 02:24:42 PMIs there an easier (one line) approch to solve my problem which is to select all shapes that are not assigned to any layer?
There is definitely no such possibility!
You even cant define which shapes assigned to some layer without iteration.
Quote from: Surrogate on September 08, 2021, 03:29:27 PM
Quote from: DanWild on September 08, 2021, 02:24:42 PMIs there an easier (one line) approch to solve my problem which is to select all shapes that are not assigned to any layer?
There is definitely no such possibility!
You even cant define which shapes assigned to some layer without iteration.
Thanks once more for your assistance. By the way, why is this site still not secured with https?
It occurred to me that if you make all layers hidden, then, the only shapes visible are not members of any layer. These could then be selected and dealt with as desired.
The following code deletes the non-layered shapes only.
Sub Macro1()
Dim vsoLayer As Visio.Layer
Dim vsoLayers As Visio.Layers
Set vsoPage = ActivePage
Set vsoLayers = vsoPage.Layers
For Each vsoLayer In vsoLayers
vsoLayer.CellsC(visLayerVisible).FormulaU = "0"
Next
ActiveWindow.DeselectAll
ActiveWindow.SelectAll
ActiveWindow.Selection.DeleteEx (visDeleteNormal)
For Each vsoLayer In vsoLayers
vsoLayer.CellsC(visLayerVisible).FormulaU = "1"
Next
End Sub
Modify as needed.