Results 1 to 8 of 8

Thread: Create list of printers

  1. #1

    Thread Starter
    Member
    Join Date
    Aug 2005
    Location
    West Midlands, UK
    Posts
    33

    Question Create list of printers

    Help ......

    I am using VBA in Excel and I have a form which I have created. On the form I need to put a drop down list box from which to select a printer.

    The list of printers is not known at creation time as it is to be the list of printers installed on the current computer so that user can print to any attached printer.

    Does anybody know a simple way to obtain the names for the printers that are installed. I do not want to use the xlDialogPrinterSetup as it allow the user to override my print setups.

    Advise on how to populate the list box would also be helpful.

    Thank you all for your help on this.

  2. #2
    Frenzied Member cssriraman's Avatar
    Join Date
    Jun 2005
    Posts
    1,465

    Re: Create list of printers

    Hi,

    It requires some Windows API trickery, because VBA (unlike VB) does not have a Printers collection. Paste the following into a separate module. The function ListPrinters returns a variant containing an array of printer names.
    VB Code:
    1. Option Explicit
    2.  
    3. Const PRINTER_ENUM_CONNECTIONS = &H4
    4. Const PRINTER_ENUM_LOCAL = &H2
    5.  
    6. Private Declare Function EnumPrinters Lib "winspool.drv" Alias "EnumPrintersA" _
    7.         (ByVal flags As Long, ByVal name As String, ByVal Level As Long, _
    8.         pPrinterEnum As Long, ByVal cdBuf As Long, pcbNeeded As Long, _
    9.         pcReturned As Long) As Long
    10.  
    11. Private Declare Function PtrToStr Lib "kernel32" Alias "lstrcpyA" _
    12.         (ByVal RetVal As String, ByVal Ptr As Long) As Long
    13.  
    14. Private Declare Function StrLen Lib "kernel32" Alias "lstrlenA" _
    15.        (ByVal Ptr As Long) As Long
    16.  
    17. Public Function ListPrinters() As Variant
    18. Dim bSuccess As Boolean
    19. Dim iBufferRequired As Long
    20. Dim iBufferSize As Long
    21. Dim iBuffer() As Long
    22. Dim iEntries As Long
    23. Dim iIndex As Long
    24. Dim strPrinterName As String
    25. Dim iDummy As Long
    26. Dim iDriverBuffer() As Long
    27. Dim strPrinters() As String
    28. iBufferSize = 3072
    29. ReDim iBuffer((iBufferSize \ 4) - 1) As Long
    30. 'EnumPrinters will return a value False if the buffer is not big enough
    31. bSuccess = EnumPrinters(PRINTER_ENUM_CONNECTIONS Or _
    32.         PRINTER_ENUM_LOCAL, vbNullString, _
    33.         1, iBuffer(0), iBufferSize, iBufferRequired, iEntries)
    34. If Not bSuccess Then
    35.     If iBufferRequired > iBufferSize Then
    36.         iBufferSize = iBufferRequired
    37.         Debug.Print "iBuffer too small. Trying again with "; _
    38.         iBufferSize & " bytes."
    39.         ReDim iBuffer(iBufferSize \ 4) As Long
    40.     End If
    41.     'Try again with new buffer
    42.     bSuccess = EnumPrinters(PRINTER_ENUM_CONNECTIONS Or _
    43.             PRINTER_ENUM_LOCAL, vbNullString, _
    44.             1, iBuffer(0), iBufferSize, iBufferRequired, iEntries)
    45. End If
    46. If Not bSuccess Then
    47.     'Enumprinters returned False
    48.     MsgBox "Error enumerating printers."
    49.     Exit Function
    50. Else
    51.     'Enumprinters returned True, use found printers to fill the array
    52.     ReDim strPrinters(iEntries - 1)
    53.     For iIndex = 0 To iEntries - 1
    54.         'Get the printername
    55.         strPrinterName = Space$(StrLen(iBuffer(iIndex * 4 + 2)))
    56.         iDummy = PtrToStr(strPrinterName, iBuffer(iIndex * 4 + 2))
    57.         strPrinters(iIndex) = strPrinterName
    58.     Next iIndex
    59. End If
    60. ListPrinters = strPrinters
    61. End Function
    62.  
    63. 'You could call the function as follows:
    64. Sub Test()
    65. Dim StrPrinters As Variant, x As Long
    66. StrPrinters = ListPrinters
    67. 'Fist check whether the array is filled with anything, by calling another function, IsBounded.
    68. If IsBounded(StrPrinters) Then
    69.     For x = LBound(strPrinters) To UBound(strPrinters)
    70.         Debug.Print StrPrinters(x)
    71.     Next x
    72. Else
    73.     Debug.Print "No printers found"
    74. End If
    75. End Sub
    76.  
    77. Public Function IsBounded(vArray As Variant) As Boolean
    78.     'If the variant passed to this function is an array, the function will return True;
    79.     'otherwise it will return False
    80.     On Error Resume Next
    81.     IsBounded = IsNumeric(UBound(vArray))
    82. End Function
    Let me know if you need any help on this.
    CS

  3. #3

    Thread Starter
    Member
    Join Date
    Aug 2005
    Location
    West Midlands, UK
    Posts
    33

    Re: Create list of printers

    Thank you for the code above.

    I have now got the program to display the list of available printers on the workstation.

    However if I try to change the printer I get an error: "Run-Time error 1004: Method Activeprinter of object -Application Failed."

    Checking for values I notice that the current active printer has a value in format "\\XXX9999\XXX99999 on XX99". The value take from the combobox (ie the printer name) is in the format "\\XXX9999\XXX99999".

    Please can you advise how I can get the system name so that I can change the printer.

    As I am wanting this program to be used by various people I do not know the format for everyones printers.

    Thank you in advance for advice.

  4. #4

    Thread Starter
    Member
    Join Date
    Aug 2005
    Location
    West Midlands, UK
    Posts
    33

    Re: Create list of printers

    Does any body know how to read the printers name so that it can be used to set the activeprinter property?

  5. #5
    Frenzied Member cssriraman's Avatar
    Join Date
    Jun 2005
    Posts
    1,465

    Re: Create list of printers

    Yes! I got the same problem in Excel. But it works fine for me in Word. Is there anybody to fix this issue?
    CS

  6. #6
    New Member
    Join Date
    Feb 2006
    Posts
    3

    Re: Create list of printers

    Guessing that your trying to set a networked printer as the activeprinter (by the "on xx99").

    This is the code i use at work to send a print job to a printer i'd chosen, in this case the printer is called "Stock Control"
    and "\\root" is our servers name, where all the printer drivers are installed.
    Using the code above to allow a user to choose the printer (novel idea ) drop the printer
    name into a variable and use this instead of "Stock Control" when you call the function.
    The function just loops thru on Ne00: to Ne99: testing each one until it finds the correct network address for the printer.
    It also resets the users default printer back after the jobs printed. (strCurrentPrinter)
    Hope this helps...

    VB Code:
    1. Function GetFullNetworkPrinterName(strNetworkPrinterName As String) As String
    2. ' returns the full network printer name
    3. ' returns an empty string if the printer is not found
    4. ' e.g. GetFullNetworkPrinterName("\\root\Stock Control")
    5. Dim strCurrentPrinterName As String, strTempPrinterName As String, i As Long
    6.     strCurrentPrinterName = Application.ActivePrinter
    7.     i = 0
    8.     Do While i < 100
    9.         strTempPrinterName = strNetworkPrinterName & " on Ne" & Format(i, "00") & ":"
    10.         On Error Resume Next ' try to change to the network printer
    11.         Application.ActivePrinter = strTempPrinterName
    12.         On Error GoTo 0
    13.         If Application.ActivePrinter = strTempPrinterName Then
    14.             ' the network printer was found
    15.             GetFullNetworkPrinterName = strTempPrinterName
    16.             i = 100 ' makes the loop end
    17.         End If
    18.         i = i + 1
    19.     Loop
    20.     ' remove the line below if you want the function to change the active printer
    21.     Application.ActivePrinter = strCurrentPrinterName ' change back to the original printer
    22. End Function

    call it with:
    VB Code:
    1. strNetworkPrinter = GetFullNetworkPrinterName("\\root\Stock Control")
    2.     If Len(strNetworkPrinter) > 0 Then ' found the network printer
    3.         strCurrentPrinter = Application.ActivePrinter
    4.         Application.ActivePrinter = strNetworkPrinter ' change to the network printer
    5.         ActiveWindow.SelectedSheets.PrintOut Copies:=1, Collate:=True ' Print active sheet on chosen printer
    6.         Application.ActivePrinter = strCurrentPrinter ' change back to the previously active printer

  7. #7

    Thread Starter
    Member
    Join Date
    Aug 2005
    Location
    West Midlands, UK
    Posts
    33

    Re: Create list of printers

    Any one know of a more direct route than the one suggested by LexII.

    One I have tested his suggest I will update this thread with the result.

  8. #8

    Thread Starter
    Member
    Join Date
    Aug 2005
    Location
    West Midlands, UK
    Posts
    33

    Resolved Re: Create list of printers

    Thank you to all who have helped on this. I have now got the printers to work.

    I have used the info provided above to base my code on. The code that I have used is below.

    To obtain names of the printers attached to the workstation:
    VB Code:
    1. Private Sub UserForm_Activate()
    2. Dim owshNetwork As Object
    3. Dim oPrinters As Object
    4. Dim i As Long
    5. Dim aryPrinters
    6. Set owshNetwork = CreateObject("WScript.Network")
    7. Set oPrinters = owshNetwork.EnumPrinterConnections
    8. ReDim aryPrinters(0 To oPrinters.Count \ 2 - 1)
    9. For i = 0 To oPrinters.Count - 1 Step 2
    10.     aryPrinters(i \ 2) = oPrinters.Item(i + 1)
    11. Next
    12. qty = 1
    13. Label2.Caption = qty
    14. For i = 0 To Val(UBound(aryPrinters))
    15.     ComboBox1.AddItem (aryPrinters(i))
    16. Next i
    17. ComboBox1.Text = Application.ActivePrinter
    18. End Sub
    To find the full name of the printer as required to set the active printer the code used is:
    VB Code:
    1. Sub CommandButton1_Click()
    2. Dim strPrinter As String
    3. Dim a As Integer
    4. a = 1
    5. Do While a < 100
    6.     strPinter = ComboBox1.Text & " on Ne" & Format(a, "00") & ":"
    7.     a = a + 1
    8.     On Error Resume Next
    9.     Application.ActivePrinter = strPrinter
    10.     On Error GoTo 0
    11. Loop
    12. PrintCopies = Label2.Caption
    13. Unload Me
    14. End Sub
    Thanks again. My application is now complete.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width