Hi,
I have a document with several pages. Each page has several layers (different on each page). On each page one or more layers are visible (shows one variant of a schematic). Each layer contains shapes, but there are also shapes that are "global", i.e. not assigned to a layer (so visible all the time).
I want to go through each page and collect the shape data from all shapes that are visible, i.e. the "global" plus the visible "variant".
I can recognize, whether the shape belongs to a layer (layer membership) and then I guess I can check whether this layer is visible. But it would be nice if there is a direct way of finding out.
Is there a method like "shpObj.visible" (That would be very nice)?
I found this http://visguy.com/vgforum/index.php?topic=6420.msg26535#msg26535 (http://visguy.com/vgforum/index.php?topic=6420.msg26535#msg26535) but I would rather go through the pages without making each page active to use "activewindow"
Thanks, Rolf
Not sure I understand your question...
Are wanting to identify shapes by layer membership or just visible shapes or just hidden shapes?
2nd part, as far as I know, page being searched needs to be the active page. Easy enough to do in code, but no "easy" button that magically provides one button solution.
Wapperdude
It is the visible shapes I'm interested in. When I use something like "For each shape in page" it also takes the shapes that belong to layers set to invisible.
I have created a function that works for my requirements. It's not really properly coded, but does the trick for me.
Sub TestVisibility()
Dim shp As Visio.Shape
Dim pge As Visio.Page
For Each pge In ActiveDocument.Pages
For Each shp In pge.Shapes
If IsVisible(shp) Then
Debug.Print shp.Name & " is visible"
Else
Debug.Print shp.Name & " is NOT visible"
End If
Next shp
Next pge
End Sub
Private Function IsVisible(shp As Visio.Shape) As Boolean
Dim lyr As Visio.Layer
If shp.LayerCount = 0 Then
IsVisible = True
Else
Set lyr = shp.ContainingPage.Layers(shp.Layer(1).index)
IsVisible = lyr.CellsC(visLayerVisible).ResultStr(0)
End If
End Function
You can simplify the selection process to include only visible shapes:
Note: I didn't declare anything, so, you might want to add those dim statements.
Note2: You ought to add a check to see if shapes are 1D. I'm assuming you would only want 2D shapes.
Note3: Replace MsgBox with whatever code you need to execute.
Sub GetVis()
For Each visPg In ActiveDocument.Pages
ActiveWindow.Page = visPg
ActiveWindow.SelectAll
For Each visShp In ActiveWindow.Selection
MsgBox visPg & " " & visShp.Name
Next
Next
End Sub
Hi Wapperdude,
thanks, that was what I was looking for. For some reason I thought that the "select" method might be slow, but I ran your code on my document and it isn't.
A few comments:
1. If a shape is on multiple layers, it will only be hidden if ALL of those layers are hidden. Think of the layer behavior as "if anything is positive, then it's a 'GO'", so if any of the layers are visible, the shape is visible.
2. You can build a list of hidden layers by looking at the page's ShapeSheet. Build a list of indices, so, say "1,5,8" are the hidden layer indices.
3. Now you can look at each shape's LayerMember cell, which just contains a list of layer indices, similar to what we built in step #2.
4. Now, you can just parse two strings and see if any or all of the shape's layer indices match the page's hidden-layer list.
Yes, you have to do all the work yourself, but by using a bunch of string manipulation, it might work faster than querying Visio for all sorts of Visio properties. And you only have to write it once!