Dear All,
I am creating some pages with have numbers of layers. Could someone help me to make pages activated/appeared if the layers on that pages activated, and hide the pages that do not have layers activated.
Thank you so much.
If the page is hidden how would you enable a layer on that page?
Are you really hiding a page? See this article by John Goldsmith: https://visualsignals.typepad.co.uk/vislog/2007/11/hiding-pages.htm (https://visualsignals.typepad.co.uk/vislog/2007/11/hiding-pages.htm)
Unclear how you want to control visibility. Let's say all pages have 10 layers, 1 thru 10. If layer 1 on page 1 is not active, does page 1 and all pages become hidden? Then, if they are hidden, how do you unhide them? Really need better explaination of what you want to accomplish.
Dear Paul Herber and Wapperdude,
Thank you so much for the reply. My apologize for not being clear with my question. I enclosed some screenshot with hope it will make it better understanding.
1. I made a menu to choose what layer will be showing (Active) (Capture1)
2. My layer is basically lines with specific color. One layer to another is differentiated by color. (Capture2)
2. I have number of pages. One page can have multiple layers, and a layer can be appeared on multiple pages.
3. My goal is when I choose my layer from the menu, I want to have page(s) that only contain the picked layer(s) will appear/unhide, but for those do not have that picked layer(s), will hide/not appear.
Hope, this can give better picture of my question. Thank you so much for the anticipation.
missing attachement.
Quote1. I made a menu to choose what layer will be showing (Active)
Is this a VBA form with check boxes? How do you access the "menu"?
Does the current menu functional, that is, does it change the layer characteristics on all the pages as desired?
FYI, you only need to toggle the layer visibility to show hide it.
Yes, it's a vba code I created.
It is fully functional. By having that menu, I can select all the layers that I want to be activated (Activate = the layers will appear on the page(s)), deselect all, or I can pick which layer I wanted (ie I only want to have 21AG01, then the layer will appear on page(s) that have it.
The output is I want to print only the page contain the picked layer only. At the moment, if I have 50 pages, I need to sort which page has the layer and which one not. So, If I can hide the pages that I do not need, it will save a lot of time and will give very good accuracy.
Many thanks Wapperdude.
Got it.
Actually, this is easy, requires no additional coding.
For sake of argument, assume that your code controls the Layer Visibility attribute. Vis =0 hidden, Vis =1 shown. In the shapesheet for each page, create a Custom User entry, call it User.LayVis. Set the cell to be the sum of all layer visibilities for the page, e.g., =Layers.Visible+Layers.Visible[2]+Layers.Visible[3]. If the sum =0, it means no layers are visible on the page, and the page can be hidden.
Now, in the Page Properties section, set the UIVisibility cell =IF(User.LayVis=0,1,0).
That it.
Wapperdude
...and now a code solution. As there are a lot of pages that are impacted, code is probably the most efficient route.
The code is quite simple...loops thru each page, loops thru the layers on the page, sets a flag if a visible layer is found and makes sure the page is visible. If no visible layer is found, then it sets the page to hidden. Once complete, it returns to the first page.
Wapperdude
Sub SrchLayers()
Dim vsoPg As Visio.Page
Dim pgLay As Visio.Layer
Dim visLayCnt As Double
For Each vsoPg In ActiveDocument.Pages
visLayCnt = 0
ActiveWindow.Page = vsoPg
For Each pgLay In vsoPg.Layers
If pgLay.CellsC(visLayerVisible).ResultStr(visNone) = "1" Then
visLayCnt = 1
End If
Next
If visLayCnt = 0 Then
vsoPg.PageSheet.CellsU("UIVisibility").FormulaU = 1
Else
vsoPg.PageSheet.CellsU("UIVisibility").FormulaU = 0
End If
Next
ActiveWindow.Page = ActiveDocument.Pages(1)
End Sub
Thank you so much Wapperdude!
It seems it is not working yet, maybe we still need one more category for the IF formula. I am not good at all for the VBA code.
The reason why it is not working because there is a layer called P&ID, this layer is locked and has to be appear on all the pages. The P&ID basically a picture where I put the layer on it.
I would like also to keep the main menu (Viewer) page when we hide others, and I do not know to do it. See capture 3. If this be hidden then I will have no main menu anymore.
Herewith my existing formula, for example.
Private Sub CheckBox7_Click()
Dim LayerObj As Visio.Layer
For Each PageObj In ActiveDocument.Pages
For Each LayerObj In PageObj.Layers
If LayerObj.Name = "21GH08-2" Then
LayerObj.CellsC(visLayerVisible).Formula = IIf(LayerObj.CellsC(visLayerVisible).ResultIU, 0, 1)
LayerObj.CellsC(visLayerPrint).Formula = LayerObj.CellsC(visLayerVisible).Formula
End If
Next
Next
End Sub
Private Sub CommandButton3_Click()
Me.CheckBox7.Value = True
End Sub
Private Sub CommandButton4_Click()
Me.CheckBox7.Value = False
Don't be afraid to try. The code I provided has the necessary syntax to allow you to do what you want. Here's updated code that ignores background pages and also a named layer (flrPlan).
At the bottom, this and previous code returns you to first page in your file. You can edit this to return to your desired page. You can add or modify the code that ignores background page to ignore your desired page.
There's a lot of references in google-land about Visio VBA. Too much to elaborate hear. You can also google the forum site.
Sub SrchLayers()
Dim vsoPg As Visio.Page
Dim pgLay As Visio.Layer
Dim visLayCnt As Double
For Each vsoPg In ActiveDocument.Pages
visLayCnt = 0 'set layer flag to 0
If vsoPg.Background = False Then 'exclude background pages.
ActiveWindow.Page = vsoPg
For Each pgLay In vsoPg.Layers
If pgLay.Name <> "flrPlan" Then 'exclude layer named flrPlan
If pgLay.CellsC(visLayerVisible).ResultStr(visNone) = "1" Then 'if layer is visible, then set the flag =1
visLayCnt = 1
End If
End If
Next
End If
If visLayCnt = 0 Then 'check layer flag status
vsoPg.PageSheet.CellsU("UIVisibility").FormulaU = 1 'no layers visible, hide page
Else
vsoPg.PageSheet.CellsU("UIVisibility").FormulaU = 0 'at least 1 visible layer, do not hide page
End If
Next
ActiveWindow.Page = ActiveDocument.Pages(1) 'return to desired page; in this case, the 1st page. Presumably has a visible layer
End Sub
Regarding the code you sent, the following line has a typo and, based upon your needs, this won't work anyway.
QuoteLayerObj.CellsC(visLayerVisible).Formula = IIf(LayerObj.CellsC(visLayerVisible).ResultIU, 0, 1)
The problem with the above line, when corrected, will merely toggle the visibility. If doesn't check to see if layer is hidden. It just reverses the status whatever it may be. Plus, your code doesn't change page visibility.
Thank you so much Wapperdude, it works as I wanted.
I just need to figure out how to keep one page which the main menu not to be affected by the formula you were provided. Because at the moment the main menu also being hiden.
Cheers
Modify the line that checks if page should be visible, to something like:
If visLayCnt = 0 And vsoPg.Name <> "Page-1" Then
Enter name of your main menu page in place of "Page-1". That will prevent it from becoming hidden.
Thank you so much Wapperdude, all is good.
Dear Wapperdude,
I was wondering if you would help me again. I am trying to fit below to your code, the code is as I wanted but it is applicable for specific pages only, but I need the code only for the unhidden pages. Any idea?
Dim fn As String ' variable for filenames
Dim bl As Boolean ' flag for deletion
Dim j As Integer ' counter for pages
Dim pag As Page ' current page
fn = ActiveDocument.FullName ' get active filename
fn = Replace(fn, ".vsd", "_tmp.vsd") ' set filename for copy file
ActiveDocument.SaveAs fn ' create copy of your file
fn = Replace(fn, "_tmp.vsd", ".pdf") ' set filename for pdf file
For j = ActiveDocument.Pages.Count To 1 Step -1 ' iterate all pages
Select Case j
Case 1 To 3, 4, 6, 11 To 14 ' set of desirable page numbers
bl = False ' set flag as false
Case Else
bl = True ' set flag as true
End Select
If bl Then ActiveDocument.Pages(j).Delete 1 ' if current page have flag = true, this page deleted
Next
ActiveDocument.ExportAsFixedFormat visFixedFormatPDF, fn, visDocExIntentPrint, visPrintAll ' export copy file to pdf
This should do it. You need to edit 2nd subroutine to change the name of the temporary file. You can also code in a different file path if desired.
Run the first macro to hide the pages. It will call the 2nd macro which will first save a temporary file with name you provide. Then delete pages based upon visibility. Re-save. Then export to PDF.
Sub SrchLayers()
Dim vsoPg As Visio.Page
Dim pgLay As Visio.Layer
Dim visLayCnt As Double
For Each vsoPg In ActiveDocument.Pages
visLayCnt = 0
If vsoPg.Background = False Then
ActiveWindow.Page = vsoPg
For Each pgLay In vsoPg.Layers
If pgLay.Name <> "flrPlan" Then
If pgLay.CellsC(visLayerVisible).ResultStr(visNone) = "1" Then
visLayCnt = 1
End If
End If
Next
End If
If visLayCnt = 0 And vsoPg.Name <> "Page-1" Then
vsoPg.PageSheet.CellsU("UIVisibility").FormulaU = 1
Else
vsoPg.PageSheet.CellsU("UIVisibility").FormulaU = 0
End If
Next
ActiveWindow.Page = ActiveDocument.Pages(1)
Call TmpFile
End Sub
Sub tmpFile()
Dim pgCnt As Integer
Dim docPath As Variant
Dim tmpFile As String
docPath = ActiveDocument.Path
tmpFile = "DeleteMeHidePg"
ActiveDocument.SaveAsEx docPath & tmpFile & ".vsdm", visSaveAsWS + visSaveAsListInMRU
pgCnt = ActiveDocument.Pages.Count
For i = pgCnt To 1 Step -1
Set vsoPg = ActiveDocument.Pages(i)
If vsoPg.Background = False Then
If vsoPg.PageSheet.CellsU("UIVisibility").ResultStr(visNone) = "1" Then
vsoPg.Delete (1)
End If
End If
Next
ActiveDocument.Save
ActiveDocument.ExportAsFixedFormat visFixedFormatPDF, docPath & tmpFile & ".pdf", visDocExIntentPrint, visPrintAll, 1, 2, False, True, True, True, False
End Sub
Dear Wapperdude,
Thank you so much. By running the code, the visio original file will be closed and will open the temporary visio file. How to have the original visio file keep open, I do not need to have the temporary visio file open, I do not need the temporary visio file actually, but also how to have the pdf output open. At the moment I need to go to the folder and open it.
Please advise.
Many thanks.
Here's one method to open the PDF after saving. I include the save as PDF line for completeness.
Sub saveNopen PDF()
ActiveDocument.ExportAsFixedFormat visFixedFormatPDF, "C:\some path\some file.pdf", visDocExIntentPrint, visPrintAll, 1, 2, False, True, True, True, False
ActiveDocument.FollowHyperlink "C:\some path\some file.pdf", "Page-1"
End Sub
With regards to the tmp Visio file, as long as you have a backup for the original, skip the save as tmp file steps. Just loop thru and delete pages, then save as PDF. Once PDF is saved you can
1) close Visio without saving and re-open
or
2) loop thru the pages and set UIVisibility to 0...I think that should work...to see all of the pages. Then, if you have some other "hidden" agenda, you can make your visibility changes and run save as PDF again.