Need to Print Embedded PDFs

kmackie1

New Member
Joined
Jul 30, 2013
Messages
14
Here is my code so far:

Public Sub PrintPDFFiles()​
Const ADOBEPATH As String = "C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe"​
Const FILE_PATH As String = "C:\Users\kmackie\Desktop\Sample\Test"​
Const FILE_EXT As String = "PDF"​

Dim fso, fld, file​

Set fso = CreateObject("Scripting.FileSystemObject")​
Set fld = fso.GetFolder(FILE_PATH)​

For Each file In fld.Files​
If UCase(Right(file.Name, 3)) = FILE_EXT Then​
Shell """" & ADOBEPATH & """/n /t """ & file.Path & """"​
End If​
Next​
End Sub

This code works perfectly for what I am trying to do... except for one thing:

I want to open and print PDFs that are already embedded into my worksheet. I can use the code to open the embedded PDF files:


ActiveSheet.Shapes("Object 1").OLEFormat.Activate​

How on earth can I just open these files and print them. I've spent so long trying to figure this out. If you can't tell... I'm a bit of a newbie.

End result:
I want to be able to click a button, have it open the embedded pdf file in Adobe Reader, Print it, Close Adobe Reader.
I will name my first born son to the man that can solve this problem for me!
 
Re: Need to Print Embedded PDFs - PLEASE HELP :(

What could it be? Possibly security setting or something?
 
Upvote 0

Excel Facts

How to show all formulas in Excel?
Press Ctrl+` to show all formulas. Press it again to toggle back to numbers. The grave accent is often under the tilde on US keyboards.
Re: Need to Print Embedded PDFs - PLEASE HELP :(

I doubt it's a security issue since I have ran many macros before, what if we designated it to a certain directory on c:\ say C:\test instead of active workbook path.
 
Upvote 0
Re: Need to Print Embedded PDFs - PLEASE HELP :(

That was the first thing I tried. I just get the same error with a different file path.
 
Upvote 0
Re: Need to Print Embedded PDFs - PLEASE HELP :(

Thank to all for the testing!

I've found that previous versions of code work on Win XP 32 bit SP3 (tested on Excel 2003/2007), but does not work on Win7 64 bit (tested on Excel 2003, Excel 2013 64bit).
The critical line of the code is CreateObject("Shell.Application").Namespace(p).Self.InvokeVerb "Paste"

The new version of the code has passed the same testing successfully.
Seems that running of AcroRd32.exe by command line (it comes from the original post) is not good idea because Adobe Reader need to be closed manually.
But it works at least. Try:
Rich (BB code):
Option Explicit
#If VBA7 Then
  Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hWnd As LongPtr) As Long
  Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
  Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As LongPtr
  Private Declare PtrSafe Function GlobalSize Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr
  Private Declare PtrSafe Function GlobalLock Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr
  Private Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As LongPtr) As Long
  Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
  Dim hWnd As LongPtr, Size As LongPtr, Ptr As LongPtr
#Else
  Private Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long
  Private Declare Function CloseClipboard Lib "user32" () As Long
  Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
  Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
  Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
  Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
  Dim hWnd As Long, Size As Long, Ptr As Long
#End If
 
Sub PrintEmbeddedPDFs_02()
' ZVI:2013-08-01 http://www.mrexcel.com/forum/excel-questions/717204-need-print-embedded-pdfs-please-help.html
 
  Dim a() As Byte, b() As Byte, i As Long, j As Long, k As Long, n As Long
  Dim FN As Integer, f As String, p As Variant, obj As OLEObject
 
  p = ActiveWorkbook.Path
 
  ' Check OleObjects presence
  With ActiveSheet.OLEObjects
    If .Count = 0 Then
      MsgBox "Embedded PDF not found", vbExclamation, "Nothing to print"
      Exit Sub
    End If
  End With
 
  On Error GoTo exit_
 
  ' Print all PDFs embedded into the active sheet
  For Each obj In ActiveSheet.OLEObjects
    i = 0:  hWnd = 0: Size = 0: Ptr = 0
    If obj.progID Like "Acro*.Document*" And obj.OLEType = 1 Then
      obj.Copy
      If OpenClipboard(0) Then
        hWnd = GetClipboardData(49156)
        If hWnd Then Size = GlobalSize(hWnd)
        If Size Then Ptr = GlobalLock(hWnd)
        If Ptr Then
          ReDim a(1 To CLng(Size))
          CopyMemory a(1), ByVal Ptr, Size
          Call GlobalUnlock(hWnd)
          i = InStrB(a, StrConv("%PDF", vbFromUnicode))
          If i Then
            j = InStrB(i, a, StrConv("%%EOF", vbFromUnicode)) - i + 7
            ReDim b(1 To j)
            For k = 1 To j
              b(k) = a(i + k - 1)
            Next
            Ptr = 0
          End If
        End If
        Application.CutCopyMode = False
        CloseClipboard
        If i Then
          n = n + 1
          f = p & "\_printed_.pdf"
          If Len(Dir(f)) Then Kill f
          FN = FreeFile
          Open f For Binary As #FN
          Put #FN, , b
          Close #FN
          CreateObject("wscript.shell").Run "AcroRd32.exe /N /T """ & f & """", , True
          Kill f
        End If
      Else
        Application.CutCopyMode = False
      End If
    End If
  Next
 
  ' Inform how many Embedded PDFs were printed
  MsgBox "Amount of the printed PDFs: " & n, vbInformation, "PrintEmbeddedPDFs"
 
exit_:
 
  If Err Then MsgBox Err.Description, vbCritical, "Error #" & Err.Number
 
End Sub
 
Last edited:
Upvote 0
Re: Need to Print Embedded PDFs - PLEASE HELP :(

Hi All. The code only works for one active sheet with embedded PDFs (unless I've not set it up right...)
Is it possible to print the entire workbook which contains some normal worksheets, some worksheets containing embedded PDFs, all in one go to the printer or PDF (for archival reasons)?
Many thanks.
 
Upvote 0
Re: Need to Print Embedded PDFs - PLEASE HELP :(

Is it possible to print the entire workbook which contains some normal worksheets, some worksheets containing embedded PDFs, all in one go to the printer or PDF (for archival reasons)?
Hi and welcome to the MrExcel board!

In the code of PrintEmbeddedPDFs_02 comment the line MsgBox "Amount of the printed PDFs: " …
And then use one of these subroutines:
Rich (BB code):
Sub PrintSheetsAndEmbeddedPdfs()
  PrintSheets
  PrintEmbeddedPdfs
End Sub
 
Sub PrintSheets()
  Dim sh As Worksheet
  For Each sh In Worksheets
    With sh.UsedRange
      If .Cells.Count > 1 Or Len(.Cells(1)) Then
        sh.PrintOut
      End If
    End With
  Next
End Sub
 
Sub PrintEmbeddedPdfs()
  Dim sh As Worksheet, obj As OLEObject
  For Each sh In Worksheets
    For Each obj In sh.OLEObjects
      If obj.progID Like "Acro*.Document*" And obj.OLEType = 1 Then
        sh.Activate
        Call PrintEmbeddedPDFs_02
        Exit For
      End If
    Next
  Next
End Sub
 
Last edited:
Upvote 0
Re: Need to Print Embedded PDFs - PLEASE HELP :(

Hi ZVI

Many thanks for your prompt response.

I did as you asked, sadly, I ended up with errors, and four separate macros unwilling to work together!

I'm a VBA newbie, and much to my disappointment, it is not quite as straight forward as I had hoped!

The original code for the previous person works perfectly, just not the additional subroutines provided to solve my problem.

Your help would be vastly appreciated.

Kind regards
 
Last edited by a moderator:
Upvote 0
Re: Need to Print Embedded PDFs - PLEASE HELP :(

Well, here is the detailed instruction:

1. Select this code and hit Ctrl-C to copy it into clipboard.
Rich (BB code):
Option Explicit
#If VBA7 Then
  Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hWnd As LongPtr) As Long
  Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
  Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As LongPtr
  Private Declare PtrSafe Function GlobalSize Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr
  Private Declare PtrSafe Function GlobalLock Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr
  Private Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As LongPtr) As Long
  Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
  Dim hWnd As LongPtr, Size As LongPtr, Ptr As LongPtr
#Else
  Private Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long
  Private Declare Function CloseClipboard Lib "user32" () As Long
  Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
  Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
  Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
  Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
  Dim hWnd As Long, Size As Long, Ptr As Long
#End If
 
Sub PrintEmbeddedPDFs_02()
' ZVI:2013-08-01 http://www.mrexcel.com/forum/excel-questions/717204-need-print-embedded-pdfs-please-help.html
 
  Dim a() As Byte, b() As Byte, i As Long, j As Long, k As Long, n As Long
  Dim FN As Integer, f As String, p As Variant, obj As OLEObject
 
  p = ActiveWorkbook.Path
 
  ' Check OleObjects presence
  With ActiveSheet.OLEObjects
    If .Count = 0 Then
      MsgBox "Embedded PDF not found", vbExclamation, "Nothing to print"
      Exit Sub
    End If
  End With
 
  On Error GoTo exit_
 
  ' Print all PDFs embedded into the active sheet
  For Each obj In ActiveSheet.OLEObjects
    i = 0:  hWnd = 0: Size = 0: Ptr = 0
    If obj.progID Like "Acro*.Document*" And obj.OLEType = 1 Then
      obj.Copy
      If OpenClipboard(0) Then
        hWnd = GetClipboardData(49156)
        If hWnd Then Size = GlobalSize(hWnd)
        If Size Then Ptr = GlobalLock(hWnd)
        If Ptr Then
          ReDim a(1 To CLng(Size))
          CopyMemory a(1), ByVal Ptr, Size
          Call GlobalUnlock(hWnd)
          i = InStrB(a, StrConv("%PDF", vbFromUnicode))
          If i Then
            j = InStrB(i, a, StrConv("%%EOF", vbFromUnicode)) - i + 7
            ReDim b(1 To j)
            For k = 1 To j
              b(k) = a(i + k - 1)
            Next
            Ptr = 0
          End If
        End If
        Application.CutCopyMode = False
        CloseClipboard
        If i Then
          n = n + 1
          f = p & "\_printed_.pdf"
          If Len(Dir(f)) Then Kill f
          FN = FreeFile
          Open f For Binary As #FN
          Put #FN, , b
          Close #FN
          CreateObject("wscript.shell").Run "AcroRd32.exe /N /T """ & f & """", , True
          Kill f
        End If
      Else
        Application.CutCopyMode = False
      End If
    End If
  Next
 
  ' Inform how many Embedded PDFs were printed
  'MsgBox "Amount of the printed PDFs: " & n, vbInformation, "PrintEmbeddedPDFs"
 
exit_:
 
  If Err Then MsgBox Err.Description, vbCritical, "Error #" & Err.Number
 
End Sub
 
Sub PrintSheetsAndEmbeddedPdfs()
  PrintSheets
  PrintEmbeddedPdfs
End Sub
 
Sub PrintSheets()
  Dim sh As Worksheet
  For Each sh In Worksheets
    With sh.UsedRange
      If .Cells.Count > 1 Or Len(.Cells(1)) Then
        'sh.PrintOut
      End If
    End With
  Next
End Sub
 
Sub PrintEmbeddedPdfs()
  Dim sh As Worksheet, obj As OLEObject
  For Each sh In Worksheets
    For Each obj In sh.OLEObjects
      If obj.progID Like "Acro*.Document*" And obj.OLEType = 1 Then
        sh.Activate
        Call PrintEmbeddedPDFs_02
        Exit For
      End If
    Next
  Next
End Sub

2. In Excel press Alt-F11 to open VBE and choose menu Insert – Module

3. Paste the code from the clipboard via Ctrl-V into the created module

4. Press Ctrl-S to save workbook and hit Alt-Q to leave VBE

5. Activate workbook to be printed, press Alt-F8 and run macro PrintSheetsAndEmbeddedPdfs by double click on it.

If error will happen then post its description.
For debugging learn the recommendations of this link: Debugging VBA Code
 
Upvote 0
Re: Need to Print Embedded PDFs - PLEASE HELP :(

No error occurred. However, it only prints those worksheets with the embedded PDFs.
For example, I have ten worksheets, two of them only contained embedded PDFs.

The code above prints the PDFs separately, with no eight worksheets printed.

I am hoping to have one file PDF of all ten sheets including these two embedded PDFs.

I realise that this may not work due to limitations of PDFs.
 
Last edited by a moderator:
Upvote 0

Forum statistics

Threads
1,223,666
Messages
6,173,672
Members
452,527
Latest member
ineedexcelhelptoday

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top