PDF printing on the back - vba

In the "ACCESS" program, you need to print the active page of the form, and on the back of the sheet a PDF file (by hyperlink in this page). I have a duplex printer.
Private Sub duplexprinter_Click()
Dim myform As Form
Dim pageno As Integer
pageno = Me.CurrentRecord
Set myform = Screen.ActiveForm
DoCmd.SelectObject acForm, myform.Name, True
DoCmd.PrintOut acSelection, pageno, 1, , 1
CreateObject("Shell.Application").Namespace(0).ParseName(Me.path).InvokeVerb ("Print")
DoCmd.SelectObject acForm, myform.Name, False
End Sub
The printer perceives this code as 2 consecutive jobs, so it prints on 2 different sheets.
Please help me write the code to print on both sides of one sheet.

I would do:
Print/output the form to PDF:
DoCmd.OutputTo acOutputForm, myform.Name, acFormatPDF, strFile1
Use a command-line tool like pdftk to combine file1 with the back side pdf.
https://superuser.com/questions/34284/combine-merge-pdf-files-in-windows
Print the result file.

Related

Avoiding printing specific page(s)

I have created a document for work. Due to security on the company computers the macro I have on the document is not automatically enabled.
I added directions on Page 1 for how to enable it. Now when someone prints, it prints this instruction page.
I tried to simulate a macro similar to the original one I used below, for not printing Blank Content Control, to print my instruction page as blank however, this was not effective.
Sub PrintReport()
Dim cc As ContentControl
For Each cc In ThisDocument.ContentControls
If Left(cc.Range.Text, 19) = "Click here to enter" Then
cc.Range.Font.ColorIndex = wdWhite
End If
Next
ActiveDocument.PrintOut
For Each cc In ThisDocument.ContentControls
If Left(cc.Range.Text, 19) = "Click here to enter" Then
cc.Range.Font.ColorIndex = 15
End If
Next
End Sub
I also tried to create a macro, using assistance from this site, to only print specific pages (ie. 2-5). This did not work.
Sub SpecialPgOnePrint()
Application.PrintOut FileName:="Visitation Report (Fillable-Final)", _
Range:=wdPrintRangeOfPages, Pages:="2-5"
End Sub
I would appreciate help identifying a way to either A. not print page1 (preferable) or B. start printing at page2
Try the following
Option Explicit
Sub PagePrint()
With ActiveDocument
.PrintOut Range:=wdPrintFromTo, _
From:=Format(.Sections(1).Headers(1).PageNumbers.StartingNumber + 2), _
To:=Format(.Range.Information(wdActiveEndAdjustedPageNumber))
End With
End Sub

Print Dialog in MS-Access

I want to open a print dialog box. I haven't programmed in VB for a decade and I am more than a little rusty.
I got a copy of an MS Access VB script that selects an MDB file and then prints only one copy. My thought process was:
Open up a dialog box;
Select the printer;
Type in number of copies;
Print.
Currently, the portion of the original script I want to modify is:
[SQL query above this]
....
' Open form
Dim rs As DAO.Recordset
Set rs = db.OpenRecordset("select##identity")
Debug.Print rs(0)
Dim q As String
q = "transfer_id=" & rs(0)
DoCmd.OpenForm "Transfer Report", acNormal, , q, ,acDialog
DoCmd.PrintOut
...
[End If, End Sub, etc.]
This only prints out one instance of the report and the company does not have the ability to print out other copies at the same time. Since it is in the field, they don't have access to a copier but still need multiple copies.
One answer I found, by David-W-Fenton (thank you!), shows how to create a dialog box; Would the following script accomplish what I want to do? And, how do I add a portion to the dialog box to specify how many copies to print?
...
Dim varPrinter As Printer
Dim strRowsource As String
Dim q As String
Dim rs As DAO.Recordset
Set rs = db.OpenRecordset("select ##identity")
Debug.Print rs(0)
If Len(Me.OpenArgs) > 0 Then
q = Me.OpenArgs
Me.Tag = q
For Each varPrinter In Application.Printers
strRowsource = strRowsource & "; " & varPrinter.DeviceName
Next varPrinter
Me!cmbPrinter.RowSource = Mid(strRowsource, 3)
' first check to see that the report is still open
If (1 = SysCmd(acSysCmdGetObjectState, acReport, q)) Then
With Reports(q).Printer
Me!cmbPrinter = .DeviceName
Me!optLayout = .Orientation
End With
Me!txtPageTo = Reports(q).Pages
End If
End If
Public Function PrintReport(q As String) As Boolean
q = "transfer_id=" & rs(0)
' open report in PREVIEW mode but HIDDEN
DoCmd.OpenReport q, acViewPreview, , , acHidden
' open the dialog form to let the user choose printing options
DoCmd.OpenForm "dlgPrinter", , , , , acDialog, q
With Forms!dlgPrinter
If .Tag <> "Cancel" Then
Set Reports(q).Printer = Application.Printers((!cmbPrinter))
Reports(q).Printer.Orientation = !optLayout
Application.Echo False
DoCmd.SelectObject acReport, q
DoCmd.PrintOut acPages, !txtPageFrom, !txtPageTo
PrintReport = True
End If
End With
DoCmd.Close acForm, "dlgPrinter"
DoCmd.Close acReport, q
Application.Echo True
End Function
Here is a late reply, some times it may help others.
In order to open the print dialogue:
Place a command button for PRINT on the report, and write the code as below.
Private Sub CmdbtnPrint_Click()
DoCmd.RunCommand acCmdPrint
End Sub
Change the 'Display When' property of button to 'Screen Only'.
Open the report in 'acViewReport' view mode.
Click the PRINT command button, and the systems print dialogue box will be open. Set the parameters and print the report.
Check the documentation about the PrintOut method:
http://msdn.microsoft.com/en-us/library/office/ff192667.aspx
In your original script to modify, just add the Copies argument to the DoCmd.PrintOut statement, like:
DoCmd.PrintOut Copies:=x
where x is a variable representing the number of copies you want to print.
Reviewing the documentation for the DoCmd.OpenForm method,
http://msdn.microsoft.com/en-us/library/office/ff820845.aspx
I don't think the code you have can allow a user-input for the number of copies. I do not program in Access, but I'm certain there are other ways to allow user input at run-time. In Excel/PowerPoint we would use an InputBox or a UserForm.
I think you can use an InputBox in Access:
http://office.microsoft.com/en-us/access-help/inputbox-function-HA001228856.aspx

How can I use VBA to lock/unlock all fields in a Microsoft Word 2010 document?

The problem I have got is that my corporate template set uses a SaveDate field in the footer of every word document - which is used to detail when the document was saved, which ties in with our custom document management system.
Subsequently, when users want to make a PDF of an old document, using the Save As PDF function of Office 2010, the Save Date is updated - creating a PDF of the old document, but with today's date. This is wrong. We are just trying to create a true PDF version of whatever the original document has in it.
To get around this, I am writing a macro solution which locks the fields, exports the document as a PDF and then unlocks the fields again.
I have come up against an issue where I can identify and lock all fields in the headers/footers (which is actually what I'm trying to do) but to make it more robust, need to find out a way to lock ALL FIELDS in ALL SECTIONS.
Showing you my code below, how can I identify all fields in all sections? Will this have to be done using the Index facility?
Sub CPE_CustomPDFExport()
'20-02-2013
'The function of this script is to export a PDF of the active document WITHOUT updating the fields.
'This is to create a PDF of the document as it appears - to get around Microsoft Word 2010's native behaviour.
'Route errors to the correct label
'On Error GoTo errHandler
'This sub does the following:
' -1- Locks all fields in the specified ranges of the document.
' -2- Exports the document as a PDF with various arguments.
' -3- Unlocks all fields in the specified ranges again.
' -4- Opens up the PDF file to show the user that the PDF has been generated.
'Lock document fields
Call CPE_LockFields
'Export as PDF and open afterwards
Call CPE_ExportAsPDF
'Unlock document fields
Call CPE_UnlockFields
'errHandler:
' MsgBox "Error" & Str(Err) & ": " &
End Sub
Sub CPE_LockFields()
'Update MS Word status bar
Application.StatusBar = "Saving document as PDF. Please wait..."
'Update MS Word status bar
Application.StatusBar = "Locking fields in all section of the active document..."
'Declare a variable we can use to iterate through sections of the active document
Dim docSec As section
'Loop through all document sections and lock fields in the specified ranges
For Each docSec In ActiveDocument.Sections
docSec.Footers(wdHeaderFooterFirstPage).Range.fields.Locked = True
docSec.Footers(wdHeaderFooterPrimary).Range.fields.Locked = True
docSec.Footers(wdHeaderFooterEvenPages).Range.fields.Locked = True
Next
End Sub
Sub CPE_UnlockFields()
'Update MS Word status bar
Application.StatusBar = "PDF saved to DocMan Temp. Now unlocking fields in active document. Please wait..."
'Declare a variable we can use to iterate through sections of the active document
Dim docSec As section
'Loop through all document sections and unlock fields in the specified ranges
For Each docSec In ActiveDocument.Sections
docSec.Footers(wdHeaderFooterFirstPage).Range.fields.Locked = False
docSec.Footers(wdHeaderFooterPrimary).Range.fields.Locked = False
docSec.Footers(wdHeaderFooterEvenPages).Range.fields.Locked = False
Next
End Sub
Sub CPE_ExportAsPDF()
'Update MS Word status bar
Application.StatusBar = "Saving document as PDF. Please wait..."
'Chop up the filename so that we can remove the file extension (identified by everything right of the first dot)
Dim adFilename As String
adFilename = Left(ActiveDocument.FullName, (InStrRev(ActiveDocument.FullName, ".", -1, vbTextCompare) - 1)) & ".pdf"
'Export to PDF with various arguments (here we specify file name, opening after export and exporting with bookmarks)
With ActiveDocument
.ExportAsFixedFormat outPutFileName:=adFilename, _
ExportFormat:=wdExportFormatPDF, OpenAfterExport:=True, _
OptimizeFor:=wdExportOptimizeForPrint, Range:=wdExportAllDocument, _
Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateWordBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
End With
'Update MS Word status bar
Application.StatusBar = "PDF saved to DocMan Temp."
End Sub
Try something like the following to get to all fields in the document, header, footer, background and main text:
Sub LockAllFieldsInDocument(poDoc As Document, Optional pbLock As Boolean = True)
Dim oRange As Range
If Not poDoc Is Nothing Then
For Each oRange In poDoc.StoryRanges
oRange.Fields.Locked = pbLock
Next
End If
Set oRange = Nothing
End Sub
Here is another way to do it. It'll select the entire document and then lock all fields, before deselecting everything.
Sub SelectUnlink()
ActiveDocument.Range(0, 0).Select
Selection.WholeStory
Selection.Range.Fields.Unlink
Selection.End = Selection.Start
End Sub

Get value of TextBox in Word by but in Word template

Background: I want to use a specific entered text from a TextBox for the default filename in the SaveAs dialog.
I have implemented the following VBA script in my document, a Word 2010 template .dotm
Sub FileSaveAs()
'for testing
Dim fileName As String
fileName = Me.tb_myTextBox.Value & "_MyFileNameToSave"
MsgBox fileName
'use specific file name in save dialog
With Dialogs(wdDialogFileSaveAs)
.Name = fileName
.Show
End With
End Sub
It works fine, when I run it. I saved the .dotm, closed it and reopened it out from the Windows Explorer (means as "end user").
BUT in this case, means after open the template document as "end user" (so that I can save a new doc out of it and not overwrite the template), the content/value of the TextBox is empty, even if I entered something into it.
So, how can I read out the data of the TextBox in "document mode" of a template?
Presumably, the OP's intention was something along the lines of:
Sub FileSaveAs()
Dim StrNm As String
With ActiveDocument
StrNm = Split(.Shapes(1).TextFrame.TextRange.Text, vbCr)(0) & "_MyFileNameToSave"
'use specific file name in save dialog
With Dialogs(wdDialogFileSaveAs)
.Name = StrNm
.Show
End With
End With
End Sub
where .Shapes(1) identifies the particular textbox Shape object.
how can I read out the data of the TextBox in "document mode" of a template?
Not sure what you mean. This works for me:
create a form:
Private Sub btn_OK_Click()
Dim fileName As String
fileName = tb_myTextBox.Value & "_MyFileNameToSave"
With Dialogs(wdDialogFileSaveAs)
.name = fileName
.Show
End With
End Sub
create a sub to call this form:
Sub FileSaveAs()
UserForm1.Show
End Sub
This is all saved in a template / .dotm.
Now, create a document off of the template (double click the template to launch document off of it). Alt + F8 and run the macro from the template (you may have to select the template from the "Macros in" drop down). Result: my form comes up, I enter a name for the document, press ok, and the Word Save As dialog appears with the name I gave to the document.

Printing from Excel VBA

Trying to print the same excel sheet a number of times (e.g 100) with a cell incremented each time (e.g cell 4F).
I tried using
Workbook_BeforePrint
to increment the cell, but it requires interaction with the "select printer" dialog for each printed sheet.
Would it be possible to make something like:
a = getIntegerUserInput()
for i in 1..a
increment 4F with one
print the sheet suppressing the "select printer" dialog
end for
Cheers
Have you selected a default printer?
I used this:
Sub printinc()
For i = 0 To 3
Range("A1").Value = Range("A1").Value + 1
Sheets("Sheet1").PrintOut
Next
End Sub
It printed 4 copies incrementing the value in cell A1 each time without prompting me for settings or printer selection.
To print a sheet, you can use this kind of code (assuming you know on which printer you want to print) using PrintOut:
Sub PrintFile()
Dim curPrinter As String
curPrinter = Application.ActivePrinter
Application.ActivePrinter = "Myprinter"
ActiveWindow.SelectedSheets.PrintOut
Application.ActivePrinter = curPrinter
End Sub
Hence, you can create a loop to increase a cell and print your worksheet with the increment.
By the way, you could do it using Before_print and if you don't want to display the print dialog, you can set Cancel to False while calling the procedure Private Sub Workbook_BeforePrint( Cancel As Boolean) (ref on MSDN)
You can also read this SO thread to prevent displaying the printing dialog: How do you prevent printing dialog when using Excel PrintOut method.
[EDIT] see Seyren's answer for a working solution on what you want. Yet, take care about the performance if you really wanted to loop 100 times.
Private Sub Workbook_BeforePrint(Cancel As Boolean)
'//supress recursion into this event when we print
Application.EnableEvents = False
'//increment
If Not IsNumeric(ActiveSheet.Range("A1").Value) Then ActiveSheet.Range("A1").Value = 0
ActiveSheet.Range("A1").Value = ActiveSheet.Range("A1").Value + 1
'//do a default print
ActiveSheet.PrintOut
Application.EnableEvents = True
'//prevent the default print
Cancel = True
End Sub