Microsoft Office Forums

Go Back   Microsoft Office Forums > >

Reply
 
Thread Tools Display Modes
  #1  
Old 05-22-2018, 02:12 AM
kiwimtnbkr kiwimtnbkr is offline SENDKEYS with vbYesNoCancel and Select Case Windows 10 SENDKEYS with vbYesNoCancel and Select Case Office 2010 64bit
Advanced Beginner
SENDKEYS with vbYesNoCancel and Select Case
 
Join Date: Oct 2017
Posts: 69
kiwimtnbkr is on a distinguished road
Default SENDKEYS with vbYesNoCancel and Select Case

It is possible that when the user runs the code below and clicks No in the first messagebox that a SENDKEYS routine of Alt+F+P+D, followed by a wait for the user to select 'Print on Both Sides' is run?


Then after the user has made the selection another SENDKEYS routine of Esc Alt+S+Y is run the initiate the rest of the macro.

Or is there another better way of achieving the leadup into the main part of the routine?

Code:
Sub PrintNumberedCopiesEntireDocument()
'
' PrintNumberedCopiesEntireDocument Macro
' Shortcut keys Alt+E
'
Dim Msg As String, Ans As Variant
    Dim lCopiesToPrint As Long
    Dim lCounter As Long
    Dim lCopyNumFrom As Long
    
   Ans = MsgBox(Space(1) & "Is the document print settings configured for 'Print on Both Sides?" & vbCrLf & vbCrLf & _
        "If not then click 'No', click the 'File' tab, 'Print', select 'Print on Both Sides / Flip pages on long edge' and then press 'Alt+S'.", _
        vbMsgBoxSetForeground + vbQuestion + vbYesNoCancel, (Space(50) & "ABCDF 1234"))
   
       Select Case Ans
             
        Case vbYes
        Case vbNo
        End
        Case vbCancel
        End
        
End Select

    ' ask how many to print
    On Error GoTo Canceled
    lCopiesToPrint = InputBox( _
        Prompt:="How many copies do you require?", _
        Title:=(Space(45) & "ABCDF 1234"), _
        Default:="1")
     
    ' ask where to start numbering
    On Error GoTo Canceled
        lCopyNumFrom = InputBox( _
        Prompt:="Number at which to start numbering copies?", _
        Title:=(Space(45) & "ABCDF 1234"), _
        Default:=CStr(ActiveDocument.Variables("CopyNum") + 1))
        
    ' loop through the print-write-print cycle
    For lCounter = 0 To lCopiesToPrint - 1
        ' update the document variable
        ActiveDocument.Variables("CopyNum") = _
            lCopyNumFrom + lCounter
                With Options
                    .UpdateFieldsAtPrint = False
                    .UpdateLinksAtPrint = True
                End With
                    ActiveDocument.Fields.Update
        ' print this numbered copy
        ActiveDocument.PrintOut Copies:=1
    Next lCounter
    
Canceled:

End Sub
cheers
Mike
Reply With Quote
  #2  
Old 05-22-2018, 12:50 PM
slaycock slaycock is offline SENDKEYS with vbYesNoCancel and Select Case Windows 7 64bit SENDKEYS with vbYesNoCancel and Select Case Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

You need to use the 'Visual' bit of VBA and design yourself a user form which collects all of the information you need.

There are lots of tutorials on the web so I'm not going to redo that here.

Yours won;t be complicated as it looks like you only need two text fields to collect the information you need.

A couple of comments on your code.

1. The select case for Ans does nothing because you have no code following the case statements.

2. Consider switching from a document variable to a custom document property. The advantage of a custom document property is you can edit the value from the properties dialog box which is accessed via the Backstage page.
Reply With Quote
  #3  
Old 05-22-2018, 05:29 PM
kiwimtnbkr kiwimtnbkr is offline SENDKEYS with vbYesNoCancel and Select Case Windows 10 SENDKEYS with vbYesNoCancel and Select Case Office 2010 64bit
Advanced Beginner
SENDKEYS with vbYesNoCancel and Select Case
 
Join Date: Oct 2017
Posts: 69
kiwimtnbkr is on a distinguished road
Default

I can't claim any of the code as my own - it's what I have found by searching google for what I want to do and then trial and error to see if it works as I want it to, so unfortunately for me, your comments are way over my level of ability to understand what your saying.

And there is a second bit of code that allows a selection of pages to printed that I haven't posted. I had figured that I might have been able to cut and paste any changes between the two lots of code.

As to using the Visual part of VBA - I started heading down that road but the 'tutorials' ended up, again, going over my head so I gave that idea away.

Having said that - thanks for the reply - much appreciated.
Reply With Quote
  #4  
Old 05-23-2018, 02:59 AM
slaycock slaycock is offline SENDKEYS with vbYesNoCancel and Select Case Windows 7 64bit SENDKEYS with vbYesNoCancel and Select Case Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

You might know more than you think. If you have enough knowledge to get as far as opening the VBA IDE and tinkering with code then you have enough knowledge to have a go at at least trying to create a form.

Lets assume that you want a simple form that has two input boxes and two buttons (OK and Cancel).

In the VBA IDE use

Insert.UserForm

This will open up a page that displays an empty userform.

You will also see in the 'Properties' window a set of properties available to the form.

Change the Name to 'ufrmPrintNumberedCopies'
Change the Caption to 'Print Numbered Copies'

When you change the caption text what you entered should appear in the blue bar at the top of the user form.

See if you can get this far. If you can then with a small amount of guidance it should be perfectly possible for you to revise your code to use a user dialog box.

If you don't see a properties windows (usually in the bottom left corner of the screen) then you will need to enable its display.

inthe VBA IDE

View.Properties Window
Reply With Quote
  #5  
Old 05-23-2018, 12:10 PM
kiwimtnbkr kiwimtnbkr is offline SENDKEYS with vbYesNoCancel and Select Case Windows 10 SENDKEYS with vbYesNoCancel and Select Case Office 2010 64bit
Advanced Beginner
SENDKEYS with vbYesNoCancel and Select Case
 
Join Date: Oct 2017
Posts: 69
kiwimtnbkr is on a distinguished road
Default

thank you - successfully managed to follow those steps.
Reply With Quote
  #6  
Old 05-23-2018, 12:56 PM
slaycock slaycock is offline SENDKEYS with vbYesNoCancel and Select Case Windows 7 64bit SENDKEYS with vbYesNoCancel and Select Case Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

Excellent

The next step is to add two frames, two text boxes and two buttons.

The frames will act as 'containers for the text boxes but more importantly allow the function of the text boxes to be displayed on the form.

Locate the Toolbox. If you can't see it on screen then

View.Toolbox

In the array of controls th\at are displayed select the frame control. This is the square box with XY at the top.

Click on the tool the move to your form. Click and drag in your form to draw the two frames. The frames should be wide enough and deep enough to get a text box inside. You can do this by dragging or by setting the Height and Width properties. Try for 34 as the height of the frame, 6 for Left and Top.

You should end up with two boxes with the XY being replaced by Frame 1 and Frame 2

Change the caption of Frame 1 to 'Number of copies to print'

Change the caption of Frame 2 to 'Start Number'

Drag the size of the form and or frames to get everything to fit.

To get things lines up you can use the various options in the Format Menu item

Now add text boxes inside the frames. The text box control is the one with ABC in it next to the big A.

Its easier now to enter the properties for top left and height as 6,6,16

You can now click inside each text box and type any default text you wish to appear. We can also set the default text programmatically during the form initialization so it not essential to add default text now.

Change the names of the text boxes

TexrBox1 to txtCopies
TextBox2 to txtStartNumber

Finally for this stage add the two buttons using the button tool. This is the box with rounded corners containing 'ab'

Place the two buttons on the same horizontal line and then change the caption for the left button to 'Cancel' and the for the Right button to 'OK' and the Names of the buttons to cmdCancel and cmdOK respectively

See how you get on with those actions
Reply With Quote
  #7  
Old 05-23-2018, 01:04 PM
slaycock slaycock is offline SENDKEYS with vbYesNoCancel and Select Case Windows 7 64bit SENDKEYS with vbYesNoCancel and Select Case Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

You should end up with something like the attached jpg.
Attached Images
File Type: jpg NumberOfCopiesToPrint.JPG (37.0 KB, 57 views)
Reply With Quote
  #8  
Old 05-24-2018, 01:15 AM
kiwimtnbkr kiwimtnbkr is offline SENDKEYS with vbYesNoCancel and Select Case Windows 10 SENDKEYS with vbYesNoCancel and Select Case Office 2010 64bit
Advanced Beginner
SENDKEYS with vbYesNoCancel and Select Case
 
Join Date: Oct 2017
Posts: 69
kiwimtnbkr is on a distinguished road
Default

this is what your very concise instructions lead to - note this is zoomed to 200%.
Attached Images
File Type: png Screenshot 2018-05-24 20.10.56.png (15.0 KB, 51 views)
Reply With Quote
  #9  
Old 05-28-2018, 01:42 PM
slaycock slaycock is offline SENDKEYS with vbYesNoCancel and Select Case Windows 7 64bit SENDKEYS with vbYesNoCancel and Select Case Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

Sorry for the delay in responding.

The code to be inserted in ufrmPrintNumberedCopies is below.

Code:
Option Explicit

Private self_result                                          As Boolean

Private Sub UserForm_Initialize()

    Me.StartUpPosition = 0
    Me.Top = Application.Top + (0.5 * Application.Height) - (Me.Height / 2)
    Me.Left = Application.Left + (0.5 * Application.width) - (Me.width / 2)
    
End Sub

Private Sub cmdCancel_Click()

    self_result = False
    Me.Hide
    
End Sub

Private Sub cmdOK_Click()

    If form_validates_ok Then
       self_result = True
       Me.Hide
       Exit Sub
    End If
End Sub


Public Property Get Result() As Boolean

    Result = self_result
    
End Property

Private Function form_validates_ok() As Boolean

    If Not IsNumeric(Trim(Me.txtCopies)) Then
        MsgBox "The number of copies should be a number", vbOKOnly
        Me.txtCopies.SetFocus
        Me.txtCopies.SelLength = Len(Me.txtCopies)
        form_validates_ok = False
        Exit Function
    End If
    
    If Not IsNumeric(Trim(Me.txtStartNumber)) Then
        MsgBox "The start number should be a number", vbOKOnly
        Me.txtStartNumber.SetFocus
        Me.txtStartNumber.SelLength = Len(Me.txtStartNumber)
        form_validates_ok = False
        Exit Function
    End If
    
    form_validates_ok = True
    
End Function
Add the code below to a normal module. It replaces the code you posted above.

Code:
Sub PrintNumberedCopiesEntireDocument()
'
' PrintNumberedCopiesEntireDocument Macro
' Shortcut keys Alt+E
'

Const cdp_name                          As String = "CopyNum"
Const default_copies                    As String = "1"
Const duplex_printer                    As String = "Dell Printer 5100cn PS Duplex"  ' change this to the name of your duplex printer

Dim my_form                             As ufrmPrintNumberedCopies
Dim copy_number                         As Long
Dim first_copy                          As Long
Dim last_copy                           As Long
Dim my_update_fields_at_print           As Boolean
Dim my_update_link_at_print             As Boolean
Dim current_printer                     As String


    ' We are using a custom Document Property to save the serial number
    ' as we can edit this from the backstage properties advanced dialog
    ' if needed
    
    ensure_cdp_exists cdp_name
    
    Set my_form = New ufrmPrintNumberedCopies
    
    With my_form
        .txtStartNumber = Trim(ActiveDocument.CustomDocumentProperties(cdp_name))
        .txtCopies = default_copies
        .Show
            
        If Not .Result Then
            Exit Sub
        End If
    End With
    
    ' We now switch to the document printer that has been customised to aleays
    ' print in duplex
    
    current_printer = ActivePrinter
    ActivePrinter = duplex_printer
    
    ' The update fields and links at print time are application properties so anly need setting once
    ' but we preserve the values so we can restore the current settings after we have finished printing
    
    With Options
    
        my_update_fields_at_print = .UpdateFieldsAtPrint
        .UpdateFieldsAtPrint = True
        
        my_update_link_at_print = .UpdateLinksAtPrint
        .UpdateLinksAtPrint = True
        
    End With

    
    first_copy = CLng(Trim(my_form.txtStartNumber))
    last_copy = first_copy + CLng(Trim(my_form.txtCopies)) - 1
   
   
    MsgBox "Now we do the printing", vbOKOnly   'comment this out once tested
    
    ' it is assumed that there is a field somewhere that references the customdocumentproperty
    
'    For copy_number = first_copy To last_copy  ' uncomment the for loop once tested
'        ActiveDocument.CustomDocumentProperties(cdp_name) = Cstr(copy_number)
'        ActiveDocument.PrintOut copies:=1
'    Next
    
    
    ' save the next starting serial number
    ActiveDocument.CustomDocumentProperties(cdp_name) = last_copy + 1
    
    
    ' restore saved settings
    With Options
        .UpdateFieldsAtPrint = my_update_fields_at_print
        .UpdateLinksAtPrint = my_update_link_at_print
    End With

    ActivePrinter = current_printer

End Sub

Sub ensure_cdp_exists(cdp_name As String)
'cdp is short for CustomDocumentProperty

    ' Searches for the a custom document property of cdp_name
    ' If not found the custom document property is created and assigned a value of 1

Const default_start_number         As String = "1"

Dim my_cdp                          As DocumentProperty

    For Each my_cdp In ActiveDocument.CustomDocumentProperties
    
        If my_cdp.name = cdp_name Then
            Exit Sub
        End If
   
    Next
    
    ' We only get to this point if we don't find the target custom document property
    ' using the previous loop
    
    ActiveDocument.CustomDocumentProperties.Add _
        name:=cdp_name, _
        LinkToContent:=False, _
        Value:=default_start_number, _
        Type:=msoPropertyTypeString
    
    ' Be gentle with the user and let them know what has happened.
    MsgBox _
        Title:="Missing CustomDocumentProperty", _
        prompt:="CustomDocumentProperty '" & cdp_name & "' was added to the document" & vbCrLf & vbCrLf & "A value of '" & default_start_number & "' was assigned'", _
        Buttons:=vbOKOnly
    
End Sub
With the above code there is good news and bad news.

The bad news is that it seems virtually impossible to set duplex printing in word via VBA.

I've tried the PCL 5 trick of embedding a print field in the header but this fails with PCL 6.

I've tried using sendkeys but for whatever reason the specific button on the print backstage tab cannot be selected in this way.

I've also tried adapting code from here

https://support.microsoft.com/en-us/...mation-clients

and whilst I have successfully got the code to run in a 64 bit system, actually getting Duplex printing has eluded me.

The good news is that all of the above can be avoided by installing a dedicated duplex printer.

You do this be reinstalling the current printer, saying yes to use the current printer driver, and then just add duplex to the end of the name in the final part of the dialog box.

You can then access the printers properties and set the defaults for whatever you want and fortunately, duplex printing is one of these options (if it is supported by the printer).

It is then very simple code to switch the active printer in VBA to use the duplex printer (as demonstrated above).

Let us know if you have any problems with the code above.
Reply With Quote
  #10  
Old 05-29-2018, 01:31 AM
kiwimtnbkr kiwimtnbkr is offline SENDKEYS with vbYesNoCancel and Select Case Windows 10 SENDKEYS with vbYesNoCancel and Select Case Office 2010 64bit
Advanced Beginner
SENDKEYS with vbYesNoCancel and Select Case
 
Join Date: Oct 2017
Posts: 69
kiwimtnbkr is on a distinguished road
Default

Absolutely not a worry with the delay in your reply, was kind of expecting it - and the wait was worth it!

After a very minor change to three lines of your code (highlighted below) it most certainly works at home so massive thanks. Will try tomorrow at work and see what happens.

Code:
Sub PrintNumberedCopiesEntireDocument()
'
' PrintNumberedCopiesEntireDocument Macro
' Shortcut keys Alt+E
'

Const cdp_name                          As String = "CopyNum"
Const default_copies                    As String = "1"
Const duplex_printer                    As String = "hp deskjet 5550 series (HPA) duplex"  ' change this to the name of your duplex printer

Dim my_form                             As ufrmPrintNumberedCopies
Dim copy_number                         As Long
Dim first_copy                          As Long
Dim last_copy                           As Long
Dim my_update_fields_at_print           As Boolean
Dim my_update_link_at_print             As Boolean
Dim current_printer                     As String


    ' We are using a custom Document Property to save the serial number
    ' as we can edit this from the backstage properties advanced dialog
    ' if needed
    
    ensure_cdp_exists cdp_name
    
    Set my_form = New ufrmPrintNumberedCopies
    
    With my_form
        .txtStartNumber = Trim(ActiveDocument.Variables(cdp_name))
        .txtCopies = default_copies
        .Show
            
        If Not .Result Then
            Exit Sub
        End If
    End With
    
    ' We now switch to the document printer that has been customised to aleays
    ' print in duplex
    
    current_printer = ActivePrinter
    ActivePrinter = duplex_printer
    
    ' The update fields and links at print time are application properties so anly need setting once
    ' but we preserve the values so we can restore the current settings after we have finished printing
    
    With Options
    
        my_update_fields_at_print = .UpdateFieldsAtPrint
        .UpdateFieldsAtPrint = True
        
        my_update_link_at_print = .UpdateLinksAtPrint
        .UpdateLinksAtPrint = True
        
    End With

    
    first_copy = CLng(Trim(my_form.txtStartNumber))
    last_copy = first_copy + CLng(Trim(my_form.txtCopies)) - 1
   
   
'    MsgBox "Now we do the printing", vbOKOnly   'comment this out once tested
    
    ' it is assumed that there is a field somewhere that references the customdocumentproperty
    
     For copy_number = first_copy To last_copy  ' uncomment the for loop once tested
         ActiveDocument.Variables(cdp_name) = CStr(copy_number)
         ActiveDocument.PrintOut copies:=1
     Next
    
    
    ' save the next starting serial number
    ActiveDocument.Variables(cdp_name) = last_copy + 1
    
 ' snipped as the remainder of the code is not changed
Another question (and one I should have asked right from the outset - sorry!) is that there is the need to be able to just print certain pages of the document but retaining the ability of being able to specify the number of copies required and the starting serial number.

This is the code that was being used:
Code:
Sub PrintNumberedCopiesSelectionofPages()
'
' PrintNumberedCopiesSelectionofPages Macro
' Shortcut Key Alt+S
'
Dim Msg As String, Ans As Long
    Dim lCopiesToPrint As Long
    Dim lCounter As Long
    Dim lCopyNumFrom As Long
    Dim strPages As String
        
     Ans = MsgBox(Space(1) & "Is the document print settings configured for 'Print on Both Sides?" & vbCrLf & vbCrLf & _
        "If not then click 'No', click the 'File' tab, 'Print', select 'Print on Both Sides / Flip pages on long edge' and then press 'Alt+S'.", _
        vbMsgBoxSetForeground + vbQuestion + vbYesNoCancel, (Space(50) & "ABCDF 1234" & Application.Name))
   
       Select Case Ans
             
        Case vbYes
        Case vbNo
        End
        Case vbCancel
        End
        
End Select

    ' ask how many to print
    On Error GoTo Canceled
    lCopiesToPrint = InputBox( _
        prompt:="How many copies do you require?", _
        Title:=(Space(45) & "ABCDF 1234"), _
        Default:="1")
 
    ' ask where to start numbering
    On Error GoTo Canceled
    lCopyNumFrom = InputBox( _
        prompt:="Number at which to start numbering copies?", _
        Title:=(Space(45) & "ABCDF 1234"), _
        Default:=CStr(ActiveDocument.Variables("CopyNum") + 1))
        
    ' ask what pages need printing
      On Error GoTo Canceled
      strPages = InputBox( _
         prompt:="What pages require printing?", _
         Title:=(Space(45) & "ABCDF 1234"), _
         Default:="1-4")
      
    ' loop through the print-write-print cycle
    For lCounter = 0 To lCopiesToPrint - 1
        ' update the document variable
        ActiveDocument.Variables("CopyNum") = _
            lCopyNumFrom + lCounter
                With Options
                    ' .UpdateFieldsAtPrint = False
                    .UpdateLinksAtPrint = True
                End With
                    ActiveDocument.Fields.Update
        ' print this numbered copy
         ActiveDocument.PrintOut Range:=wdPrintRangeOfPages, Pages:=strPages
         
    Next lCounter
 
Canceled:
 
End Sub
I have created another userform (ufrmPrintNumberedCopiesSelect) and incorporated frame 3 with the caption 'What pages require printing?' and textbox3 to read txtPages.

Screenshot 2018-05-29 20.19.15.png

One sticking point I have when I modified the code from ufrmPrintNumberedCopies is that it doesn't recognise the hyphens for the page range...

Code:
If Not IsNumeric(Trim(Me.txtPages)) Then
        MsgBox "The pages required should be a number", vbOKOnly
        Me.txtPages.SetFocus
        Me.txtPages.SelLength = Len(Me.txtPages)
        form_validates_ok = False
        Exit Function
    End If
Will it be easy in a new module to add to your previously written code the ability to print just certain pages?
Reply With Quote
  #11  
Old 05-29-2018, 02:47 AM
slaycock slaycock is offline SENDKEYS with vbYesNoCancel and Select Case Windows 7 64bit SENDKEYS with vbYesNoCancel and Select Case Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

Well done. I'm impressed with your ability to extend the userform based on previous instructions.

Its very easy to update the code to validate the page range you want.

The first trick is to use the Trim and Replace functions to get rid of any commas and hyphens and multiple spaces.

You can then split the list of page numbers separated by spaces using the split function to give an array of page numbers

You can then test each page number in turn for it being numeric.

This is the updated code for the form_validates_ok function If it were for my personal use then there would be some further abstraction as the validation is quite repetitive.

Code:
Private Function form_validates_ok() As Boolean

Dim txt_pages                               As String
Dim pages()                                  As String
Dim a_page_number                      As Variant  ' must be a variant for loop control

    If Not IsNumeric(Trim(Me.txtCopies)) Then
        MsgBox "The number of copies should be a number", vbOKOnly
        Me.txtCopies.SetFocus
        Me.txtCopies.SelLength = Len(Me.txtCopies)
        form_validates_ok = False
        Exit Function
    End If
    
    If Not IsNumeric(Trim(Me.txtStartNumber)) Then
        MsgBox "The start number should be a number", vbOKOnly
        Me.txtStartNumber.SetFocus
        Me.txtStartNumber.SelLength = Len(Me.txtStartNumber)
        form_validates_ok = False
        Exit Function
    End If
    
    ' convert the txtPages string into an array of page numbers in array pages
    txt_pages = Trim(Me.txtPages)
    txt_pages = replace(txt_pages, ",", " ")
    txt_pages = replace(txt_pages, "-", " ")
    Do While InStr(txt_pages, "  ") > 0 ' checking for the presence of two spaves adjacent to each other
        txt_pages = replace(txt_pages, "  ", " ")
    Loop
    pages = split(txt_pages, " ") ' Note the absence of () when assigning to an array
    
    For Each a_page_number In pages
        If Not IsNumeric(a_page_number) Then
            MsgBox "The pages required should be a number", vbOKOnly
            Me.txtPages.SetFocus
            Me.txtPages.SelLength = Len(Me.txtPages)
            form_validates_ok = False
            Exit Function
        End If
    Next
    
    form_validates_ok = True
    
End Function
You will also need to amend the printout statement to use the page ranges in .txtxPages

Code:
ActiveDocument.PrintOut copies:=1, pages:=my_form.txtPages
Reply With Quote
  #12  
Old 05-29-2018, 03:39 AM
kiwimtnbkr kiwimtnbkr is offline SENDKEYS with vbYesNoCancel and Select Case Windows 10 SENDKEYS with vbYesNoCancel and Select Case Office 2010 64bit
Advanced Beginner
SENDKEYS with vbYesNoCancel and Select Case
 
Join Date: Oct 2017
Posts: 69
kiwimtnbkr is on a distinguished road
Default

WOW, that was fast! Thank you!

I've got the forms code in no problems but when I amended the printout statement and run it, I get a Run-time error '13': Type mismatch dialog.

I've highlighted the line that 'debug' doesn't seem to like.

This is the module code
Code:
Sub PrintNumberedCopiesSelect()
'
' PrintNumberedCopiesSelectionofPages macro
' Shortcut keys Alt+S
'

Const cdp_name                          As String = "CopyNum"
Const default_copies                    As String = "1"
Const duplex_printer                    As String = "hp deskjet 5550 series (HPA) duplex"  ' change this to the name of your duplex printer

Dim my_form                             As ufrmPrintNumberedCopiesSelect
Dim copy_number                         As Long
Dim first_copy                          As Long
Dim last_copy                           As Long
Dim my_update_fields_at_print           As Boolean
Dim my_update_link_at_print             As Boolean
Dim current_printer                     As String



    ' We are using a custom Document Property to save the serial number
    ' as we can edit this from the backstage properties advanced dialog
    ' if needed
    
    ensure_cdp_exists cdp_name
    
    Set my_form = New ufrmPrintNumberedCopiesSelect
    
    With my_form
        .txtStartNumber = Trim(ActiveDocument.Variables(cdp_name))
        .txtCopies = default_copies
        .Show
            
        If Not .Result Then
            Exit Sub
        End If
    End With
    
    ' We now switch to the document printer that has been customised to aleays
    ' print in duplex
    
    current_printer = ActivePrinter
    ActivePrinter = duplex_printer
    
    ' The update fields and links at print time are application properties so anly need setting once
    ' but we preserve the values so we can restore the current settings after we have finished printing
    
    With Options
    
        my_update_fields_at_print = .UpdateFieldsAtPrint
        .UpdateFieldsAtPrint = True
        
        my_update_link_at_print = .UpdateLinksAtPrint
        .UpdateLinksAtPrint = True
        
    End With

    
    first_copy = CLng(Trim(my_form.txtStartNumber))
    last_copy = first_copy + CLng(Trim(my_form.txtCopies)) - 1
   
   
'    MsgBox "Now we do the printing", vbOKOnly   'comment this out once tested
    
    ' it is assumed that there is a field somewhere that references the customdocumentproperty
    
     For copy_number = first_copy To last_copy  ' uncomment the for loop once tested
         ActiveDocument.Variables(cdp_name) = CStr(copy_number)
         ActiveDocument.PrintOut copies:=1, pages:=my_form.txtPages
     Next
    
    
    ' save the next starting serial number
    ActiveDocument.Variables(cdp_name) = last_copy + 1
    
    
    ' restore saved settings
    With Options
        .UpdateFieldsAtPrint = my_update_fields_at_print
        .UpdateLinksAtPrint = my_update_link_at_print
    End With

    ActivePrinter = current_printer

End Sub

Sub ensure_cdp_exists(cdp_name As String)
'cdp is short for CustomDocumentProperty

    ' Searches for the a custom document property of cdp_name
    ' If not found the custom document property is created and assigned a value of 1

Const default_start_number         As String = "1"

Dim my_cdp                          As DocumentProperty

    For Each my_cdp In ActiveDocument.CustomDocumentProperties
    
        If my_cdp.Name = cdp_name Then
            Exit Sub
        End If
   
    Next
    
    ' We only get to this point if we don't find the target custom document property
    ' using the previous loop
    
    ActiveDocument.CustomDocumentProperties.Add _
        Name:=cdp_name, _
        LinkToContent:=False, _
        Value:=default_start_number, _
        Type:=msoPropertyTypeString
    
    ' Be gentle with the user and let them know what has happened.
    MsgBox _
        Title:="Missing CustomDocumentProperty", _
        prompt:="CustomDocumentProperty '" & cdp_name & "' was added to the document" & vbCrLf & vbCrLf & "A value of '" & default_start_number & "' was assigned'", _
        Buttons:=vbOKOnly
    
End Sub
Reply With Quote
  #13  
Old 05-29-2018, 03:55 AM
slaycock slaycock is offline SENDKEYS with vbYesNoCancel and Select Case Windows 7 64bit SENDKEYS with vbYesNoCancel and Select Case Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

Apologies. I don't check the actual printout statement as I don't want to waste reams of paper.

The help page for printout is here

https://msdn.microsoft.com/en-us/VBA...ut-method-word

I suspect the problem is that the pages parameter should be a variant but we are passing a string.

Try changing to

pages:=Cvar(my_form.txtPages)
Reply With Quote
  #14  
Old 05-29-2018, 06:13 AM
slaycock slaycock is offline SENDKEYS with vbYesNoCancel and Select Case Windows 7 64bit SENDKEYS with vbYesNoCancel and Select Case Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

No. That's not the answer.

Replace my_form.txtPages with my_form.txtPages.value

That works on my PC
Reply With Quote
  #15  
Old 05-29-2018, 07:14 AM
gmaxey gmaxey is offline SENDKEYS with vbYesNoCancel and Select Case Windows 7 32bit SENDKEYS with vbYesNoCancel and Select Case Office 2016
Expert
 
Join Date: May 2010
Location: Brasstown, NC
Posts: 1,429
gmaxey is a jewel in the roughgmaxey is a jewel in the roughgmaxey is a jewel in the roughgmaxey is a jewel in the rough
Default

Gents,

It is a slow day and raining outside. I hope neither of you will mind if I chime in with a few alternatives and questions. Each of us has (or will develop) their own style. In the code below, I've used mine.

The form code:

Code:
Option Explicit
Dim m_bTest As Boolean
Private Sub txtStartNumber_Change()
  Validate_OK
End Sub
Private Sub txtStartNumber_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
  m_bTest = IsInteger(KeyAscii)
  If m_bTest = False Then
    Beep
    KeyAscii = 0
  End If
End Sub
Private Sub txtCopies_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
  m_bTest = IsInteger(KeyAscii)
  If m_bTest = False Then
    Beep
    KeyAscii = 0
  End If
End Sub
Private Sub txtCopies_Change()
  Validate_OK
End Sub
Function IsInteger(ByVal i As String) As Boolean
  Select Case i  'Checking to see if inside valid Ascii range for integers
    Case 48 To 57: IsInteger = True
    Case Else: IsInteger = False
  End Select
End Function
Private Sub UserForm_Activate()
  Validate_OK
End Sub
Private Sub cmdCancel_Click()
  Tag = "CANCX"
  Hide
End Sub
Private Sub cmdOK_Click()
  Hide
End Sub
Private Sub Validate_OK()
  cmdOK.Enabled = True
  If Not IsNumeric(Trim(txtCopies)) Then cmdOK.Enabled = False
  If Not IsNumeric(Trim(txtStartNumber)) Then cmdOK.Enabled = False
End Sub
The standard module code:

Code:
Option Explicit
Sub PrintNumberedCopiesSelect()
Const strCDP_name As String = "CopyNum"
Const strDuplex_printer As String = "hp deskjet 5550 series (HPA) duplex"  ' change this to the name of your duplex printer
Dim oFrm As frmPrintDialog
Dim lngCopy_number As Long, lngFirst_copy As Long, lngLast_copy As Long
Dim bUpdate_fields_at_print As Boolean, bUpdate_link_at_print As Boolean
Dim strCurrent_printer As String
  'We are using a custom Document Property to save the serial number as we can edit this from the backstage _
  properties advanced dialog.
  Validate_CDP strCDP_name
  Set oFrm = New frmPrintDialog
  With oFrm
    .txtStartNumber = Trim(ActiveDocument.CustomDocumentProperties(strCDP_name))
    .txtCopies = "1"
    .Show
    If .Tag = "CANCX" Then GoTo lbl_Exit
  End With
  'We now switch to the document printer that has been customised to aleays print in duplex.
  strCurrent_printer = ActivePrinter
  ActivePrinter = strDuplex_printer
  'The update fields and links at print time are application properties so anly need setting once _
  but we preserve the values so we can restore the current settings after we have finished printing
  With Options
    bUpdate_fields_at_print = .UpdateFieldsAtPrint
    .UpdateFieldsAtPrint = True
    bUpdate_link_at_print = .UpdateLinksAtPrint
    .UpdateLinksAtPrint = True
  End With
  lngFirst_copy = CLng(Trim(oFrm.txtStartNumber))
  lngLast_copy = lngFirst_copy + CLng(Trim(oFrm.txtCopies)) - 1
  'MsgBox "Now we do the printing", vbOKOnly   'comment this out once tested
  'It is assumed that there is a field somewhere that references the customdocumentproperty
  For lngCopy_number = lngFirst_copy To lngLast_copy ' uncomment the for loop once tested
    ActiveDocument.Variables(strCDP_name) = CStr(lngCopy_number)
    ActiveDocument.PrintOut copies:=1, Pages:=oFrm.txtPages.Value
  Next
  'Save the next starting serial number
  ActiveDocument.CustomDocumentProperties(strCDP_name) = lngLast_copy + 1
  'Restore saved settings
  With Options
    .UpdateFieldsAtPrint = bUpdate_fields_at_print
    .UpdateLinksAtPrint = bUpdate_link_at_print
  End With
  ActivePrinter = strCurrent_printer
lbl_Exit:
  Unload oFrm
  Set oFrm = Nothing
End Sub
Sub Validate_CDP(strCDP_name As String)
Dim oCDP As DocumentProperty
  'See if custom document property already exists.
  On Error Resume Next
  Set oCDP = ActiveDocument.CustomDocumentProperties(strCDP_name)
  If Not oCDP Is Nothing Then Exit Sub
  On Error GoTo 0
  'It doesn't exists so create it.
  ActiveDocument.CustomDocumentProperties.Add Name:=strCDP_name, _
                LinkToContent:=False, Value:="1", Type:=msoPropertyTypeString
  MsgBox "A CustomDocumentProperty named """ & strCDP_name & """ with the value ""1"" was added to the document.", _
         vbInformation + vbOKOnly, "Create CustomDocumentProperty"
lbl_Exit:
  Exit Sub
End Sub
In the code above, the loop check for the custom document property is replaced with a process of trying to access the item explicitly. The command button validation is upfront. It can't be clicked if not valid.

Slaycock are there reasons (which I may be unaware of) why you use the public property "Result" rather than the built-in Tag property of the Userform? Is there a reason you set the form to the display top left then move to center vice using the default Center Owner?

Thanks
__________________
Greg Maxey
Please visit my web site at http://www.gregmaxey.com/

Last edited by gmaxey; 05-29-2018 at 06:40 PM.
Reply With Quote
Reply



Similar Threads
Thread Thread Starter Forum Replies Last Post
Help with Case and Select case brent chadwick Word VBA 34 10-18-2015 02:13 PM
Replace & case Jennifer Murphy Word 1 02-11-2013 03:26 AM
SENDKEYS with vbYesNoCancel and Select Case A macro that can insert FILENAME, sendkeys CTRL ALT T, paste clipboard, and nextline kyjac85 Word VBA 13 09-20-2012 05:00 PM
Problem with the sendkeys in Win7 vidyapakki Excel Programming 1 05-07-2012 11:10 PM
SENDKEYS with vbYesNoCancel and Select Case From all UPPER CASE to Proper Case davers Word 1 04-30-2009 12:41 PM

Other Forums: Access Forums

All times are GMT -7. The time now is 02:52 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Search Engine Optimisation provided by DragonByte SEO (Lite) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
MSOfficeForums.com is not affiliated with Microsoft