Programming Printer Settings in Microsoft Access 2002This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.
Summary: This article discusses how to change printer settings programmatically in Microsoft Access 2002 applications by using the new Printers collection and Printer objects. (17 printed pages)
In previous versions of Microsoft® Access, the only way to programmatically retrieve and work with the printer settings of forms and reports is to use the PrtDevMode, PrtDevNames, and PrtMip properties, which are available only when a form or report is open in Design View. The PrtDevMode and PrtDevNames properties work with copies of the DEVMODE and DEVNAMES data structures that are used internally by Microsoft Windows® to provide information about printer settings. The PrtMip property works with the data structure that Access stores with a form or report when printer settings are saved with those database objects. While these properties provide a high degree of detail and control, they can be difficult to use because instead of providing a standard Visual Basic® object model to work with, each property returns all of its members as a single array of bytes that your code must carefully parse. While these properties are still supported, in response to developer requests for a better object model for working with printer settings, Access 2002 provides a new Printers collection and Printer object with a rich set of properties for retrieving and setting printer information. These properties are much simpler to use than working with the PrtDevMode, PrtDevNames, and PrtMip properties.
Additionally, because the PrtDevMode, PrtDevNames, and PrtMip properties are available only when a form or report is open in Design View, it is not possible to use them from Access applications saved as .mde or .ade files or from Access runtime applications because those file types don't support opening forms and reports in Design View. However, the new Printers collection and Application.Printer object are available whenever Access or a database application is open for working with the default printer settings of all database objects, and the Printer objects of forms and reports are available in all views.
The Printers collection of the Application object contains a collection of Printer objects that represent all of the printers installed on the current system.
The following table provides a summary of the properties available for the Printers collection.
|Application||The accessor property to the Application object for the running instance of Access.|
|Count||Returns a count of the printers installed on the current system.|
|Item||Returns a specific Printer object in the collection by position, starting from 0 to the value of the Count property minus 1, or by a string that specifies the device name of the printer as returned by the DeviceName property of the Printer object.|
|Parent||Returns the parent of the Printers collection, which is the Application object.|
You use the Printers property of the Application object to return the Printers collection. You can then enumerate through each Printer object in the Printers collection by using a For Each…Next statement. The following code fragment from the Open event of frmPrinter in the PrinterDemo.mdb file included in the sample download uses a For Each…Next statement and the new AddItem method to populate the cboPrinter combo box with the list of installed printers:
Dim prt As Printer ... For Each prt In Application.Printers Me!cboPrinter.AddItem Item:=prt.DeviceName Next prt
You can return a reference to a particular Printer object in the Printers collection by using any of the following syntax forms.
|Printers!devicename or Printers("devicename")||The devicename argument is a String value that specifies the name of the printer as returned by the DeviceName property, which is also the same name displayed in the Access Print dialog box.
|Printers(index)||The index argument is the numeric position of the object within the collection. The valid range is from 0 to |
You can't add or delete a Printer object from the Printers collection in code. A Printer object is added to the Printers collection for each printer installed by the user or the user's system. Similarly, a Printer object is removed from the Printers collection when a user deletes a printer from the system.
The following table summarizes the properties of the Printer object that you can use to return system information about the printers available on the current system. All of these properties are read-only.
|DeviceName||Returns a String value indicating the name of the specified printer device as displayed in the Access Print dialog box.|
|DriverName||Returns a String value indicating the name of the driver used by the specified printer. This string is the same as the Type field listed in the Access Print dialog box.
|Port||Returns a String indicating the port name of the specified printer.|
For a listing of the remaining properties of the Printer object, see the Printer Properties Appendix at the end of this article.
In addition to working with Printer objects in the Printers collection, the Printer object is also available directly from the Application object, and from Form and Report objects. Working with the Printer object from the Application object lets you retrieve the settings of the default printer for the entire application, or lets you temporarily override the default printer settings for the current session. Working with the Printer objects from Form and Report objects lets you temporarily or permanently override the default printer's settings for forms and reports.
The Application Printer Object
The Printer object of the Application object lets you retrieve or set the settings of the default printer for the Access application. These printer settings affect all printable objects in the application, such as the datasheets for tables and queries, macros and modules in Design View, as well as database diagrams in Access project .adp files. Additionally, by default, all forms and reports use the settings of the default printer. For information on how to determine if a form or report is using the settings of the default printer, and how to override those settings, see Form and Report Printer Objects later in this article.
The syntax for reading system information and settings for the default printer is as follows:
In this syntax, PrinterProperty is any valid property of a Printer object.
For example, the following code fragment returns the name of the current default printer by using the DeviceName property:
NoteIf no printer is installed on the system and your code refers to the Application.Printer object, Access returns the following error message:
Run-time error '2205':
The default printer driver isn't setup correctly.
By default, reading the LeftMargin, RightMargin, TopMargin, BottomMargin, DataOnly, ItemsAcross, RowSpacing, ColumnSpacing, DefaultSize, ItemSizeWidth, ItemSizeHeight, and ItemLayout properties of the Application.Printer object will always return zero. This is because these values are not available from the printer driver as part of the Windows DEVMODE and DEVNAMES data structures, but are part of the Access-specific MIPS data structure that can only be saved with forms and reports. However, you can set these values for the Application.Printer object and they will affect printing any database object to which they apply. Additionally, if printer settings have been saved with a form or report, you can read the values of these property settings from the Printer object of the Form or Report object of the corresponding form or report.
Overriding Settings of the Application Printer Object
When you first start a session of Access, it uses the Windows default printer. As long as you make no changes to the Application. Printer object, Access will continue to use the Windows default printer and its settings for all printable database objects, except for forms and reports that have saved printer settings. You can temporarily override the read/write property settings of the Application.Printer object during the current session by using the following syntax:
Application.Printer.PrinterProperty = PropertyValue
In this syntax, PrinterProperty is any read/write property of a Printer object that is applicable to the current printer, and PropertyValue is any valid setting for the current printer. The properties you can set include all properties other than the DeviceName, DriverName, or Port properties. See the Printer Properties Appendix later in this article for a summary of these Printer properties.
If you want to switch the Application.Printer object to a printer other the Windows default printer, or change several property settings at once, you can do so by setting the Application.Printer object using the following syntax:
Set Application.Printer = PrinterObject
Where PrinterObject is a Printer object variable that has been set to the properties you want to override, or an expression that returns the Printer object for the printer you want to switch to. For example, the following code fragment from the Click event of the cmdChangeDefaultPrt button on frmPrinter in the PrinterDemo.mdb sample download switches the default printer to the printer selected by the user from the cboPrinter combo box.
Dim prt As Printer ' Get the Printer object for the selected printer. Set prt = Application.Printers(Me!cboPrinter.Value) ' Set the selected printer as the default printer for this session. Set Application.Printer = prt
After running this code, a request to print any database object that uses the default printer will print to the selected printer.
Preserving and Restoring Application Printer Settings
If you override the settings of the Application.Printer object and don't change them again, those settings will remain in effect for the lifetime of the Application object, that is, until your code invokes the Quit method of the Application object, or the user closes the current session of Access. If you want to restore all settings of the Application.Printer object to match those of the Windows default printer within the current session, you can do so by setting Application.Printer equal to Nothing:
Application.Printer = Nothing
You can also restore the settings of the Application.Printer object by saving the current settings in a public Printer object variable prior to changing settings as shown in the following code fragment:
Public prtOriginalPrinter as Printer Sub cmdUsePrinter_Click() ' Save original printer to global variable. prtOriginalPrinter = Application.Printer ' Switch printer. Set Application.Printer = _ Application.Printers(cboPrinters.Value) End Sub
At the appropriate point in your code, you can reset the application printer settings back to their original values with the following line of code:
Application.Printer = prtOriginalPrinter
ImportantYou cannot permanently change the default printer for Access through the Application.Printer object or any other Access code. When a user starts a session of Access, or your code creates an Access Application object, that session will always default to the Window default printer. However, you can override the default printer and printer settings and save those settings for particular forms or reports as described in the Form and Report Printer Objects section below.
Form and Report Printer Objects
The Printer objects associated with Form and Report objects support the same properties and programming techniques as the Application.Printer object. Use the Printer object of a Form or Report object when you want set or retrieve printer settings for a specific form or report. You can change form and report printer settings temporarily, or you can save those settings with the form or report.
The following code fragment opens the Customer Labels report in Print Preview, and then sets the printer for the report to a printer named Label Printer.
Dim rpt As Report DoCmd.OpenReport ReportName:="Customer Labels", View:=acViewPreview Set rpt = Reports("Customer Labels") rpt.Printer = Application.Printers("Label Printer")
ImportantWhile Access 2002 will allow you to change a report's printer settings when a report is opened from event procedure code running in the report's Activate event, you should not do so. Access doesn't currently have the ability to redo the layout for a report if those settings are changed from the events that are fired when you open a report. For this reason, attempting to change a report's printer settings from all other report events, such as the Open event, will return a run-time error. To change a report's printer settings, you should use code running in a separate form or module that opens the report in Print Preview or Design View before changing printer settings and printing the report.
You also cannot set form or report printer properties after printing has started. If you try to do so, the following run-time error is displayed:
Run-time error '2191':
You can't set the Printer property after printing has started.
Saving Printer Settings with a Form or Report
Whether a form or report uses the settings of the default application printer (the settings managed with the Application.Printer object) is determined by whether the form or report has previously saved printer settings. Printer settings for a form or report can be saved two ways:
- A user can save printer settings by opening the form or report in any view, and then clicking the Page Setup command on the File menu.
- You can make changes to the Printer object of a form or report in code, and those changes will be saved with the form or report if you use the DocCmd.Save method before closing the form or report, or specify acSaveYes for the Save argument when using the DoCmd.Close method to close the form or report.
The following code fragment from Click event for the cmdSaveSettings button on the frmPrinters form saves the settings for the report currently being previewed:
If CurrentProject.AllReports(Me!lstSelectReport).IsLoaded Then ' Load settings for the report being previewed. With Reports(Me!lstSelectReport).Printer .PaperSize = modPrinters.GetPaperSize(Me) .PaperBin = modPrinters.GetPaperBin(Me) .Orientation = Me!fraOrientation End With ' Save settings with report. DoCmd.Save ObjectType:=acReport, ObjectName:=Me!lstSelectReport Else MsgBox "Please preview the report first." End If
NoteWhen printer settings are saved with a form or report, Access creates a new data structure for the form or report to contain the saved settings. Initially, this new data structure contains a copy of all of the settings of the default printer. Any settings the user or your code overrides are saved with the data structure. Access does not maintain any sort of inheritance between settings of the default printer and the settings saved with a form or report. If you change settings of the default printer after saving settings for a form or report, the settings that were originally saved will remain in effect.
Determining Whether a Form or Report Has Saved Printer Settings
To determine whether a form or report has saved printer settings, you can read the UseDefaultPrinter property of a Form or Report object using the following syntax:
Where expression is any expression that returns a Form or Report object. The UseDefaultPrinter property is read/write in Design View and read-only in all other views.
The UseDefaultPrinter property returns a Boolean value when you read it that is True if the no changes to printer settings have been saved with the form or report, and is False if any printer setting has been saved with the form or report.
Clearing Saved Printer Settings
You can also use the UseDefaultPrinter property like a method to clear saved settings from a form or report by setting its value to True. This is equivalent to opening the Page Setup dialog box for the form or report and selecting Default Printer on the Page tab.
You can only set the UseDefaultPrinter property when a form or report is open in Design View. The following code fragment from the ClearFormReportSettings procedure in the PrinterDemo.mdb sample download opens each of the reports in the current project and clears any report that has saved settings.
For Each obj In CurrentProject.AllReports DoCmd.OpenReport ReportName:=obj.Name, View:=acViewDesign If Not Reports(obj.Name).UseDefaultPrinter Then Reports(obj.Name).UseDefaultPrinter = True DoCmd.Save ObjectType:=acReport, ObjectName:=obj.Name End If DoCmd.Close Next obj
NoteIf you try to set the UseDefaultPrinter property for a form or report that is in a view other than Design View, Access will return the following Automation error instead of a "friendly" Access error:
Run-time error '-2147467259 (80004005)':
Method 'UseDefaultPrinter' of object '<form or report name>' failed
Preserving Form and Report Printer Settings
When you programmatically change printer property settings for forms or reports while the object is in any view other than Design View, those changes are automatically saved if the user interactively closes the form or report. The following code sample from the modPrinters module in the PrinterDemo.mdb sample download demonstrates how to save and restore a report's printer settings.
Sub RestoreReportPrinter() Dim rpt As Report Dim prtOld As Printer Dim prtNew As Printer ' Open the Invoice report in Print Preview. DoCmd.OpenReport ReportName:="Invoice", View:=acViewPreview ' Initialize rpt variable. Set rpt = Reports!Invoice ' Save the report's current printer settings ' in the prtOld variable. Set prtOld = rpt.Printer ' Load the report's current printer settings ' into the prtNew variable. Set prtNew = rpt.Printer ' Change the report's Orientation property. prtNew.Orientation = acPRORLandscape ' Change other Printer properties, and then print ' or perform other operations here. ' If you comment out the following line of code, ' and a user interactively closes the report preview ' any changes made to properties of the report's Printer ' object are saved when the report is closed. Set rpt.Printer = prtOld ' Close report without saving. DoCmd.Close ObjectType:=acReport, ObjectName:="Invoice", Save:=acSaveNo End Sub
The Printers collection and Printer object only allow you to set or retrieve settings for a printer. To determine a printer's capabilities, such as the kinds of paper or paper bins it supports, you must use calls to the Windows Application Programming Interface (API) DeviceCapabilities function. It is beyond the scope of this article to cover this in detail, but the following code sample from the modPrinters module of the PrinterDemo.mdb sample download demonstrates how to retrieve the names and IDs of the supported paper bins for a printer.
' Declaration for DeviceCapabilities function API call. Private Declare Function DeviceCapabilities Lib "winspool.drv" _ Alias "DeviceCapabilitiesA" (ByVal lpsDeviceName As String, _ ByVal lpPort As String, ByVal iIndex As Long, lpOutput As Any, _ ByVal lpDevMode As Long) As Long ' DeviceCapabilities function constants. Private Const DC_BINNAMES = 12 Private Const DC_BINS = 6 Private Const DEFAULT_VALUES = 0 Sub GetBinList(strName As String) Dim lngBinCount As Long Dim lngCounter As Long Dim hPrinter As Long Dim strDeviceName As String Dim strDevicePort As String Dim strBinNamesList As String Dim strBinName As String Dim intLength As Integer Dim strMsg As String Dim aintNumBin() As Integer ' Get name and port of the default printer. strDeviceName = Application.Printers(strName).DeviceName strDevicePort = Application.Printers(strName).Port ' Get count of paper bin names supported by the printer. lngBinCount = DeviceCapabilities(lpsDeviceName:=strDeviceName, _ lpPort:=strDevicePort, _ iIndex:=DC_BINNAMES, _ lpOutput:=ByVal vbNullString, _ lpDevMode:=DEFAULT_VALUES) ' Re-dimension array to count of paper bins. ReDim aintNumBin(1 To lngBinCount) ' Pad variable to accept 24 bytes for each bin name. strBinNamesList = String(Number:=24 * lngBinCount, Character:=0) ' Get string buffer of paper bin names supported by printer. lngBinCount = DeviceCapabilities(lpsDeviceName:=strDeviceName, _ lpPort:=strDevicePort, _ iIndex:=DC_BINNAMES, _ lpOutput:=strBinNamesList, _ lpDevMode:=DEFAULT_VALUES) ' Get array of paper bin numbers supported by the printer. lngBinCount = DeviceCapabilities(lpsDeviceName:=strDeviceName, _ lpPort:=strDevicePort, _ iIndex:=DC_BINS, _ lpOutput:=aintNumBin(1), _ lpDevMode:=DEFAULT_VALUES) ' List available paper bin names. strMsg = "Paper bins available for " & strDeviceName & vbCrLf For lngCounter = 1 To lngBinCount ' Parse a paper bin name from string buffer. strBinName = Mid(String:=strBinNamesList, _ Start:=24 * (lngCounter - 1) + 1, _ Length:=24) intLength = VBA.InStr(Start:=1, _ String1:=strBinName, String2:=Chr(0)) - 1 strBinName = Left(String:=strBinName, _ Length:=intLength) ' Add bin name and number to the text string for the message box. strMsg = strMsg & vbCrLf & aintNumBin(lngCounter) _ & vbTab & strBinName Next lngCounter ' Show paper bin numbers and names in a message box. MsgBox Prompt:=strMsg End Sub
To see a code sample that uses the DeviceCapabilities API function to retrieve a list of papers supported by the default printer, see the GetPaperList procedure in the modPrinters module of the PrinterDemo.mdb sample download.
The tables in this appendix describe all of the properties of the Printer object except for the DeviceName, DriverName, and Port properties which are described in the "Printers Collection" section earlier in this article.
NoteThe effect of the properties of the Printer object depends on the driver supplied by the printer manufacturer and the features supported by the printer. Some property settings may have no effect, or several different property settings may all have the same effect.
The following table summarizes the properties of the Printer object that you can use to return or set output settings on the specified printer.
|ColorMode||Returns or sets an AcPrintColor constant to determine whether the specified printer should print output in color or monochrome.
An AcPrintColor constant can be one of the following:
|Copies||Returns or sets a Long value indicating the number of copies to be printed.|
|Duplex||Returns or sets an AcPrintDuplex constant indicating how the specified printer handles the orientation of duplex (two-sided) printing.
An AcPrintDuplex constant can be one of the following:
|Orientation||Returns or sets an AcPrintOrientation constant to determine how the specified printer orients printed pages.
An AcPrintOrientation constant can be one of the following:
|PaperBin||Returns or sets an AcPrintPaperBin constant indicating which paper bin the specified printer should use.
An AcPrintPaperBin constant can be one of the following:
|PaperSize||Returns or sets an AcPrintPaperSize constant indicating the paper size to use when printing.
An AcPrintPaperSize constant can be one of the following:
|PrintQuality||Returns or sets an AcPrintObjQuality constant indicating the print resolution for the specified printer.
An AcPrintQuality constant can be one of the following:
The following table summarizes the properties of the Printer object that you can use to return or set output settings on the specified printer.
|BottomMargin||Returns or sets a Long value that specifies the bottom margin for a printed page in twips.|
|ColumnSpacing||Returns or sets a Long value that specifies the vertical space between detail sections in twips.|
|DataOnly||Returns or sets a Boolean value that is True if Access prints only the data from a table or query in Datasheet view and not the labels, control borders, gridlines, and display graphics.|
|DefaultSize||Returns or sets a Boolean value that is True if the detail section in Design View is used for printing, and is False if the values of the ItemSizeHeight and ItemSizeWidth properties are used.
When this property is True, the values of the ItemSizeHeight and ItemSizeWidth properties are ignored.
|ItemsAcross||Returns or sets a Long value indicating the number of columns to print across a page for multiple-column reports or labels.|
|ItemLayout||Returns or sets an AcPrintItemLayout constant indicating whether the print lays out columns across, then down, or down, then across.
An AcPrintItemLayout constant can be one of the following:
|ItemSizeHeight||Returns or sets a Long value indicating the height of the detail section of a form or report in twips.
If the DefaultSize property is True, this property is ignored.
|ItemSizeWidth||Returns or sets a Long value indicating the width of the detail section of a form or report in twips.
If the DefaultSize property is True, this property is ignored.
|LeftMargin||Returns or sets a Long value that specifies the left margin for a printed page in twips.|
|RightMargin||Returns or sets a Long value that specifies the right margin for a printed page in twips.|
|RowSpacing||Returns or sets a Long value that specifies the horizontal space between detail sections in twips.|
|TopMargin||Returns or sets a Long value that specifies the top margin for a printed page in twips.|