Go Back   Access World Forums > Microsoft Access Discussion > Modules & VBA

 
Reply
 
Thread Tools Rate Thread Display Modes
Old 05-17-2018, 07:35 AM   #1
lespritdelescalier
Newly Registered User
 
Join Date: Mar 2015
Posts: 50
Thanks: 9
Thanked 1 Time in 1 Post
lespritdelescalier is on a distinguished road
Can I set the Windows default printer using VBA?

Hi everyone,

I am working on an application which prints both reports created in Access, and external PDFs. These documents are printed to a physical printer, but each document may need to be sent to a different printer than the previous one.

For reports created in Access, this isn't an issue, as I can specify the printer using Reports(reportname).Printer when I print. However, when I am printing external PDFs, I am using the following code, which uses the Windows default printer:

Code:
CreateObject("shell.application").namespace(0).parsename(document).invokeverb ("Print")
I will either need to be able to switch the Windows default printer at some point before the above line, or employ some other method of printing. It is important that the printing be conducted silently by the application, as it will often be printing thousands of documents a day and having someone monitor the PC is not feasible.

The Application.Printers property does not work for this purpose, as the printing is happening in the secondary application.

Thank you in advance for any assistance you can provide.

lespritdelescalier is offline   Reply With Quote
Old 05-17-2018, 07:44 AM   #2
Ranman256
Newly Registered User
 
Join Date: Apr 2015
Location: KY,USA
Posts: 2,850
Thanks: 0
Thanked 618 Times in 603 Posts
Ranman256 will become famous soon enough
Re: Can I set the Windows default printer using VBA?

the code alters printer settings
Code:
sub btnPrintDocs()
dim ptr1

ptr1 = GetDefaultPrinter ()      'save old printer
setDefaultPrinter "Printer2"     'set new printer
  docmd.openreport "myReport"    'print my report
setDefaultPrinter ptr1      'set back to old printer
end sub

paste the printer contol code into a module: modPrinters

Code:
Option Compare Database
Option Explicit

Private Declare Function ShellExecute _
Lib "shell32.dll" _
Alias "ShellExecuteA" ( _
ByVal hWnd As Long, ByVal lpszOp As String, _
ByVal lpszFile As String, _
ByVal lpszParams As String, _
ByVal lpszDir As String, _
ByVal FsShowCmd As Long _
) As Long

Private Const SE_ERR_FNF = 2&
Private Const SE_ERR_PNF = 3&
Private Const SE_ERR_ACCESSDENIED = 5&
Private Const SE_ERR_OOM = 8&
Private Const SE_ERR_DLLNOTFOUND = 32&
Private Const SE_ERR_SHARE = 26&
Private Const SE_ERR_ASSOCINCOMPLETE = 27&
Private Const SE_ERR_DDETIMEOUT = 28&
Private Const SE_ERR_DDEFAIL = 29&
Private Const SE_ERR_DDEBUSY = 30&
Private Const SE_ERR_NOASSOC = 31&
Private Const SE_ERR_BAD_FORMAT = 11&

Private Const SW_HIDE = 0
Private Const SW_SHOWNORMAL = 1

Private Const HWND_BROADCAST As Long = &HFFFF&
Private Const WM_WININICHANGE As Long = &H1A

' The following code allows one to read, and write to the WIN.INI files
' In win 2000 the printer settings are actually in the registry. However, windows
' handles this correctly
'
Private Declare Function GetProfileString Lib "kernel32" _
   Alias "GetProfileStringA" _
  (ByVal lpAppName As String, _
   ByVal lpKeyName As String, _
   ByVal lpDefault As String, _
   ByVal lpReturnedString As String, _
   ByVal nSize As Long) As Long

Private Declare Function WriteProfileString Lib "kernel32" _
   Alias "WriteProfileStringA" _
  (ByVal lpszSection As String, _
   ByVal lpszKeyName As String, _
   ByVal lpszString As String) As Long

Private Declare Function SendMessage Lib "user32" _
   Alias "SendMessageA" _
  (ByVal hWnd As Long, _
   ByVal wMsg As Long, _
   ByVal wParam As Long, _
   lparam As Any) As Long


Private Function fstrDField(mytext As String, delim As String, groupnum As Integer) As String

   ' this is a standard delimiter routine that every developer I know has.
   ' This routine has a million uses. This routine is great for splitting up
   ' data fields, or sending multiple parms to a openargs of a form
   '
   '  Parms are
   '        mytext   - a delimited string
   '        delim    - our delimiter (usually a , or / or a space)
   '        groupnum - which of the delimited values to return
   '
   
Dim startpos As Integer, endpos As Integer
Dim groupptr As Integer, chptr As Integer

chptr = 1
startpos = 0
 For groupptr = 1 To groupnum - 1
    chptr = InStr(chptr, mytext, delim)
    If chptr = 0 Then
       fstrDField = ""
       Exit Function
    Else
       chptr = chptr + 1
    End If
 Next groupptr
startpos = chptr
endpos = InStr(startpos + 1, mytext, delim)
If endpos = 0 Then
   endpos = Len(mytext) + 1
End If

fstrDField = Mid$(mytext, startpos, endpos - startpos)

End Function

Function SetDefaultPrinter(strPrinterName As String) As Boolean

   Dim strDeviceLine As String
   Dim strBuffer     As String
   Dim lngbuf        As Long
    
  ' get the full device string
  '
   strBuffer = Space(1024)
   lngbuf = GetProfileString("PrinterPorts", strPrinterName, "", strBuffer, Len(strBuffer))
  
  'Write out this new printer information in
  ' WIN.INI file for DEVICE item
  If lngbuf > 0 Then
     
     strDeviceLine = strPrinterName & "," & _
                     fstrDField(strBuffer, Chr(0), 1) & "," & _
                     fstrDField(strBuffer, Chr(0), 2)
                     
     Call WriteProfileString("windows", "Device", strDeviceLine)
     SetDefaultPrinter = True
     
     ' Below is optional, and should be done. It updates the existing windows
     ' so the "default" printer icon changes. If you don't do the below..then
     ' you will often see more than one printer as the default! The reason *not*
     ' to do the SendMessage is that many open applications will now sense the change
     ' in printer. I vote to leave it in..but your case you might not want this.
     '
     
     'Call SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, ByVal "windows")
    
  Else
     SetDefaultPrinter = False
  End If
       
End Function


Function GetDefaultPrinter() As String

   Dim strDefault    As String
   Dim lngbuf        As Long

   strDefault = String(255, Chr(0))
   lngbuf = GetProfileString("Windows", "Device", "", strDefault, Len(strDefault))
   If lngbuf > 0 Then
      GetDefaultPrinter = fstrDField(strDefault, ",", 1)
   Else
      GetDefaultPrinter = ""
   End If

End Function

Public Sub ListPrinters()

   Debug.Print GetDefaultPrinter
   Debug.Print "------------"
   Debug.Print GetPrinters
   
End Sub

Function GetPrinters() As String
   
   ' this routine returns a list of printers, separated by
   ' a ";", and thus the results are suitable for stuffing into a combo box
   
   Dim strBuffer  As String
   Dim strOnePtr  As String
   Dim intPos     As Integer
   Dim lngChars   As Long
   
   strBuffer = Space(2048)
   lngChars = GetProfileString("PrinterPorts", vbNullString, "", strBuffer, Len(strBuffer))
   
   If lngChars > 0 Then
      intPos = InStr(strBuffer, Chr(0))
     Do While intPos > 1
        strOnePtr = Left(strBuffer, intPos - 1)
        strBuffer = Mid(strBuffer, intPos + 1)
        If GetPrinters <> "" Then GetPrinters = GetPrinters & vbCrLf
        'Debug.Print strOnePtr
        GetPrinters = GetPrinters & strOnePtr
        intPos = InStr(strBuffer, Chr(0))
        
     Loop
   Else
      GetPrinters = ""
   End If
   
 End Function


Public Sub PrinterSides(ByVal pyNum As Byte)
   'acPRDPSimplex = 1
   'acPRDPHorizontal =  2
   'acPRDPVertical = 3
   Select Case pyNum
    Case ": 'nothing to do"
    Case 1
       rpt.Printer.Duplex = acPRDPSimplex
    Case 2
       rpt.Printer.Duplex = acPRDPHorizontal
    Case 3
       rpt.Printer.Duplex = acPRDPVertical
   End Select
   Printer.Duplex = pyNum
End Sub

Public Sub PrinterOrient()

'If CommonDialog1.Orientation = cdlLandscape Then
'       Printer.Orientation = cdlLandscape  '2
'Else
'       Printer.Orientation = cdlPortrait  '1
'End If
End Sub

Private Sub ProcessList(FileOp As String)
Dim varItem As Variant
Dim strFile As String
If Me.lstFiles.ItemsSelected.Count = 0 Then
   MsgBox " No file selected for " & FileOp & "ing", vbExclamation, "Process"
   Exit Sub
End If

For Each varItem In Me.lstFiles.ItemsSelected
   strFile = Me.lstFiles.Column(1, varItem)
   If ExecuteFile(strFile, FileOp) Then MsgBox "File " & FileOp & "ed"""
   Debug.Print strFile
Next
End Sub


Public Sub PrintListOfFiles()
Dim sOld As String, sFilename As String


ExecuteFile sFilename, "print"

End Sub

Public Function ExecuteFile(DocName As String, Optional FileOp As String = "open") As Boolean
Dim lRetVal As Long, sMsg As String

lRetVal = ShellExecute(0&, FileOp, DocName, vbNullString, vbNullString, IIf(FileOp = "print", SW_HIDE, SW_SHOWNORMAL))

If lRetVal <= 32 Then
    ExecuteFile = False
'There was an error
Select Case lRetVal
    Case SE_ERR_FNF
    sMsg = "File not found"
    Case SE_ERR_PNF
    sMsg = "Path not found"
    Case SE_ERR_ACCESSDENIED
    sMsg = "Access denied"
    Case SE_ERR_OOM
    sMsg = "Out of memory"
    Case SE_ERR_DLLNOTFOUND
    sMsg = "DLL not found"
    Case SE_ERR_SHARE
    sMsg = "A sharing violation occurred"
    Case SE_ERR_ASSOCINCOMPLETE
    sMsg = "Incomplete or invalid file association"
    Case SE_ERR_DDETIMEOUT
    sMsg = "DDE Time out"
    Case SE_ERR_DDEFAIL
    sMsg = "DDE transaction failed"
    Case SE_ERR_DDEBUSY
    sMsg = "DDE busy"
    Case SE_ERR_NOASSOC
    sMsg = "No association for file extension"
    Case SE_ERR_BAD_FORMAT
    sMsg = "Invalid EXE file or error in EXE image"
    Case Else
    sMsg = "Unknown error"
End Select
    MsgBox "Cannot " & FileOp & " " & DocName & vbCrLf & vbCrLf & sMsg, vbExclamation
Else
   ExecuteFile = True
End If
End Function
Ranman256 is offline   Reply With Quote
Old 05-17-2018, 10:22 AM   #3
lespritdelescalier
Newly Registered User
 
Join Date: Mar 2015
Posts: 50
Thanks: 9
Thanked 1 Time in 1 Post
lespritdelescalier is on a distinguished road
Re: Can I set the Windows default printer using VBA?

Thanks for the response, but this code doesn't seem to change the Windows default printer. It doesn't modify the win.ini file, and it doesn't throw any errors.

lespritdelescalier is offline   Reply With Quote
Old 05-17-2018, 11:14 AM   #4
The_Doc_Man
AWF VIP
 
Join Date: Feb 2001
Location: Suburban New Orleans, LA, USA
Posts: 11,585
Thanks: 41
Thanked 1,017 Times in 928 Posts
The_Doc_Man is a splendid one to behold The_Doc_Man is a splendid one to behold The_Doc_Man is a splendid one to behold The_Doc_Man is a splendid one to behold The_Doc_Man is a splendid one to behold The_Doc_Man is a splendid one to behold
Re: Can I set the Windows default printer using VBA?

Win.INI?????

What version of Windows are we talking about? Win.INI hasn't been significant since the registry was first announced and has become less of a factor ever since.

I don't know that ANY version of Windows since XP has bothered to update that file. However, specifically for Access 32-bit and 64-bit, WIN.INI is NOT used. It is strictly and only based on registry settings. WIN.INI is retained ONLY for compatibility with the few 16-bit apps that still exist and are running in a tightly restrictive virtual shell.

And no, don't ask me which ones still do that.
__________________
I'm a certified grandpa (3 times now) and proud of it.
Retired over one year and survived being home all day with the wife. She must really love me.
The_Doc_Man is offline   Reply With Quote
Old 05-17-2018, 12:06 PM   #5
lespritdelescalier
Newly Registered User
 
Join Date: Mar 2015
Posts: 50
Thanks: 9
Thanked 1 Time in 1 Post
lespritdelescalier is on a distinguished road
Re: Can I set the Windows default printer using VBA?

Quote:
Originally Posted by The_Doc_Man View Post
Win.INI?????

What version of Windows are we talking about? Win.INI hasn't been significant since the registry was first announced and has become less of a factor ever since.

I don't know that ANY version of Windows since XP has bothered to update that file. However, specifically for Access 32-bit and 64-bit, WIN.INI is NOT used. It is strictly and only based on registry settings. WIN.INI is retained ONLY for compatibility with the few 16-bit apps that still exist and are running in a tightly restrictive virtual shell.

And no, don't ask me which ones still do that.
I just mentioned that because the code in the first response mentioned editing the win.ini file. I know the default printer settings are in the registry, and have found the key. I just need to figure out how to set the value now.
lespritdelescalier is offline   Reply With Quote
Old 05-17-2018, 12:08 PM   #6
bastanu
Newly Registered User
 
Join Date: Apr 2010
Posts: 104
Thanks: 0
Thanked 32 Times in 32 Posts
bastanu is on a distinguished road
Re: Can I set the Windows default printer using VBA?

Check out these links:
https://social.msdn.microsoft.com/Fo...orum=vbgeneral

https://stackoverflow.com/questions/...sing-excel-vba
bastanu is offline   Reply With Quote
The Following User Says Thank You to bastanu For This Useful Post:
lespritdelescalier (05-17-2018)
Old 05-17-2018, 01:36 PM   #7
Cronk
Newly Registered User
 
Join Date: Jul 2013
Posts: 1,720
Thanks: 2
Thanked 362 Times in 358 Posts
Cronk will become famous soon enough
Re: Can I set the Windows default printer using VBA?

Another (shorter) way of changing the default printer has been included in previous answers on this forum


dim ptr as printer
set ptr = application.printer
set application.printer = application.printers("YourPrinterName")
<print whatever>
set application.printer = ptr 'restore default printer

Cronk is offline   Reply With Quote
Old 05-17-2018, 01:47 PM   #8
lespritdelescalier
Newly Registered User
 
Join Date: Mar 2015
Posts: 50
Thanks: 9
Thanked 1 Time in 1 Post
lespritdelescalier is on a distinguished road
Re: Can I set the Windows default printer using VBA?

Quote:
Originally Posted by Cronk View Post
Another (shorter) way of changing the default printer has been included in previous answers on this forum


dim ptr as printer
set ptr = application.printer
set application.printer = application.printers("YourPrinterName")
<print whatever>
set application.printer = ptr 'restore default printer
I mentioned in the original post that Application.Printer does not work, as the printing is happening outside of the Access application.
lespritdelescalier is offline   Reply With Quote
Old 05-17-2018, 01:55 PM   #9
lespritdelescalier
Newly Registered User
 
Join Date: Mar 2015
Posts: 50
Thanks: 9
Thanked 1 Time in 1 Post
lespritdelescalier is on a distinguished road
Re: Can I set the Windows default printer using VBA?

The first link was the solution that was posted in the first response.

The second one did the trick! Thank you!
lespritdelescalier is offline   Reply With Quote
Old 05-17-2018, 02:01 PM   #10
bastanu
Newly Registered User
 
Join Date: Apr 2010
Posts: 104
Thanks: 0
Thanked 32 Times in 32 Posts
bastanu is on a distinguished road
Re: Can I set the Windows default printer using VBA?

You're very welcome!

Cheers,
Vlad

bastanu is offline   Reply With Quote
Reply

Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Question changing default windows printer from code eatraas General 9 01-27-2009 03:58 PM
Change Default Printer in Windows/Office Xp (using DefaultPRT.ZIP) karmahum General 4 09-13-2005 09:43 AM
Specific Printer and Windows XP fails John Hazen Reports 2 09-05-2002 10:48 AM
What is the name of the default printer? shacket Modules & VBA 6 08-08-2001 07:48 AM
Printer fonts and Windows NT PrPu Reports 0 10-21-1999 01:03 AM




All times are GMT -8. The time now is 04:26 PM.


Microsoft Access Help
General
Tables
Queries
Forms
Reports
Macros
Modules & VBA
Theory & Practice
Access FAQs
Code Repository
Sample Databases
Video Tutorials

Sponsored Links

How to advertise

Media Kit


Powered by vBulletin®
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
(c) copyright 2017 Access World