List Available Printers from Access 2000 VBA

A

Alan Z. Scharf

How can I get a list of available printers in Access 2000 VBA.

I would like the equivalent of the code below, which works in Access 2003.

Access 2000 doesn't seem to have the Printer object.

Thanks.

Alan

---------------

Public Function GetPrinterList()

Dim prt As Printer

For Each prt In Application.Printers
Debug.Print prt.DeviceName
Next

End Function
 
A

Allen Browne

See help on PrtDevNames and PrtMip.

These properties are rather cryptic, and not easy to get right. For example,
Microsoft got the PrtMip example wrong in the A2000 help file, and they also
got it wrong in a different place in the A97 help file, and also in a
different place in the A95 help file. I haven't checked the later versions,
but this link should give you the right lead:
http://www.mvps.org/access/reports/rpt0009.htm
 
G

Graham Mandeno

Hi Alan

It's a little arcane (we waited a long time for a native Printer object and
they haven't *quite* got it right yet!) but here goes:

You need to first paste this code into a module:

=============== start of code ================

Private Const PRINTER_ENUM_LOCAL = &H2
Private Const PRINTER_ENUM_CONNECTIONS = &H4

Private Declare Function EnumPrinters Lib "winspool.drv" _
Alias "EnumPrintersA" _
(ByVal flags As Long, _
ByVal name As String, _
ByVal Level As Long, _
pPrinterEnum As Any, _
ByVal cdBuf As Long, _
pcbNeeded As Long, _
pcReturned As Long) _
As Long

Private Declare Function StrLen Lib "kernel32" _
Alias "lstrlenA" _
(ByVal Ptr As Long) _
As Long

Private Declare Function StrCopy Lib "kernel32" _
Alias "lstrcpyA" _
(ByVal RetVal As String, _
ByVal Ptr As Long) _
As Long

Private Function CopyStringFromPtr(ByVal pSource As Long) As String
CopyStringFromPtr = Space$(StrLen(pSource))
StrCopy CopyStringFromPtr, pSource
End Function

Public Function GetPrinterNames() As Variant
Dim fSuccess As Boolean, lBuflen As Long, lFlags As Long
Dim aBuffer() As Long, lEntries As Long
Dim iCount As Integer, aPrinters() As String
lFlags = PRINTER_ENUM_LOCAL Or PRINTER_ENUM_CONNECTIONS
Call EnumPrinters(lFlags, vbNullString, 1, 0, 0, lBuflen, lEntries)
ReDim aBuffer(lBuflen \ 4)
fSuccess = EnumPrinters( _
lFlags, _
vbNullString, _
1, _
aBuffer(0), _
lBuflen, _
lBuflen, _
lEntries) <> 0
If fSuccess And lEntries > 0 Then
ReDim aPrinters(lEntries - 1)
For iCount = 0 To lEntries - 1
aPrinters(iCount) = CopyStringFromPtr(aBuffer(iCount * 4 + 2))
Next
GetPrinterNames = aPrinters
End If
End Function

=============== end of code ================

Then, make a small alteration to your GetPrinterList procedure:

Public Function GetPrinterList()
Dim aPrinters As Variant, i As Integer
aPrinters = GetPrinterNames
If IsArray(aPrinters) Then
For i = 0 To UBound(aPrinters)
Debug.Print aPrinters(i)
Next
End If
End Sub
 
V

Van T. Dinh

Yep, it was wrong in A95 & A97 Help. IIRC the Help topic said the PrtMip is
a 28-byte String and it turned out to be a 56-byte String. It took me 2
days to get something done that should have taken a hour had the Help topic
go the right info.

Even though I got the thing done, I have avoided PrtMip since.
 
A

Allen Browne

Yes, Van, my frustration was similar.

But it did make me feel better when I realized the MS guys had got it wrong
several times as well. :)
 
A

Alan Z. Scharf

rry for the delay in getting back to you.

Thanks very much for your detailded code!

That worked perfectly.

Alan


Graham Mandeno said:
Hi Alan

It's a little arcane (we waited a long time for a native Printer object and
they haven't *quite* got it right yet!) but here goes:

You need to first paste this code into a module:

=============== start of code ================

Private Const PRINTER_ENUM_LOCAL = &H2
Private Const PRINTER_ENUM_CONNECTIONS = &H4

Private Declare Function EnumPrinters Lib "winspool.drv" _
Alias "EnumPrintersA" _
(ByVal flags As Long, _
ByVal name As String, _
ByVal Level As Long, _
pPrinterEnum As Any, _
ByVal cdBuf As Long, _
pcbNeeded As Long, _
pcReturned As Long) _
As Long

Private Declare Function StrLen Lib "kernel32" _
Alias "lstrlenA" _
(ByVal Ptr As Long) _
As Long

Private Declare Function StrCopy Lib "kernel32" _
Alias "lstrcpyA" _
(ByVal RetVal As String, _
ByVal Ptr As Long) _
As Long

Private Function CopyStringFromPtr(ByVal pSource As Long) As String
CopyStringFromPtr = Space$(StrLen(pSource))
StrCopy CopyStringFromPtr, pSource
End Function

Public Function GetPrinterNames() As Variant
Dim fSuccess As Boolean, lBuflen As Long, lFlags As Long
Dim aBuffer() As Long, lEntries As Long
Dim iCount As Integer, aPrinters() As String
lFlags = PRINTER_ENUM_LOCAL Or PRINTER_ENUM_CONNECTIONS
Call EnumPrinters(lFlags, vbNullString, 1, 0, 0, lBuflen, lEntries)
ReDim aBuffer(lBuflen \ 4)
fSuccess = EnumPrinters( _
lFlags, _
vbNullString, _
1, _
aBuffer(0), _
lBuflen, _
lBuflen, _
lEntries) <> 0
If fSuccess And lEntries > 0 Then
ReDim aPrinters(lEntries - 1)
For iCount = 0 To lEntries - 1
aPrinters(iCount) = CopyStringFromPtr(aBuffer(iCount * 4 + 2))
Next
GetPrinterNames = aPrinters
End If
End Function

=============== end of code ================

Then, make a small alteration to your GetPrinterList procedure:

Public Function GetPrinterList()
Dim aPrinters As Variant, i As Integer
aPrinters = GetPrinterNames
If IsArray(aPrinters) Then
For i = 0 To UBound(aPrinters)
Debug.Print aPrinters(i)
Next
End If
End Sub

--
Good Luck!

Graham Mandeno [Access MVP]
Auckland, New Zealand

Alan Z. Scharf said:
How can I get a list of available printers in Access 2000 VBA.

I would like the equivalent of the code below, which works in Access 2003.

Access 2000 doesn't seem to have the Printer object.

Thanks.

Alan

---------------

Public Function GetPrinterList()

Dim prt As Printer

For Each prt In Application.Printers
Debug.Print prt.DeviceName
Next

End Function
 
A

Alan Z. Scharf

Allen,

Sorry for the delay in getting back to you.

Thanks very much for your links.

They helped a great deal.

Alan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top