MS Office Forum

Ask Question   UnAnswered
Home » Forum » MS Office       RSS Feeds

Print Control From A Combo Box Value

  Asked By: Glenn    Date: Oct 06    Category: MS Office    Views: 1969

I need a bit of pointing in the right direction

I have already conquered getting the current printers installed on a
computer, then sorted them and the put them in a combobox on a form.

I used a API routine found on the net - understand a bit about the flow but
not the concept of the api and how to work out the features.

The hard bit I seem to be having is storing the current one then switching
the focus to the one selected in the combobox and then sending the job to
the printer, then restoring the standard default printer.

The routine which grabs the printers and put them in to an array create the
"friendly printer name" and doesn't include the network port which I seem to
need (ie ne02) the same format that application.activeprinter gives you.

Now I have come up with a couple of ideas but need some sounding out of

I have recently read about


Application.XLDialogPrint and Application.XLDialog.Printersetup but not sure
how to use them and can I pass variables to them instead of user interaction

I tried playing but not to any great success please advice

Registry Method

I found the info which is stored in the current user part of the registry
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices

Where the friendly name is the name
And the Data is something like winspool,Ne0x:

So would be a good way of matching the name and then try and match the key
(friendly name) and then data and then string manipulation



3 Answers Found

Answer #1    Answered By: Thomas Thompson     Answered On: Oct 06

Can you post your API code? Maybe it can be modified to grab the port  name
also, to be stored  for later when you need it.

I think Stan Getz’ Access Cookbook book is well known to have a really good
section on changing the printers  from inside Access, most of which should be
transferable to Excel.

This web site:


has a lot of info  on the subject, however, it seems to be a reference to
other sources only, some of which are fee-based. It might be a jackpot, or
it might not be. For what it’s worth.

Answer #2    Answered By: Morris Hughes     Answered On: Oct 06

What I would like to do is to create  an array  then with

Friendly Name , Friendly Name & "on" Port Number

I not ever done a multi dimension array so any tips would be appreciated

As I currently call this function once then send the info  to a sort routine
and then populate the combobox

This is the module code

Option Explicit


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

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

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

Public Function ListPrinters() As Variant

Dim bSuccess As Boolean
Dim iBufferRequired As Long
Dim iBufferSize As Long
Dim iBuffer() As Long
Dim iEntries As Long
Dim iIndex As Long
Dim strPrinterName As String
Dim iDummy As Long
Dim iDriverBuffer() As Long
Dim StrPrinters() As String

iBufferSize = 3072

ReDim iBuffer((iBufferSize \ 4) - 1) As Long

'EnumPrinters will return a value False if the buffer is not big enough
bSuccess = EnumPrinters(PRINTER_ENUM_CONNECTIONS Or _
1, iBuffer(0), iBufferSize, iBufferRequired, iEntries)

If Not bSuccess Then
If iBufferRequired > iBufferSize Then
iBufferSize = iBufferRequired
Debug.Print "iBuffer too small. Trying again with "; _
iBufferSize & " bytes."
ReDim iBuffer(iBufferSize \ 4) As Long
End If
'Try again with new buffer
bSuccess = EnumPrinters(PRINTER_ENUM_CONNECTIONS Or _
1, iBuffer(0), iBufferSize, iBufferRequired, iEntries)
End If

If Not bSuccess Then
'Enumprinters returned False
MsgBox "Error enumerating printers."
Exit Function
'Enumprinters returned True, use found printers  to fill the array
ReDim StrPrinters(iEntries - 1)
For iIndex = 0 To iEntries - 1
'Get the printername
strPrinterName = Space$(StrLen(iBuffer(iIndex * 4 + 2)))
iDummy = PtrToStr(strPrinterName, iBuffer(iIndex * 4 + 2))
StrPrinters(iIndex) = strPrinterName
Next iIndex
End If

ListPrinters = StrPrinters

End Function

Answer #3    Answered By: Leo Evans     Answered On: Oct 06

Well, the key here is the Win32 API EnumPrinters.


Lots of info  there.

The key is that EnumPrinters returns data  into a buffer of either type
links to these data structures in the above article.

The docs, which should be read  carefully if you’re going to try to use this,
indicate that you have your choice of which PRINTER_INFO data structure you
want to return. It recommends PRINTER_INFO_4 as the one to use because it’s
the quickest and most lightweight. Your code is using PRINTER_INFO_1, as
determined by the 3rd parameter in the EnumPrinters call. PRINTER_INFO_1 may
work fine too.



PRINTER_INFO_4 just has the printer  name, the server name, and a
local/network attribute. MAYBE the server name is what you need. I don’t
know, haven’t tried it.

However, the docs also say that it just gets this info right out of the
registry, so if you find that easier, there you go.

In order to user  PRINTER_INFO_4 instead of PRINTER_INFO_1, you’ll need to
change iBufferSize to the correct number of bytes for the data structure (I
don’t know what that is), and you’ll also need to hack up the result using
code similar to what you currently have after the comment in your code that
says “get printer name”. I don’t know if that kind of byte-twiddle coding is
within your scope or not.

It may just be easier to pull the info from the Registry – I’m finding the
exact info you want at:

HKCU\Software\Microsoft\Windows NT\Current Version\Devices

It’s got the port  name and everything.

HKCU\Software\Microsoft\Windows NT\Current Version\PrinterPorts

has most of the same info, but with some extra timeout values, probably
unnecessary for your purposes.

I would go with the registry…

Didn't find what you were looking for? Find more on Print Control From A Combo Box Value Or get search suggestion and latest updates.