Hi All,
I am working on a Visio drawing template that is linked to an external data source. I want to be able to hide and disable printing for specific pages based on the external data. I can currently manage the hide component by using TheDoc shapesheet user cells and then referencing them in each page shapesheet for the UIVisibility cell. This works exactly how I want but cant work out how to disable print on the same pages.
I have had a look through and was not able to find anything suitable. I have tried the PagesX and PagesY cells, whilst this stops the drawing from being printed, there is still a blank page. I was looking for more of a not print at all option.
Does anyone have some ideas on how to achieve this?
I really suck at VBA so would prefer to avoid this option if feasible.
Thanks
dmac101
You can change pages to Background pages
https://visio-getbb-ru.translate.goog/viewtopic.php?p=14123&_x_tr_sl=ru&_x_tr_tl=en&_x_tr_hl=ru#p14123
Can pages be sent to the background using the page shapesheet?
Quote from: dmac101 on December 03, 2021, 06:58:37 AM
Can pages be sent to the background using the page shapesheet?
IMHO, you cant do it via shapesheet environment !
Only via user interface or your custom code.
mmmm custom code. This is something have been avoiding due to my lack of knowledge. Looks like I am going to get my hands dirty. Any suggestions on where to start?
In this post from 2012 (https://visio-getbb-ru.translate.goog/viewtopic.php?p=441&sid=4902975e345ff8bdffcce9dcc19a73ca&_x_tr_sl=ru&_x_tr_tl=en&_x_tr_hl=ru#p441) you can find my old code
Sub hidepages ()
Dim pg As Page 'defining the current page
Dim pgn As String' defining the name of the current page
Dim wn As Window 'defining the current window
For Each pg In ActiveDocument.Pages' iterating over the pages of the document
pgn = pg.Name' assigning the name of the page
s = MsgBox ("Hide page" & pgn, vbYesNo, "Hide pages") 'receive a response to hide the page
If s = 6 Then
pg.Background = True ' make current page as backgound
pg.CellsSRC (visSectionObject, visRowPage, visPageUIVisibility) .FormulaU = "1"' hide the current page
Else
pg.Background = False ' make current page as foregound
pg.CellsSRC (visSectionObject, visRowPage, visPageUIVisibility) .FormulaU = "0"' show the current page
End If
Next pg 'go to the next page
End Sub
Thanks Surrogate. The initial code had compile error. I removed the spaces before the FormulaU this now runs and i get the MsgBox but when i make a selection it has an "Object doesn't support this property or method" error'. However the page is moved to the background when i select Yes, it just doesn't iterate through the pages. I can now see how it works and will attempt to integrate into my drawing.
Thanks for you help
Quote from: dmac101 on December 03, 2021, 08:31:36 PM
The initial code had compile error.
You are right ! I didn't test code, just modify at my phone code which was written about decade years ago. Sorry!
Quote from: dmac101 on December 03, 2021, 08:31:36 PMit just doesn't iterate through the pages.
Just now i tested this code, it works at my side
Sub hidepages()
Dim pg As Page 'declaring the current page
Dim pgn As String ' defining the name of the current page
Dim wn As Window 'defining the current window
For i = ActiveDocument.Pages.Count To 1 Step -1 ' iterating over the pages of the document
Set pg = ActiveDocument.Pages(i) 'defining the current page
pgn = pg.Name ' assigning the name of the page
s = MsgBox("Hide page " & pgn, vbYesNo, "Please select pages for hide!") 'receive a response to hide the page
If s = 6 Then
pg.Background = True ' make current page as backgound
pg.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageUIVisibility).FormulaU = "1" ' hide the current page
Else
pg.Background = False ' make current page as foregound
pg.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageUIVisibility).FormulaU = "0" ' show the current page
End If
Next i 'go to the next page
End Sub
Thanks That works fine for me now.
I had already set the page visibility with linked external data, so i have modified your code above to set background based on each pages UIVisibility cell. Now i am just trying to work out how best to trigger this. I have set to page change but it does not work when the coverpage is updated by linking to another data row. Any suggestions?
Private Sub Document_PageChanged(ByVal Page As IVPage)
Dim pg As Page 'declaring the current page
Dim pgn As String ' defining the name of the current page
Dim wn As Window 'defining the current window
Dim vsoCell As Visio.Cell
Set pg = ActivePage
For i = ActiveDocument.Pages.Count To 1 Step -1 ' iterating over the pages of the document
Set pg = ActiveDocument.Pages(i) 'defining the current page
Set vsoCell = pg.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageUIVisibility)
If vsoCell = 1 Then
pg.Background = True ' make current page as backgound
Else
pg.Background = False ' make current page as foregound
End If
Next i 'go to the next page
End Sub
Quote from: dmac101 on December 05, 2021, 11:58:02 PM
I had already set the page visibility with linked external data
I.e. in your case UIVisibility managed by external data ? :o
Document_PageChanged event (https://docs.microsoft.com/vi-vn/office/vba/api/visio.documents.pagechanged) dont trigerred when you change page visibility ! it is dont fired even when you change page size...
My suggestion use DEPENDSON function (https://docs.microsoft.com/en-us/office/client-developer/visio/dependson-function) for triggered UIVisibility changes!
As first you need add user-defined cell with formula for each Page
CALLTHIS("Thisdocument.bb")+DEPENDSON(UIVisibility)
Also you need change your code
Sub bb(sh As Shape)
Dim par As Page
MsgBox sh.Name
Set par = sh.Parent
If par.PageSheet.Cells("UIVisibility").FormulaU Then
pg.Background = True ' make current page as background
Else
pg.Background = False ' make current page as foreground
End If
End Sub
After you hide and make page as background you cant see it in user interface !
You can navigate into document with keys Ctrl+/Ctrl+PgUp :o
Thanks Surrogate,
For some reason the pages that are hidden are sill printable.
I have modified the code with MsgBox's to provide debug info
The "par set" msgbox appears but nothing after that.
Sub bb(sh As Shape)
Dim par As Page
MsgBox sh.Name
Set par = sh.Parent
MsgBox "par set"
If par.PageSheet.Cells("UIVisibility").FormulaU Then
pg.Background = True ' make current page as background
MsgBox "Make Page Background"
Else
pg.Background = False ' make current page as foreground
MsgBox "Make Page Foreground"
End If
End Sub
The print dialog also allows you to print specific pages, e.g. 1-3,5,7,9-12.
I wonder if there is a way to send info to that field in the print dialog using code? If so, you could mark pages as "not to print" using a shape or some page-shapesheet cell/value. Then you could have a special My Print button that figures out which pages should not be printed. This code would send the correct syntax to the print dialog.
Quote from: Visio Guy on December 07, 2021, 03:52:38 PM
I wonder if there is a way to send info to that field in the print dialog using code?
Should be possible using SendKeys.
I just looked at Visio's print dialog/backstage panel. It doesn't support the ranges like Word or Adobe Reader do.
So temporary conversion to background seems like it might do the trick.
One question I had: "Does setting a page to background and then back again mess up the page order for the document?"
The answer is "Yes", since making a page a background sends it to the end of the page list.
So your code should add a user cell to any page that it flips between background/foreground, noting the "User.LastForegroundPageIndex". That way, the code can restore the page indices when the printing is done.
More über-nerd notes:
You can set the NonPrinting cell for a page, but it doesn't seem to do anything.
I don't think this cell displays in the ShapeSheet, but you can get to it via automation, e.g.:
Visio.ActivePage.PageSheet.CellsU("NonPrinting").FormulaU = "TRUE"
Visio doesn't seem to respect this cell, even though it technically exists. That is probably why it is hidden from the ShapeSheet UI. There are a lot of cells that appear to be inherited from some sort of base class, but the page object overrides them. For example Width and Height can be set for a page, but only PageWidth and PageHeight have any effect.
The page ID stays the same, but the index changes when a page is made a background or back to foreground.
Thanks for the suggestions.
At this point I would prefer to keep going on the current path as I believe that I am almost there.
I have narrowed this down to the UIVisibility field in the page shapesheet.
Below are the steps I have taken to determine this.
- add "MsgBox par.PageSheet.Cells("UIVisibility").FormulaU" before if statement in code
- response back in msgbox is "TheDoc!User.ExWks_Hidden" , I am storing the visibility for each page in it own cell within TheDoc shapesheet
I would have thought that it would have displayed the 1 or 0 that is in the "TheDoc!User.ExWks_Hidden" cell rather than the cell name but maybe it cant evaluate past the first cell.
- I have then replaced the cell reference in the UIVisibility cell for one of the pages for both a 1 & 0 but the page does not move to the background.
- I then realized that the variable declared for the page was not the same variable being used in the if statement.
This has been rectified and now if I change the UIVisibility cell from a reference to TheDoc to a 1 or a 0 I can get it to work.
Is there any way to treat the cell reference I have in the UIVisibility cell as the end value for the "If par.PageSheet.Cells("UIVisibility").FormulaU = 1" statement?
I have sorted out the print by using a user cell on each page with =SETF(GetRef(ThePage!UIVisibility),TheDoc!User.StLoc_hidden)
that way the UIVisibility has a value rather than a formula and the VBA code now works fantastically.
I agree, that when pages are pushed to the background and then pushed to foreground the change of order is a complete pain. This is now where i am focued
Hi Guys,
I am struggling trying to work out how to set the page index.
My approach is to manually set the index in a user cell of the page sheet.
then when the code runs on each page to bring to the foreground the index cell is looked up and value is set into page index.
This is what I have got so far but the page order does not change.
Any suggestions?
Sub bb(sh As Shape)
Dim par As Page
Dim pgindx As String
Set par = sh.Parent
If par.PageSheet.Cells("UIVisibility").FormulaU = 1 Then
par.Background = True ' make current page as background
Else
par.Background = False ' make current page as foreground
pgindx = par.PageSheet.CellsU("PageIndex")
par.Index = pgindx
End If
End Sub
Something like...
ActiveDocument.Pages.ItemU("Page-1").Index = 2
where "Page-1" is the pagename of the page you want to set the order.
I created a 3 page document. Used the following code to convert 1st page to background, and then back to foreground. Then, without touching the Index structure, I moved named page = "Page-2" to 3rd place in order. Finally moved "Page-1" to first position. All worked well.
It's unclear if you need to set pgindx. Use "par" to get the pagename and use the value of the PageSheet cell as the desired numerical value for ".index" = numerical value.
Sub ShflPgs()
'Convert Page-1 to background.
ActiveWindow.Page = ActiveDocument.Pages.ItemU("Page-1")
ActivePage.Background = True
ActivePage.BackPage = ""
'Convert background to foreground page
ActivePage.Background = False
'Change Positional order of Page-2 without updating Index count
ActiveDocument.Pages.ItemU("Page-2").Index = 3
'Reset positional order of Page-1
ActiveDocument.Pages.ItemU("Page-1").Index = 1
End Sub
Thanks wapperdude.
I was able to change the page index to a specific number using par.index = x, but when i try and pull the user cell "PageIndex" from the page shapesheet and substitute it, i cant get it to work.
I am calling this routine from each page only when the UIVisibility changes for the page.
Sub bb(sh As Shape)
Dim par As Page
Set par = sh.Parent
If par.PageSheet.Cells("UIVisibility").FormulaU = 1 Then
par.Background = True ' make current page as background
Else
par.Background = False ' make current page as foreground
par.Index = par.PageSheet.CellsU("PageIndex") ' set page index to page shapesheet user.PageIndex
'par.Index = 4
End If
End Sub
Looks like a silly mistake on my side it should be
par.Index = par.PageSheet.CellsU("user.PageIndex") ' set page index to page shapesheet user.PageIndex
This seems to work somewhat but not all of the pages are in the correct order. I suspect it is to do with the order in which they are being set. Ie if a page is being set to an index of 4, then another is being set to index of 2 it may be pushing the 4 to 5. Still investigating anyway.
Yep. When inserting, start at top of order and work down. Anything already in place gets pushed down relative to top spot. Think of someone cutting in line.
The other thing, .formula is used to assign something to a cell. Use .result to fetch from a cell.