MS Office Forum / Word / Programming / December 2007
List pages to print, select one page
|
|
Thread rating:  |
BruceM - 17 Dec 2007 13:39 GMT I have a situation where the user may select one of several possible pages to print. My idea (which may be off the mark, but it's what has occurred to me) is that each of the pages would contain a bookmark. I have adapted some code Jay Freedman posted about a year ago to list bookmarks. I run the code as a macro.
Dim bkm As Word.Bookmark Dim doc As Word.Document Dim strBkm As String Set doc = ActiveDocument strBkm = ""
For Each bkm In doc.Bookmarks strBkm = strBkm & bkm.Name & vbCrLf Next
MsgBox strBkm
This produces a list of bookmarks in the document. I realize the list as produced by this code is for display only, but what I hope is that the user can select from the list, thereby printing the page on which the bookmark appears. I already have worked out some code that can identify the page number. Maybe it would be something like:
Dim b1 as Long
b1 = ActiveDocument.Bookmarks("MoreStart").Range _ .Information(wdActiveEndAdjustedPageNumber) ActiveDocument.PrintOut _ Range:=wdPrintFromTo, From:=CStr(b1), To:=CStr(b1)
This may not be the smoothest way to accomplish what I need. For instance, maybe I can produce a list of bookmarks, and when the user selects one Word can go to that page, and I can use wdPrintSelection, or something like that. Or maybe there is another option I have not considered.
The main thing is that I would first need to have a user-selectable list to identify the page that needs to be printed.
Greg Maxey - 17 Dec 2007 14:36 GMT Bruce,
You probably don't want to clutter you list of pages the user can select from with any other bookmark name. One way to do this is with a UserForm.
Create a UserForm that contains a ListBox that list the pages the User can choose from (I would make it a multi-select list) and a Command Button.
Populate the Listbox with the list of pages bookmarked "Page_1", Page_2", etc.
Here is some sample code that you could use:
Private Sub CommandButton1_Click() Dim i As Long Dim pStr As String If ListBox1.ListIndex <> -1 Then For i = 0 To ListBox1.ListCount - 1 If ListBox1.Selected(i) Then pStr = pStr + ListBox1.List(i) & ", " End If Next i End If 'Clean up string pStr = Left(pStr, Len(pStr) - 2) 'PrintOut Application.PrintOut Range:=wdPrintRangeOfPages, Pages:=pStr Unload Me End Sub
Private Sub UserForm_Initialize() Dim oBM As Bookmark Dim oBMs As Bookmarks Set oBMs = ActiveDocument.Bookmarks For Each oBM In oBMs If InStr(oBM.Name, "Page_") > 0 Then Me.ListBox1.AddItem Mid(oBM.Name, 6, Len(oBM.Name) - 5) End If Next End Sub
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> I have a situation where the user may select one of several possible > pages to print. My idea (which may be off the mark, but it's what [quoted text clipped - 34 lines] > The main thing is that I would first need to have a user-selectable > list to identify the page that needs to be printed. BruceM - 17 Dec 2007 20:10 GMT Thanks for the reply. I am not very familiar with user forms, but I did manage to create one and add a list box. In many cases the user will not print the selected pages, but will only view the document. Right now the user navigates to the required page and clicks a custom toolbar item to run a macro, causing the current page to print. The Help documentation, however, is vague at best about how to actually open or run a userform.
After poking around some more I managed to create a userform with a list box, and to populate the list box with selected bookmarks. The user form is opened when a macro is run. I used the list box After Update event to print the page on which the selected bookmark is located. First I call the user form (named fusrBkm) from a macro: fusrBkm.Show I do it this way because the situation is somewhat more complex than I have shown: one or more pages other than the one with the selected bookmark may need to be printed. The macro identifies other bookmarks and sets the print range(s) accordingly.
Other code (the list box is lstBkm):
Private Sub UserForm_Initialize()
Dim oBM As Bookmark Dim oBMs As Bookmarks
Set oBMs = ActiveDocument.Bookmarks
For Each oBM In oBMs If InStr(oBM.Name, "_") <> 0 Then Me.lstBkm.AddItem (oBM.Name) End If Next
End Sub
I read several times in my research that a DocVariable may be used instead of a bookmark. I thought that if I could do that I wouldn't need to worry about filtering the list of bookmarks, but I could not figure out how to list DocVariables in the list box. Since I don't even know if it's possible, I didn't spend that much time trying.
Private Sub lstBkm_AfterUpdate()
Dim i As Long Dim strBkm As String Dim pStr As String
If fusrBkm.lstBkm.ListIndex <> -1 Then For i = 0 To fusrBkm.lstBkm.ListCount - 1 If fusrBkm.lstBkm.Selected(i) Then pStr = pStr + fusrBkm.lstBkm.List(i) & ", " End If Next i End If 'Clean up string pStr = Left(pStr, Len(pStr) - 2)
'PrintOut strBkm = ActiveDocument.Bookmarks(pStr).Range.Information(wdActiveEndAdjustedPageNumber) Application.PrintOut Range:=wdPrintFromTo, From:=strBkm, To:=strBkm
Unload Me
I could not get the ListIndex or any other properties for lstBkm unless I drilled down through the userform name. Also, I kept getting an error (invaalid print range, I think) when I tried: Application.PrintOut Range:=wdPrintRangeOfPages, Pages:=pStr
Anyhow, it seems to work. I would be interested in clearing up the remaining questions, but it seems to be something I can work with. Thanks again.
> Bruce, > [quoted text clipped - 75 lines] >> The main thing is that I would first need to have a user-selectable >> list to identify the page that needs to be printed. Greg Maxey - 17 Dec 2007 20:58 GMT Bruce,
I am not completely sure that I know what your ulitimate goal is. The code sent to you was tied to a document that had a bookmark name "Page_1" on page 1, Page_2 on page 2, etc. There was also the possibility that other bookmarks where present in the document.
The UserForm initialize code strips out "Page_" from the bookmark name and populates the Listbox with 1, 2, 3, etc.
The ListBox was a multi-select box so if the user wants to print pages 1, 3, and 5 then they would select those pages and then press the command button to print.
Using the AfterUpdate event like you do would make a dog's breakfast out of that approach ;-)
To populate a listbox with Variables you have to first create the variables e.g.,
Sub CreateSomeDocVariables() Dim oVar As Variables Set oVar = ActiveDocument.Variables oVar("1-3").Value = "1-3" oVar("4").Value = "4" oVar("6-9").Value = "6-9" End Sub
And then populate the listbox:
Private Sub UserForm_Initialize() Dim oVar As Variable Dim oVars As Variables Set oVars = ActiveDocument.Variables For Each oVar In oVars Me.ListBox1.AddItem oVar.Name Next End Sub
Private Sub UserForm_Initialize() Dim oVar As Variable Dim oVars As Variables Set oVars = ActiveDocument.Variables For Each oVar In oVars Me.ListBox1.AddItem oVar.Name Next End Sub
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> Thanks for the reply. I am not very familiar with user forms, but I > did manage to create one and add a list box. In many cases the user [quoted text clipped - 153 lines] >>> The main thing is that I would first need to have a user-selectable >>> list to identify the page that needs to be printed. BruceM - 18 Dec 2007 15:04 GMT The document is a technical package of work instructions, including a routing slip (one page of the document with the manufacturing steps summarized). Most technical packages have only one routing slip. However, some packages have a choice of routing slips. I understand what you are saying about the multi-select list box. If it is needed I can add a command button, but as it stands only one routing slip will be selected. However, it could be that a command button is more comfortable for the user, since they will have a chance to take another look at what they have selected before printing it. The code would be the same as in the After Update event. Other pages, such as a log for measurements, etc., will be printed in every case, so there is no user input.
I have realized that some of the code assumes a multi-select list box, and that with a single-select list box it can be simplified: i = fusrBkm.lstBkm.ListIndex pStr = fusrBkm.lstBkm.List(i)
Sorry I didn't describe my needs more clearly from the first, but I will say that the multi-select code is now part of my code library. I expect I will use it one day.
Regarding the use of variables, I had thought it was a matter of inserting a DocVariable field, then referencing that field. My early experiments showed me that it is not that simple. The Initialize code you provided (and which I had tried on my own before the previous post) produces an empty list.
I have done some more research, and have discovered that I can list the fields by way of: Dim fldVar As Field
For Each fldVar In ActiveDocument.Fields If fldVar.Type = wdFieldDocVariable Then ' Parse the field to remove field type, etc. End If Next fldVar
I would parse the field to make it more user-friendly in the list. However, I suppose I would need to reassemble it in order to find the page number, if it is possible at all to find the page on which a field is located. I see no advantage over bookmarks, even if I can get it to work. It's interesting to experiment with it, but I think it is outside this project's scope. It seems to do the trick as it is, so it's probably time to move on with other projects.
Thanks for all of your help with this.
> Bruce, > [quoted text clipped - 201 lines] >>>> The main thing is that I would first need to have a user-selectable >>>> list to identify the page that needs to be printed. Greg Maxey - 18 Dec 2007 15:41 GMT Bruce,
Yes I would use a command button. I think most people would find it odd for the forms to immediately begin printing on a click in the listbox. In fact, you might save paper if you added a confirmation message box in the command button code that told the User what pages where about to be printed and offer an OK/Cancel options.
I would just use:
If lstBkm.ListIndex <> -1 Then pStr = lstBkm End If
... as the simplified code for defining the initial pStr.
The part I am still missing is what exactly to you want to appear in the Listbox? Do you want something like:
Label: Chose Pages to print: 1 2-3 5 6-9
and are these values fixed?
If so, I don't see why you need bookmarks or anything else in the document itself.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> The document is a technical package of work instructions, including a > routing slip (one page of the document with the manufacturing steps [quoted text clipped - 248 lines] >>>>> The main thing is that I would first need to have a user-selectable >>>>> list to identify the page that needs to be printed. BruceM - 18 Dec 2007 17:41 GMT I think I will use a command button, as you suggest, for the reasons you mention.
The bookmarks (or something) are needed to identify the page. The page number alone is not enough information, unless the user is going to scroll around in the document to identify the page number. For instance, one routing slip may be Apply Coating. Another would be Coat and Polish. Then maybe there is an appendix: Strip Coating. The list box would show: Apply Coating Coat and Polish Strip Coating
Of course, the bookmarks have underscores instead of spaces, but I replace them with spaces for the list box, then reverse the replacement so the code can identify the page number.
If the document contains only one routing slip, the user runs a macro (by way of a toolbar button) that prints everything from the bookmark DocStart to the bookmark DocEnd. If a document contains more than one routing slip, so that a choice needs to be made, the existence of a ChoosePage bookmark brings up the user form.
> Bruce, > [quoted text clipped - 278 lines] >>>>>> The main thing is that I would first need to have a user-selectable >>>>>> list to identify the page that needs to be printed. Greg Maxey - 19 Dec 2007 02:14 GMT Bruce,
I suppose my remaining question is: Do you know the page range of "Apply Coating," "Strip Coating," etc.?
If so then I still don't see the need for Bookmarks or anything else in the document.
If you (as the document author) know the page number of the various routing slips then build the Listbox list in the initialize procedure
and then in the command button procedure use the user selection to define a string that makes sense to the PrintOut method.
Dim printStr As String Select Case Me.lstBkm Case Is = "Apply Coating" printString = "1-3" Case Is = "Strip Coating" printString = "6, 8-9" Case Else MsgBox "You didn't pick a routing slip to print" Exit Sub End Select Application.PrintOut Range:=wdPrintRangeOfPages, Pages:=pStr Unload Me
If I am missing your mark then just ignore my comments has hapless ramblings.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> I think I will use a command button, as you suggest, for the reasons > you mention. [quoted text clipped - 310 lines] >>>>>>> user-selectable list to identify the page that needs to be >>>>>>> printed. BruceM - 19 Dec 2007 13:39 GMT I need to apply the code to many documents. I gave a simplified example with Apply Coating and Strip Coating. The technical packages are for a diverse range of processes on a wide assortment of parts. Depending on the customer, one technical package may be for several dozen parts. They are grouped in categories, but one type of part may require certain processes. Another group of the same type of part may require something like an additional coating on a portion of the part. Without going into a lot of details about that, even if two technical packages have Strip Coating and Apply Coating routing slips, there is no guarantee they are on the same page. This is due in some cases to the fact that different people over the years have developed the technical packages, and in other cases to different requirements from customer to customer. Bookmarks have the advantage of allowing me to add them to the document and then not worry about the coding. One disadvantage is that I need to come up with a naming convention that will allow me to filter the list to just the ones that need to appear in the list box. Right now I am using underscores, but I may end up adding something such as R__ to the start of the list bookmarks, and test for that before adding it to the list box. I can remove unnecessary characters for display, then add them back later, which is what I am doing now with the underscores. However, underscores are common in bookmarks, so another type of "flag" may be a better choice in order to avoid extra items on the list. In investigating bookmarks I looked up some information on hidden bookmarks, which I gather are parts of cross-references, although I can't seem to stumble upon it now. With the Word Help dialog being a Microsoft creation it is all but useless for specific searches such as "hidden bookmark". I wonder if there is some coherent information somewhere about such things as hidden bookmarks and cross-reference fields. They are potentially useful, although my early experiments are not encouraging. I can insert a cross-reference as a hyperlink, but I can't make it look like a hyperlink, and I can't seem to control the text that is displayed. I realize this is OT relative to the original post, but as I said it came up, and now I am curious as to whether I can put the information and techniques to use.
> Bruce, > [quoted text clipped - 340 lines] >>>>>>>> user-selectable list to identify the page that needs to be >>>>>>>> printed.
|
|
|