Saved Printer Name

J

JimP

Is there a way to loop through the Reports collection of an mdb and identify
the name of the printer saved with each report?
 
G

Graham Mandeno

Hi Jim

This ought to do the trick:

Sub ListReportPrinters()
Dim rpt As AccessObject
For Each rpt In CurrentProject.AllReports
DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden
With Reports(rpt.Name)
Debug.Print .Name; Tab(30); .Printer.DeviceName; _
IIf(.UseDefaultPrinter, " <default>", "")
End With
DoCmd.Close acReport, rpt.Name
Next
End Sub
 
J

JimP

Thank you,


Graham Mandeno said:
Hi Jim

This ought to do the trick:

Sub ListReportPrinters()
Dim rpt As AccessObject
For Each rpt In CurrentProject.AllReports
DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden
With Reports(rpt.Name)
Debug.Print .Name; Tab(30); .Printer.DeviceName; _
IIf(.UseDefaultPrinter, " <default>", "")
End With
DoCmd.Close acReport, rpt.Name
Next
End Sub

--
Good Luck :)

Graham Mandeno [Access MVP]
Auckland, New Zealand

JimP said:
Is there a way to loop through the Reports collection of an mdb and
identify the name of the printer saved with each report?
 
J

JimP

I've run into a snag. I get an error message when the report opens and the
printer is not available. Can I disable the error message?

"This document was previously formatted for the printer ..., but that
printer isn't available. Do you want to use the default printer ...?


Graham Mandeno said:
Hi Jim

This ought to do the trick:

Sub ListReportPrinters()
Dim rpt As AccessObject
For Each rpt In CurrentProject.AllReports
DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden
With Reports(rpt.Name)
Debug.Print .Name; Tab(30); .Printer.DeviceName; _
IIf(.UseDefaultPrinter, " <default>", "")
End With
DoCmd.Close acReport, rpt.Name
Next
End Sub

--
Good Luck :)

Graham Mandeno [Access MVP]
Auckland, New Zealand

JimP said:
Is there a way to loop through the Reports collection of an mdb and
identify the name of the printer saved with each report?
 
J

Jack Leach

Get the error number and put an error trap in the loop for that number. Set
the debug.print to something like "no printer" if err.number = whatever this
error is.



--
Jack Leach
www.tristatemachine.com

"I haven't failed, I've found ten thousand ways that don't work."
-Thomas Edison (1847-1931)



JimP said:
I've run into a snag. I get an error message when the report opens and the
printer is not available. Can I disable the error message?

"This document was previously formatted for the printer ..., but that
printer isn't available. Do you want to use the default printer ...?


Graham Mandeno said:
Hi Jim

This ought to do the trick:

Sub ListReportPrinters()
Dim rpt As AccessObject
For Each rpt In CurrentProject.AllReports
DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden
With Reports(rpt.Name)
Debug.Print .Name; Tab(30); .Printer.DeviceName; _
IIf(.UseDefaultPrinter, " <default>", "")
End With
DoCmd.Close acReport, rpt.Name
Next
End Sub

--
Good Luck :)

Graham Mandeno [Access MVP]
Auckland, New Zealand

JimP said:
Is there a way to loop through the Reports collection of an mdb and
identify the name of the printer saved with each report?
 
J

JimP

I have an error handler in the routine. This "message window" does not trip
an error. The message window appears upon opening up the report, e.g.

DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden

...not sure what I can do - there's too many reports to consider opening each
one manually.


Jack Leach said:
Get the error number and put an error trap in the loop for that number.
Set
the debug.print to something like "no printer" if err.number = whatever
this
error is.



--
Jack Leach
www.tristatemachine.com

"I haven't failed, I've found ten thousand ways that don't work."
-Thomas Edison (1847-1931)



JimP said:
I've run into a snag. I get an error message when the report opens and
the
printer is not available. Can I disable the error message?

"This document was previously formatted for the printer ..., but that
printer isn't available. Do you want to use the default printer ...?


Graham Mandeno said:
Hi Jim

This ought to do the trick:

Sub ListReportPrinters()
Dim rpt As AccessObject
For Each rpt In CurrentProject.AllReports
DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden
With Reports(rpt.Name)
Debug.Print .Name; Tab(30); .Printer.DeviceName; _
IIf(.UseDefaultPrinter, " <default>", "")
End With
DoCmd.Close acReport, rpt.Name
Next
End Sub

--
Good Luck :)

Graham Mandeno [Access MVP]
Auckland, New Zealand

Is there a way to loop through the Reports collection of an mdb and
identify the name of the printer saved with each report?
 
D

Dirk Goldgar

JimP said:
I have an error handler in the routine. This "message window" does not trip
an error. The message window appears upon opening up the report, e.g.

DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden

..not sure what I can do - there's too many reports to consider opening
each one manually.


I have no means to check this at the moment, but does turning warning off
(DoCmd.SetWarnings False) suppress the message?
 
J

Jack Leach

Ahhh... not technically an error.

Sorry, I wouldn't know how to handle this. I'm assuming SetWarnings won't
do anything for you, but it may be worth a shot just to see.

Sorry, this is hardly an area of expertise for me. Too bad the reports need
to be opened to access these properties.

--
Jack Leach
www.tristatemachine.com

"I haven't failed, I've found ten thousand ways that don't work."
-Thomas Edison (1847-1931)



JimP said:
I have an error handler in the routine. This "message window" does not trip
an error. The message window appears upon opening up the report, e.g.

DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden

...not sure what I can do - there's too many reports to consider opening each
one manually.


Jack Leach said:
Get the error number and put an error trap in the loop for that number.
Set
the debug.print to something like "no printer" if err.number = whatever
this
error is.



--
Jack Leach
www.tristatemachine.com

"I haven't failed, I've found ten thousand ways that don't work."
-Thomas Edison (1847-1931)



JimP said:
I've run into a snag. I get an error message when the report opens and
the
printer is not available. Can I disable the error message?

"This document was previously formatted for the printer ..., but that
printer isn't available. Do you want to use the default printer ...?


Hi Jim

This ought to do the trick:

Sub ListReportPrinters()
Dim rpt As AccessObject
For Each rpt In CurrentProject.AllReports
DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden
With Reports(rpt.Name)
Debug.Print .Name; Tab(30); .Printer.DeviceName; _
IIf(.UseDefaultPrinter, " <default>", "")
End With
DoCmd.Close acReport, rpt.Name
Next
End Sub

--
Good Luck :)

Graham Mandeno [Access MVP]
Auckland, New Zealand

Is there a way to loop through the Reports collection of an mdb and
identify the name of the printer saved with each report?
 
D

Dirk Goldgar

JimP said:
I have an error handler in the routine. This "message window" does not trip
an error. The message window appears upon opening up the report, e.g.

DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden

..not sure what I can do - there's too many reports to consider opening
each one manually.


Another possibility, though a bit complicated and clunky, is to save the
report design as a text file:

Application.SaveAsText acReport, rpt.Name, _
CurrentProject.Path & "\" & rpt.Name & ".txt"

.... and then use standard VB I/O statements to read and parse the text file.
If you open the text file in NotePad, you can see the PrtDevMode and
PrtDevNames structures, and can probably work out how to parse and interpret
them.
 
J

JimP

Thanks to all. I'll give the SetWarnings a try. Also, I Googled the error
below, and there may be some other issues.

"This document was previously formatted for the printer ..., but that
printer isn't available. Do you want to use the default printer ...?
 
T

Tony Toews [MVP]

Dirk Goldgar said:
Another possibility, though a bit complicated and clunky, is to save the
report design as a text file:

Application.SaveAsText acReport, rpt.Name, _
CurrentProject.Path & "\" & rpt.Name & ".txt"

... and then use standard VB I/O statements to read and parse the text file.
If you open the text file in NotePad, you can see the PrtDevMode and
PrtDevNames structures, and can probably work out how to parse and interpret
them.

Even I tread carefully and softly when it comes to PrtDevMode.

Tony
 
G

Graham Mandeno

Hi Jim

[I normally wouldn't do this, but I'm cc-ing your email just in case]

I hope I'm not too late, but DO NOT USE SetWarnings False.

If you do, then the "do something" option will be used for anything you
would otherwise get a prompt for.

So, instead of asking you, the report WILL be modified to use the default
printer, then, because the report's design has changed, the changes will be
saved without asking when you close the report. Any record that the report
once used a non-default but unavailable printer will be lost.

Just for safety, I suggest you add acSaveNo to the DoCmd.Close.

I believe the only practical way to do this is to use Dirk's suggestion and
dump the report design into a text file with SaveAsText.

The problem is that the printer info is hard to decode. You get something
like this:

PrtDevNames = Begin
0x080012002b00000077696e73706f6f6c002d5c5c43524f4e4f535c43616e6f6e ,
0x204c42502d3137363000284c5054313a00204c5054313a0036302028322d7570 ,
0x2900
End

The printer name (and whether or not it's the default printer) are buried in
the hex strings!

If you're really serious about doing this, I'm happy to help you knock up
some code. Let me know. But please reply to the newsgroup, not the email.
 
G

Graham Mandeno

Hi Jim

Curiosity got the better of me and I couldn't resist <grin>.

I haven't timed it properly, but the code below seems to be much faster that
the version that opened each report.

--
Good Luck :)

Graham Mandeno [Access MVP]
Auckland, New Zealand

=========== start code ==============

Public Sub ListReportPrinters2()
Dim rpt As AccessObject
Dim sTmpFile As String, hTmp As Long
Dim sDevNames As String, sLine As String
Dim sPrinter As String, fDefault As Boolean
sTmpFile = CurrentProject.Path & "\~tmpReport.tmp"
hTmp = FreeFile
For Each rpt In CurrentProject.AllReports
If Len(Dir(sTmpFile)) <> 0 Then Kill sTmpFile
Application.SaveAsText acReport, rpt.Name, sTmpFile
Open sTmpFile For Input As #hTmp
Do
Line Input #hTmp, sLine
Loop Until InStr(sLine, "PrtDevNames = Begin") <> 0
Line Input #hTmp, sLine
sDevNames = vbNullString
Do Until InStr(sLine, " End") <> 0
sLine = Replace(sLine, "0x", "")
sLine = Replace(sLine, " ", "")
sLine = Replace(sLine, ",", "")
sDevNames = sDevNames & sLine
Line Input #hTmp, sLine
Loop
sPrinter = HexToSZ(sDevNames, HexToInteger(sDevNames, 2))
fDefault = HexToInteger(sDevNames, 6)
Debug.Print rpt.Name; Tab(40); sPrinter; _
IIf(fDefault, " <default>", "")
Close #hTmp
Next
If Len(Dir(sTmpFile)) <> 0 Then Kill sTmpFile
End Sub

Public Function HexToByte(s As String, _
Optional offset As Long) As Byte
HexToByte = Val("&H" & Mid(s, offset * 2 + 1, 2))
End Function

Public Function HexToInteger(s As String, _
Optional offset As Long) As Integer
HexToInteger = HexToByte(s, offset + 1) * &H100 _
+ HexToByte(s, offset)
End Function

Public Function HexToSZ(s As String, _
Optional offset As Long) As String
Dim rslt As String, o As Long, b As Byte
o = offset
Do While True
b = HexToByte(s, o)
If b = 0 Then Exit Do
rslt = rslt & Chr(b)
o = o + 1
Loop
HexToSZ = rslt
End Function
============= end code ====================

Graham Mandeno said:
Hi Jim

[I normally wouldn't do this, but I'm cc-ing your email just in case]

I hope I'm not too late, but DO NOT USE SetWarnings False.

If you do, then the "do something" option will be used for anything you
would otherwise get a prompt for.

So, instead of asking you, the report WILL be modified to use the default
printer, then, because the report's design has changed, the changes will
be saved without asking when you close the report. Any record that the
report once used a non-default but unavailable printer will be lost.

Just for safety, I suggest you add acSaveNo to the DoCmd.Close.

I believe the only practical way to do this is to use Dirk's suggestion
and dump the report design into a text file with SaveAsText.

The problem is that the printer info is hard to decode. You get something
like this:

PrtDevNames = Begin
0x080012002b00000077696e73706f6f6c002d5c5c43524f4e4f535c43616e6f6e
,
0x204c42502d3137363000284c5054313a00204c5054313a0036302028322d7570
,
0x2900
End

The printer name (and whether or not it's the default printer) are buried
in the hex strings!

If you're really serious about doing this, I'm happy to help you knock up
some code. Let me know. But please reply to the newsgroup, not the
email.

--
Good Luck :)

Graham Mandeno [Access MVP]
Auckland, New Zealand


JimP said:
Thanks to all. I'll give the SetWarnings a try. Also, I Googled the error
below, and there may be some other issues.

"This document was previously formatted for the printer ..., but that
printer isn't available. Do you want to use the default printer ...?
 
J

JimP

Thanks. But, if I wanted to save each report using the default printer (and
save the settings), then it sounds like this would work.


Graham Mandeno said:
Hi Jim

[I normally wouldn't do this, but I'm cc-ing your email just in case]

I hope I'm not too late, but DO NOT USE SetWarnings False.

If you do, then the "do something" option will be used for anything you
would otherwise get a prompt for.

So, instead of asking you, the report WILL be modified to use the default
printer, then, because the report's design has changed, the changes will
be saved without asking when you close the report. Any record that the
report once used a non-default but unavailable printer will be lost.

Just for safety, I suggest you add acSaveNo to the DoCmd.Close.

I believe the only practical way to do this is to use Dirk's suggestion
and dump the report design into a text file with SaveAsText.

The problem is that the printer info is hard to decode. You get something
like this:

PrtDevNames = Begin
0x080012002b00000077696e73706f6f6c002d5c5c43524f4e4f535c43616e6f6e
,
0x204c42502d3137363000284c5054313a00204c5054313a0036302028322d7570
,
0x2900
End

The printer name (and whether or not it's the default printer) are buried
in the hex strings!

If you're really serious about doing this, I'm happy to help you knock up
some code. Let me know. But please reply to the newsgroup, not the
email.

--
Good Luck :)

Graham Mandeno [Access MVP]
Auckland, New Zealand


JimP said:
Thanks to all. I'll give the SetWarnings a try. Also, I Googled the error
below, and there may be some other issues.

"This document was previously formatted for the printer ..., but that
printer isn't available. Do you want to use the default printer ...?
 
G

Graham Mandeno

Hi Jim

Ah well, I learned something writing the code! I hope you or someone else
still finds it useful. :)

You could still use it to find, list and modify all those reports that do
NOT use the default printer, because the other code will (a) not tell you
what the assigned but unavailable printer was before and (b) will not modify
a non-default printer that IS available:

If Not fDefault then
Debug.Print rpt.Name; Tab(40); sPrinter
DoCmd.SetWarnings False
DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden
Reports(rpt.Name).UseDefaultPrinter = True
DoCmd.Close acReport, rpt.Name, acSaveYes

DoCmd.SetWarnings True
End If

--
Good Luck :)

Graham Mandeno [Access MVP]
Auckland, New Zealand

JimP said:
Thanks. But, if I wanted to save each report using the default printer
(and save the settings), then it sounds like this would work.


Graham Mandeno said:
Hi Jim

[I normally wouldn't do this, but I'm cc-ing your email just in case]

I hope I'm not too late, but DO NOT USE SetWarnings False.

If you do, then the "do something" option will be used for anything you
would otherwise get a prompt for.

So, instead of asking you, the report WILL be modified to use the default
printer, then, because the report's design has changed, the changes will
be saved without asking when you close the report. Any record that the
report once used a non-default but unavailable printer will be lost.

Just for safety, I suggest you add acSaveNo to the DoCmd.Close.

I believe the only practical way to do this is to use Dirk's suggestion
and dump the report design into a text file with SaveAsText.

The problem is that the printer info is hard to decode. You get
something like this:

PrtDevNames = Begin
0x080012002b00000077696e73706f6f6c002d5c5c43524f4e4f535c43616e6f6e
,
0x204c42502d3137363000284c5054313a00204c5054313a0036302028322d7570
,
0x2900
End

The printer name (and whether or not it's the default printer) are buried
in the hex strings!

If you're really serious about doing this, I'm happy to help you knock up
some code. Let me know. But please reply to the newsgroup, not the
email.

--
Good Luck :)

Graham Mandeno [Access MVP]
Auckland, New Zealand


JimP said:
Thanks to all. I'll give the SetWarnings a try. Also, I Googled the
error below, and there may be some other issues.

"This document was previously formatted for the printer ..., but that
printer isn't available. Do you want to use the default printer ...?



I have an error handler in the routine. This "message window" does not
trip an error. The message window appears upon opening up the report,
e.g.

DoCmd.OpenReport rpt.Name, acViewDesign, , , acHidden

..not sure what I can do - there's too many reports to consider
opening each one manually.


Another possibility, though a bit complicated and clunky, is to save
the report design as a text file:

Application.SaveAsText acReport, rpt.Name, _
CurrentProject.Path & "\" & rpt.Name & ".txt"

... and then use standard VB I/O statements to read and parse the text
file. If you open the text file in NotePad, you can see the PrtDevMode
and PrtDevNames structures, and can probably work out how to parse and
interpret them.

--
Dirk Goldgar, MS Access MVP
www.datagnostics.com

(please reply to the newsgroup)
 
Top