Hello,
I'm trying to print 1 or more pdf files from within Access 2000 vba. Users will have Acrobat Reader installed. I've found that the following command line works:
AcroRd32.exe /t <FileName> <PrinterName>
I can run this from Start/Run menu. I'm trying to put this feature into my vba code. What I have so far is this:
Public Function PrintPdf() As Long
Dim lRet As Long
Dim sFile As String
Dim sParms As String
This seems to work, but leaves a copy of Acrobat Reader minimized in the taskbar. Is there any way to remove this when I'm done with it? I do have what seems to be a task id returned from the function. Is there an api method to kill that task, or would that simply add more time to the process (I will be looping through many records, and printing a pdf file for each one)? Maybe save the initial task id returned, and kill it once at the end, assuming the same task id is used in each ShellExecute iteration?
In any case, 1: How can I kill the task created, and 2: Should I be using ShellExecuteEx instead?
Thanks to all for your suggestions. I finally solved the problem by using "print" instead of open, and the pdf document path as the item to print, rather than "open" and the Acrobat Reader program as the argument. This of course relies on the association set up when I installed Acrobat Reader. Using "print", I don't even have to close the application, as it closes by itself.
There were tradeoffs of course. When I used the "open" version with the Acrobat Reader exe, I could specify which printer to send the document to in the command line options for the Reader program. This was necessary, as the report printer is not necessarily the default printer. With the "print" version, I first have to save the current default printer, then if the report printer is not the default printer, set the default to the report printer, then print the pdf file, then restore the original default printer. This sounds like a lot of "stuff" to do, but I found some code examples on msdn which worked like a charm. I can supply the routines if necessary, just reply to the thread.
I'm doing VBA programming for an Access 2000 Database and I needed to do exactly the same thing as you. I'm curious to get more detail on your "ShellExecute" command or if a list of command switches for the AcroRd32.exe is available.
The routine shown at the beginning of this thread should work properly to print the pdf document(s), but as mentioned, it leaves the Acrobat Reader minimized in the taskbar, and I haven't found a way to remove it programatically.
However, as mentioned, I've written routines to use ShellExecute with the "Print" option, and the Acrobat Reader closes automatically.
The only "gotcha" is that it will only print to the user's default printer, as you can't specify a particular printer using the "print" option.
I got around that by writing a routine to save the default printer name, then change the default printer to the desired printer, then print the files, then restore the original default printer. This is done in VB6 rather than Access, but should work there too. Attached is a Printers.cls file, which contains the code for the printer manipulation. Just insert the class into your project & use the DefaultPrinter properties to save and restore the active printer. It should work on Win9x and NT/2000. Hasn't been tested on later versions.
I did the ShellExecute like this:
PHP Code:
'Shell out to print pdf file.
sSendFile = mSourceForm.txtReportPath & "\" & AddressNo & ".pdf"
lResult = ShellExecute(mSourceForm.hwnd, "print", sSendFile, _
vbNullString, "", 0)
You can build the path\filename as needed. You have to search Adobe's site to get the command line switches for Acrobat Reader, but using the "print" option with ShellExecute eliminates the need for that.
How would one send the WM_Close event in this scenario? How do you identify the window when you cannot know the exact window title b/c the user could have Acrobat Standard or Acrobat Professional or Reader installed.
Using VS 6 Enterprise w/ SP5 & Windows 2000 Professional
I didn't find it at first, but then I refreshed Spy ++ and found it under the name I have been using, which is "Adobe Acrobat Standard". It is also using the class I have been using, which is "AdobeAcrobat".
The refresh thing is obviously just a Spy ++ deal. I am using a project to identify the window, which is:
Code:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Const SW_SHOWNORMAL = 1
Const WM_CLOSE = &H10
Const gcClassnameMSWord = "OpusApp"
Const gcClassnameMSExcel = "XLMAIN"
Const gcClassnameMSIExplorer = "IEFrame"
Const gcClassnameMSVBasic = "wndclass_desked_gsk"
Const gcClassnameNotePad = "Notepad"
Const gcClassnameMyVBApp = "ThunderForm"
Private Sub Command1_Click()
'KPD-Team 1998
'URL: http://www.allapi.net/
'E-Mail: KPDTeam@Allapi.net
Dim WinWnd As Long, Ret As String, RetVal As Long, lpClassName As String
'Ask for a Window title
Ret = InputBox("Enter the exact window title:" + Chr$(13) + Chr$(10) + "Note: must be an exact match")
'Search the window
WinWnd = FindWindow(vbNullString, Ret)
If WinWnd = 0 Then MsgBox "Couldn't find the window ...": Exit Sub
'Show the window
ShowWindow WinWnd, SW_SHOWNORMAL
'Create a buffer
lpClassName = Space(256)
'retrieve the class name
RetVal = GetClassName(WinWnd, lpClassName, 256)
'Show the classname
MsgBox "Classname: " + Left$(lpClassName, RetVal)
'Post a message to the window to close itself
PostMessage WinWnd, WM_CLOSE, 0&, 0&
End Sub
Using VS 6 Enterprise w/ SP5 & Windows 2000 Professional
The code above works, but if it is integrated into my current project for testing, then it will not find the window. Strange... It can't find the window when adding this code:
lRet = ShellExecute(0, "PRINT", "C:\windows\temp\temp.pdf", vbNullString, "", SW_SHOWMINNOACTIVE) ' Execute the print API command
Using VS 6 Enterprise w/ SP5 & Windows 2000 Professional