rpm97
asked on
selecting page size in code
How is prtdevmode used to specify the layout of a report. I guess I need to know where to enter the code and where to call it.
Thanks
Thanks
Here is the example they use:
The following example uses the PrtDevMode property to check the user-defined page size for a report:
Type str_DEVMODE
RGB As String * 94
End Type
Type type_DEVMODE
strDeviceName As String * 16
intSpecVersion As Integer
intDriverVersion As Integer
intSize As Integer
intDriverExtra As Integer
lngFields As Long
intOrientation As Integer
intPaperSize As Integer
intPaperLength As Integer
intPaperWidth As Integer
intScale As Integer
intCopies As Integer
intDefaultSource As Integer
intPrintQuality As Integer
intColor As Integer
intDuplex As Integer
intResolution As Integer
intTTOption As Integer
intCollate As Integer
strFormName As String * 16
lngPad As Long
lngBits As Long
lngPW As Long
lngPH As Long
lngDFI As Long
lngDFr As Long
End Type
Sub CheckCustomPage(rptName As String)
Dim DevString As str_DEVMODE
Dim DM As type_DEVMODE
Dim strDevModeExtra As String
Dim rpt As Report
Dim intResponse As Integer
' Opens report in Design view.
DoCmd.OpenReport rptName, acDesign
Set rpt = Reports(rptName)
If Not IsNull(rpt.PrtDevMode) Then
strDevModeExtra = rpt.PrtDevMode ' Gets current DEVMODE structure.
DevString.RGB = strDevModeExtra
LSet DM = DevString
If DM.intPaperSize = 256 Then
' Display user-defined size.
intResponse = MsgBox("The current custom page size is " _
& DM.intPaperWidth / 254 & " inches wide by " _
& DM.intPaperLength / 254 & " inches long. Do you want " _
& "to change the settings?", 4)
Else
' Currently not user-defined.
intResponse = MsgBox("The report does not have a custom page size. " _
& "Do you want to define one?", 4)
End If
If intResponse = 6 Then
' User wants to change settings.
' Initialize fields.
DM.lngFields = DM.lngFields Or DM.intPaperSize Or DM.intPaperLength _
Or DM.intPaperWidth
DM.intPaperSize = 256 ' Set custom page.
' Prompt for length and width.
DM.intPaperLength = InputBox("Please enter page length " _
& "in inches.") * 254
DM.intPaperWidth = InputBox("Please enter page width " _
& "in inches.") * 254
LSet DevString = DM ' Update property.
Mid(strDevModeExtra, 1, 94) = DevString.RGB
rpt.PrtDevMode = strDevModeExtra
End If
End If
End Sub
berg
The following example uses the PrtDevMode property to check the user-defined page size for a report:
Type str_DEVMODE
RGB As String * 94
End Type
Type type_DEVMODE
strDeviceName As String * 16
intSpecVersion As Integer
intDriverVersion As Integer
intSize As Integer
intDriverExtra As Integer
lngFields As Long
intOrientation As Integer
intPaperSize As Integer
intPaperLength As Integer
intPaperWidth As Integer
intScale As Integer
intCopies As Integer
intDefaultSource As Integer
intPrintQuality As Integer
intColor As Integer
intDuplex As Integer
intResolution As Integer
intTTOption As Integer
intCollate As Integer
strFormName As String * 16
lngPad As Long
lngBits As Long
lngPW As Long
lngPH As Long
lngDFI As Long
lngDFr As Long
End Type
Sub CheckCustomPage(rptName As String)
Dim DevString As str_DEVMODE
Dim DM As type_DEVMODE
Dim strDevModeExtra As String
Dim rpt As Report
Dim intResponse As Integer
' Opens report in Design view.
DoCmd.OpenReport rptName, acDesign
Set rpt = Reports(rptName)
If Not IsNull(rpt.PrtDevMode) Then
strDevModeExtra = rpt.PrtDevMode ' Gets current DEVMODE structure.
DevString.RGB = strDevModeExtra
LSet DM = DevString
If DM.intPaperSize = 256 Then
' Display user-defined size.
intResponse = MsgBox("The current custom page size is " _
& DM.intPaperWidth / 254 & " inches wide by " _
& DM.intPaperLength / 254 & " inches long. Do you want " _
& "to change the settings?", 4)
Else
' Currently not user-defined.
intResponse = MsgBox("The report does not have a custom page size. " _
& "Do you want to define one?", 4)
End If
If intResponse = 6 Then
' User wants to change settings.
' Initialize fields.
DM.lngFields = DM.lngFields Or DM.intPaperSize Or DM.intPaperLength _
Or DM.intPaperWidth
DM.intPaperSize = 256 ' Set custom page.
' Prompt for length and width.
DM.intPaperLength = InputBox("Please enter page length " _
& "in inches.") * 254
DM.intPaperWidth = InputBox("Please enter page width " _
& "in inches.") * 254
LSet DevString = DM ' Update property.
Mid(strDevModeExtra, 1, 94) = DevString.RGB
rpt.PrtDevMode = strDevModeExtra
End If
End If
End Sub
berg
ASKER
I have looked at that code, I'm just not sure where to implement it into my database. I have a number of reports that needt to be printed at the same time, but I'd like to be able to be sure that the page size is set in the report so that it does not need specification otherwise.
The OnFormat, or the OnPrint event would probably be the place for this code, then you wouldn't have to specify, you could use ME. Or you could put the code in a public module then call it from the OnFormat, or OnPrint event, although that would only work if you want the same format for all reports.
berg
berg
ASKER
I have tried using it in on format but I have not had success. Does the entire section of code go there, I guess the main question I have is how does the 'type' section of this code work?
ASKER
I have tried using it in on format but I have not had success. Does the entire section of code go there, I guess the main question I have is how does the 'type' section of this code work?
I looks to me that they are defining field types for the file DM. They then use user input to create some of the settings and store them into the fields in file DM.
berg
berg
ASKER
What's the DM - I haven't gotten into anything like this before?
DM is just the initials for DEVMODE, they are just using that as the file name.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Of course that can be done, but there seems to be a problem with it running on other machines. When people switch sizes that way, it seems to default to that size. The whole thing with mde's pretty much rules out using prtdevmode, all my databases are mde's.
Thanks for the info.
Rich
Thanks for the info.
Rich
Were you talking to me?
There can be only three problems with saving the page settings with the report and it not running properly on other machines:
1) The report was set to a setting on your printer which is not available on the target printer. If Access can't find the save setting, it will default to the normal setting of the printer.
2) If the user has the rights to modify a report, which can't be done in an MDE, and sets a setting and saves the report, it will default from that point on for that user. For a MDE, you set the report page settings and the user lives with them. If you would like to have them run the report in either portrait or landscape, create two reports and give them a choice going into the report.
3) If there is a special setting using a custom setting for a particular, then unless the user has exactly the same printer, the setting will change back to the printer default. I recently worked with someone else who had that problem. They were using one printer and the users could be using any dot matrix printer. To fix that, the developer's dot matrix had to be set as the default. For that particular report, he had to issue a warning that the user must have their dot matrix printer set as the default with the special, odd sized paper loaded.
I have done this report setting (forms used for printing work the same way) several times and unless one of the three items mentioned above come up, they will always work.
Since you are shipping mdes, there is no way for the user to change the setting and save the report, so they can change the setting, if you give them that menu item, and print but the next time, it will go back to the page setting that you saved the report before converting to a mde.
If it doesn't work that way for you, I need to know because something is basically going on that weird.
Jim
There can be only three problems with saving the page settings with the report and it not running properly on other machines:
1) The report was set to a setting on your printer which is not available on the target printer. If Access can't find the save setting, it will default to the normal setting of the printer.
2) If the user has the rights to modify a report, which can't be done in an MDE, and sets a setting and saves the report, it will default from that point on for that user. For a MDE, you set the report page settings and the user lives with them. If you would like to have them run the report in either portrait or landscape, create two reports and give them a choice going into the report.
3) If there is a special setting using a custom setting for a particular, then unless the user has exactly the same printer, the setting will change back to the printer default. I recently worked with someone else who had that problem. They were using one printer and the users could be using any dot matrix printer. To fix that, the developer's dot matrix had to be set as the default. For that particular report, he had to issue a warning that the user must have their dot matrix printer set as the default with the special, odd sized paper loaded.
I have done this report setting (forms used for printing work the same way) several times and unless one of the three items mentioned above come up, they will always work.
Since you are shipping mdes, there is no way for the user to change the setting and save the report, so they can change the setting, if you give them that menu item, and print but the next time, it will go back to the page setting that you saved the report before converting to a mde.
If it doesn't work that way for you, I need to know because something is basically going on that weird.
Jim
Here is code I call from the Switchboard menu utility to run reports. The code was written because in Access 2000 I have a problem that the report orientation keeps getting switched back to portrait letter, no matter how the report was saved.
Code in Switchboard or any other menu pushbutton:
PrintWeeklyWide
Public Function PrintWeeklyWide()
OpenReport "Schedule Weekly Wide", "Landscape", "Legal"
'note: you can also pass along a where clause
' OpenReport "Schedule Weekly Wide", "Landscape", "Legal", "where cause string"
End Function
Public Function OpenReport(ReportName As String, Orientation, PaperSize, Optional WhereClause)
'kluge - everytime we switch from on printer to an other (or to another pc using a different printer)
'access sets the pages to letter, portrait, letter
PageSetup _
ReportName:=ReportName, _
Orientation:=Orientation, _
PaperSize:=PaperSize
'if the report is cancelled because of no data, an error results in the OpenReport method
On Error GoTo ReportError
With DoCmd
.OpenReport ReportName, acPreview, , WhereClause
.RunCommand acCmdFitToWindow
.Maximize
End With
FunctionExit:
Exit Function
ReportError:
'Error 2501 means that the OpenReport action was cancelled.
'Ignore it.
If Err.Number <> 2501 Then
MsgBox "Run Time Error '" & Err.Number & "':" & Chr(13) & Chr(13) & _
Err.Description & Chr(13), , _
"Microsoft Visual Basic"
End If
Resume FunctionExit
End Function
'Another Module
'I think I copied most of this from the Access help file
'and modified it to fit this application
Option Compare Database
Option Explicit
Type str_DEVMODE
RGB As String * 94
End Type
Type type_DEVMODE
strDeviceName As String * 16
intSpecVersion As Integer
intDriverVersion As Integer
intSize As Integer
intDriverExtra As Integer
lngFields As Long
intOrientation As Integer
intPaperSize As Integer
intPaperLength As Integer
intPaperWidth As Integer
intScale As Integer
intCopies As Integer
intDefaultSource As Integer
intPrintQuality As Integer
intColor As Integer
intDuplex As Integer
intResolution As Integer
intTTOption As Integer
intCollate As Integer
strFormName As String * 16
lngPad As Long
lngBits As Long
lngPW As Long
lngPH As Long
lngDFI As Long
lngDFr As Long
End Type
Public Function PageSetup(ReportName As String, Orientation, PaperSize)
'kluge - everytime we switch from on printer to an other (or to another pc using a different printer)
'access sets the pages to letter, portrait, letter
' called by the functions in module Menu Functions
Dim DevString As str_DEVMODE
Dim DM As type_DEVMODE
Dim strDevModeExtra As String
Dim rpt As Report
Dim PaperTray As String
' Opens report in Design view.
DoCmd.OpenReport ReportName, acDesign
Reports(ReportName).Visibl e = False
Set rpt = Reports(ReportName)
If Not IsNull(rpt.PrtDevMode) Then
strDevModeExtra = rpt.PrtDevMode
DevString.RGB = strDevModeExtra
LSet DM = DevString
DM.lngFields = DM.lngFields Or _
&H1 Or _
&H2 Or _
&H200
'DM.intOrientation ' Initialize fields.
Select Case Orientation
Case "Portrait"
DM.intOrientation = 1
Case "Landscape"
DM.intOrientation = 2
End Select
Select Case PaperSize
Case "Letter"
DM.intPaperSize = 1
PaperTray = "Automatic"
Case "Legal"
DM.intPaperSize = 5
PaperTray = "Manual"
End Select
Select Case PaperTray
Case "Automatic"
DM.intDefaultSource = 7
Case "Manual"
DM.intDefaultSource = 4
End Select
LSet DevString = DM ' Update property.
Mid(strDevModeExtra, 1, 94) = DevString.RGB
rpt.PrtDevMode = strDevModeExtra
End If
DoCmd.Close acReport, ReportName, acSave
End Function
Code in Switchboard or any other menu pushbutton:
PrintWeeklyWide
Public Function PrintWeeklyWide()
OpenReport "Schedule Weekly Wide", "Landscape", "Legal"
'note: you can also pass along a where clause
' OpenReport "Schedule Weekly Wide", "Landscape", "Legal", "where cause string"
End Function
Public Function OpenReport(ReportName As String, Orientation, PaperSize, Optional WhereClause)
'kluge - everytime we switch from on printer to an other (or to another pc using a different printer)
'access sets the pages to letter, portrait, letter
PageSetup _
ReportName:=ReportName, _
Orientation:=Orientation, _
PaperSize:=PaperSize
'if the report is cancelled because of no data, an error results in the OpenReport method
On Error GoTo ReportError
With DoCmd
.OpenReport ReportName, acPreview, , WhereClause
.RunCommand acCmdFitToWindow
.Maximize
End With
FunctionExit:
Exit Function
ReportError:
'Error 2501 means that the OpenReport action was cancelled.
'Ignore it.
If Err.Number <> 2501 Then
MsgBox "Run Time Error '" & Err.Number & "':" & Chr(13) & Chr(13) & _
Err.Description & Chr(13), , _
"Microsoft Visual Basic"
End If
Resume FunctionExit
End Function
'Another Module
'I think I copied most of this from the Access help file
'and modified it to fit this application
Option Compare Database
Option Explicit
Type str_DEVMODE
RGB As String * 94
End Type
Type type_DEVMODE
strDeviceName As String * 16
intSpecVersion As Integer
intDriverVersion As Integer
intSize As Integer
intDriverExtra As Integer
lngFields As Long
intOrientation As Integer
intPaperSize As Integer
intPaperLength As Integer
intPaperWidth As Integer
intScale As Integer
intCopies As Integer
intDefaultSource As Integer
intPrintQuality As Integer
intColor As Integer
intDuplex As Integer
intResolution As Integer
intTTOption As Integer
intCollate As Integer
strFormName As String * 16
lngPad As Long
lngBits As Long
lngPW As Long
lngPH As Long
lngDFI As Long
lngDFr As Long
End Type
Public Function PageSetup(ReportName As String, Orientation, PaperSize)
'kluge - everytime we switch from on printer to an other (or to another pc using a different printer)
'access sets the pages to letter, portrait, letter
' called by the functions in module Menu Functions
Dim DevString As str_DEVMODE
Dim DM As type_DEVMODE
Dim strDevModeExtra As String
Dim rpt As Report
Dim PaperTray As String
' Opens report in Design view.
DoCmd.OpenReport ReportName, acDesign
Reports(ReportName).Visibl
Set rpt = Reports(ReportName)
If Not IsNull(rpt.PrtDevMode) Then
strDevModeExtra = rpt.PrtDevMode
DevString.RGB = strDevModeExtra
LSet DM = DevString
DM.lngFields = DM.lngFields Or _
&H1 Or _
&H2 Or _
&H200
'DM.intOrientation ' Initialize fields.
Select Case Orientation
Case "Portrait"
DM.intOrientation = 1
Case "Landscape"
DM.intOrientation = 2
End Select
Select Case PaperSize
Case "Letter"
DM.intPaperSize = 1
PaperTray = "Automatic"
Case "Legal"
DM.intPaperSize = 5
PaperTray = "Manual"
End Select
Select Case PaperTray
Case "Automatic"
DM.intDefaultSource = 7
Case "Manual"
DM.intDefaultSource = 4
End Select
LSet DevString = DM ' Update property.
Mid(strDevModeExtra, 1, 94) = DevString.RGB
rpt.PrtDevMode = strDevModeExtra
End If
DoCmd.Close acReport, ReportName, acSave
End Function
BClark:
We don't see you very often around here and I'd like to encourage you to come by and participate more often. The first part of you comment was very informative. Do you know for sure if this works with a MDE in run-time?
The second bit of code was the same that Berg provided in his second comment. Of course it will not work with a MDE.
PageSetup must be a new function in Access 2000 as it is unknown in Access 97. Is that true or do you have another function which does this? The ability to do that is very intreging.
Jim
We don't see you very often around here and I'd like to encourage you to come by and participate more often. The first part of you comment was very informative. Do you know for sure if this works with a MDE in run-time?
The second bit of code was the same that Berg provided in his second comment. Of course it will not work with a MDE.
PageSetup must be a new function in Access 2000 as it is unknown in Access 97. Is that true or do you have another function which does this? The ability to do that is very intreging.
Jim
JimMorgan,
PageSetup is a function I put together. I think the core of it appears in the MS Access help file. The PageSetup function is listed at the end of my previous comment here. I don't know if any of this works with MDE or not...
Bill
PageSetup is a function I put together. I think the core of it appears in the MS Access help file. The PageSetup function is listed at the end of my previous comment here. I don't know if any of this works with MDE or not...
Bill
Bill:
Unfortunately, it will not work in an MDE for either Access2000 or Access97. According to Microsoft, this is 'By Design".
Microsoft suggests that if you want to change the page setting for a report (and who doesn't) that you ship your product as an MDE with full security turned on.
My reaction is MS is out of its gourd!
I've come up with what I believe is the only solution. Ship your MDE but create a separate MDB which is called from the MDE. This MDB only has Reports and minimal code that you might need for the reports. The reports are secured as Read Design only. That way no one can go screwing with the report and blame you if it doesn't give the right results. Also any queries you need to use with the report are linked back to the main MDE and are Snapshot so that the user can't use those to mess with the table data.
There is also one form which is Read Design only which has a listbox showing all the reports what the user can select from. This goes through the reportdefs and puts the names in the listbox.
They are not allowed to create any tables, forms, macros.
The nice thing about this is they can create their own reports. To use a prewritten report as a template, they can copy the report to a new report name and then modify it all they want. It automatically goes into the form listbox.
Same thing with queries. They can't change the existing ones but they can make a new query using the other query as a base. Since the shipped queries are Snapshot, the new queries will inherit the properties.
There are no tables and they won't be able to link to any tables as they are have no permissions for the users.
Does this make sense to you? I can't figure out any other way to do it.
Jim
Unfortunately, it will not work in an MDE for either Access2000 or Access97. According to Microsoft, this is 'By Design".
Microsoft suggests that if you want to change the page setting for a report (and who doesn't) that you ship your product as an MDE with full security turned on.
My reaction is MS is out of its gourd!
I've come up with what I believe is the only solution. Ship your MDE but create a separate MDB which is called from the MDE. This MDB only has Reports and minimal code that you might need for the reports. The reports are secured as Read Design only. That way no one can go screwing with the report and blame you if it doesn't give the right results. Also any queries you need to use with the report are linked back to the main MDE and are Snapshot so that the user can't use those to mess with the table data.
There is also one form which is Read Design only which has a listbox showing all the reports what the user can select from. This goes through the reportdefs and puts the names in the listbox.
They are not allowed to create any tables, forms, macros.
The nice thing about this is they can create their own reports. To use a prewritten report as a template, they can copy the report to a new report name and then modify it all they want. It automatically goes into the form listbox.
Same thing with queries. They can't change the existing ones but they can make a new query using the other query as a base. Since the shipped queries are Snapshot, the new queries will inherit the properties.
There are no tables and they won't be able to link to any tables as they are have no permissions for the users.
Does this make sense to you? I can't figure out any other way to do it.
Jim
In the previous comment, I meant to say MDB instead of MDE in the second sentence.
You can use the PrtDevMode property to set or return printing device mode information specified for a form or report in the Print dialog box.
Note It is strongly recommended that you consult the Win32 Software Development Kit for complete documentation on the PrtDevMode, PrtDevNames, and PrtMip properties.
Setting
The PrtDevMode property setting is a 94-byte structure that mirrors the DEVMODE structure defined in the Win32 Software Development Kit. For complete information on the PrtDevMode property members, consult the Win32 Software Development Kit.
The PrtDevMode property uses the following members.
Member Description
DeviceName A string with a maximum of 32 bytes that specifies the name of the device the driver supports ¾ for example, "HP LaserJet IIISi" if the Hewlett-Packard LaserJet IIISi is the specified printer. Each printer driver has a unique string.
SpecVersion An Integer that specifies the version number of the DEVMODE structure in the Win32 Software Development Kit.
DriverVersion An Integer that specifies the printer driver version number assigned by the printer driver developer.
Size An Integer that specifies the size, in bytes, of the DEVMODE structure. (This value doesn't include the optional dmDriverData member for device-specific data, which can follow this structure.) If an application manipulates only the driver-independent portion of the data, you can use this member to find out the length of this structure without having to account for different versions.
DriverExtra An Integer that specifies the size, in bytes, of the optional dmDriverData member for device-specific data, which can follow this structure. If an application doesn't use device-specific information, you set this member to 0.
Fields A Long value that specifies which of the remaining members in the DEVMODE structure have been initialized. It can be any combination of specific constants or none of them. For available constants, see the Fields member constants.
Orientation An Integer that specifies the orientation of the paper. It can be either 1 (portrait) or 2 (landscape).
PaperSize An Integer that specifies the size of the paper to print on. If you set this member to 0 or 256, the length and width of the paper are specified by the PaperLength and PaperWidth members, respectively. Otherwise, you can set the PaperSize member to a predefined value. For available values, see the PaperSize member values.
PaperLength An Integer that specifies the paper length in units of 1/10 of a millimeter. This member overrides the paper length specified by the PaperSize member for custom paper sizes or for devices such as dot-matrix printers that can print on a variety of paper sizes.
PaperWidth An Integer that specifies the paper width in units of 1/10 of a millimeter. This member overrides the paper width specified by the PaperSize member.
Scale An Integer that specifies the factor by which the printed output will be scaled. The apparent page size is scaled from the physical page size by a factor of scale/100. For example, a piece of paper measuring 8.5 by 11 inches (letter-size) with a Scale value of 50 would contain as much data as a page measuring 17 by 22 inches because the output text and graphics would be half their original height and width.
Copies An Integer that specifies the number of copies printed if the printing device supports multiple-page copies.
DefaultSource An Integer that specifies the default bin from which the paper is fed. For available values, see the DefaultSource member values.
PrintQuality An Integer that specifies the printer resolution. The values are –4 (high), –3 (medium), –2 (low), and –1 (draft).
Color An Integer. For a color printer, specifies whether the output is printed in color. The values are 1 (color) and 2 (monochrome).
Duplex An Integer. For a printer capable of duplex printing, specifies whether the output is printed on both sides of the paper. The values are 1 (simplex), 2 (horizontal), and 3 (vertical).
YResolution An Integer that specifies the y-resolution of the printer in dots per inch (dpi). If the printer initializes this member, the PrintQuality member specifies the x-resolution of the printer in dpi.
TTOption An Integer that specifies how TrueType fonts will be printed. For available values, see the TTOption member values.
Collate An Integer that specifies whether collation should be used when printing multiple copies. Using uncollated copies provides faster, more efficient output, since the data is sent to the printer just once.
FormName A string with a maximum of 16 characters that specifies the size of paper to use; for example, "Letter" or "Legal".
Pad A Long value that is used to pad out spaces, characters, or values for future versions.
Bits A Long value that specifies in bits per pixel the color resolution of the display device.
PW A Long value that specifies the width, in pixels, of the visible device surface (screen or printer).
PH A Long value that specifies the height, in pixels, of the visible device surface (screen or printer).
DFI A Long value that specifies the device's display mode.
DFR A Long value that specifies the frequency, in hertz (cycles per second), of the display device in a particular mode.
You can set the PrtDevMode property using Visual Basic.
This property setting is read/write in Design view and read-only in other views.
Caution Printer drivers can add device-specific data immediately following the 94 bytes of the DEVMODE structure. For this reason, it is important that the DEVMODE data outlined above not exceed 94 bytes.
Remarks
Only printer drivers that export the ExtDeviceMode function use the DEVMODE structure.
An application can retrieve the paper sizes and names supported by a printer by using the DC_PAPERS, DC_PAPERSIZE, and DC_PAPERNAMES values to call the DeviceCapabilities function.
Before setting the value of the TTOption member, applications should find out how a printer driver can use TrueType fonts by using the DC_TRUETYPE value to call the DeviceCapabilities function.
HTH
berg