Visio Guy

Visio Discussions => Programming & Code => Topic started by: bangzii75 on February 28, 2019, 02:53:37 PM

Title: Show pages that have active layer only
Post by: bangzii75 on February 28, 2019, 02:53:37 PM
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.
Title: Re: Show pages that have active layer only
Post by: Paul Herber on February 28, 2019, 02:57:06 PM
If the page is hidden how would you enable a layer on that page?
Title: Re: Show pages that have active layer only
Post by: wapperdude on February 28, 2019, 08:57:55 PM
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.
Title: Re: Show pages that have active layer only
Post by: bangzii75 on March 06, 2019, 01:09:53 PM
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.

Title: Re: Show pages that have active layer only
Post by: bangzii75 on March 06, 2019, 01:10:36 PM
missing attachement.
Title: Re: Show pages that have active layer only
Post by: wapperdude on March 06, 2019, 03:19:44 PM
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.
Title: Re: Show pages that have active layer only
Post by: bangzii75 on March 06, 2019, 07:17:46 PM
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.
Title: Re: Show pages that have active layer only
Post by: wapperdude on March 06, 2019, 08:53:40 PM
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
Title: Re: Show pages that have active layer only
Post by: wapperdude on March 07, 2019, 03:44:54 AM
...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
Title: Re: Show pages that have active layer only
Post by: bangzii75 on March 11, 2019, 01:48:27 PM
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
Title: Re: Show pages that have active layer only
Post by: wapperdude on March 11, 2019, 09:11:00 PM
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.
Title: Re: Show pages that have active layer only
Post by: bangzii75 on March 12, 2019, 07:17:46 PM
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
Title: Re: Show pages that have active layer only
Post by: wapperdude on March 12, 2019, 09:44:16 PM
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.

Title: Re: Show pages that have active layer only
Post by: bangzii75 on March 13, 2019, 11:45:23 AM
Thank you so much Wapperdude, all is good.
Title: Re: Show pages that have active layer only
Post by: bangzii75 on March 13, 2019, 01:26:28 PM
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

Title: Re: Show pages that have active layer only
Post by: wapperdude on March 13, 2019, 03:34:23 PM
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
Title: Re: Show pages that have active layer only
Post by: bangzii75 on March 21, 2019, 03:01:58 PM
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.
Title: Re: Show pages that have active layer only
Post by: wapperdude on March 21, 2019, 09:01:13 PM
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.