Adobe Acrobat and VBA – An Introduction

Here is another topic that comes up every now and then: How can I “talk” to Adobe Acrobat from e.g. MS Excel via VBA? I’ll try to give an introduction into that subject in this document. I will only discuss the basics, but I’m open for suggestions about what part to discuss next. So keep the comments coming.

More after the jump…

The Warning Upfront

Before we get too deep into this, let me say this: I am not a VBA expert. I do not program in VBA or VB. All I know about VB is from googling a few things and looking at sample code. It does help that I’ve programmed in many (make that a capital ‘M’ Many) programming languages, and at the end most of them share enough characteristics that once you know one, you know all of them… But still, don’t consider my VB programs to be at an expert level. I only use the samples to demonstrate general methods. It’s up to you to fill in all the missing details (e.g. exception handling).

Resources

All this information is available in one form or another in Adobe’s SDK documentation. Before you read any further, click on this link and take a look at what they have available.

There are (at least) two documents that are required reading if you want to use Acrobat from within your VBA code:

If you want to utilize the VB/JavaScript bridge, you also should read the JavaScript related documents:

All of these documents can also be accessed via Adobe’s online documentation system. In order to find the documents I’ve listed above, you need to expand the tree on the left side of the window for the “JavaScript” and “Acrobat Interapplication Communication” nodes.

There is always more than one way…

There are two ways your program can interact with Acrobat. One is more direct than the other, but both require the same mechanism to get things started…
You can either use the “normal” IAC (Inter Application Communication) interface, which is basically a COM object that your program loads and uses to communicate with Acrobat, or you can use the VB/JavaScript bridge, which allows access to Acrobat’s JavaScript DOM. The latter case still requires that your program first establishes a connection to Acrobat via IAC.

Let’s get the party started

As I mentioned before, regardless of how we want to remote control Adobe Acrobat from VB, we need to establish a connection to its COM object (or OLE server). You may have noticed that I always talk about “Adobe Acrobat”, and not the “Adobe Reader”. What I’m presenting here is valid for the Adobe Acrobat, Reader only supports a small subset of features. To learn more about what the differences are, see the IAC Developer Guide. For the purpose of this document, I will use MS Excel 2007 and Adobe Acrobat 9 Pro. As long as you have a version of Acrobat that is compatible with the version of VBA that you are using, you should be able to follow along without any problems.

Preparing MS Excel 2007

When you install Office 2007 or Excel 2007, make sure that you select the Visual Basic Editor component, otherwise you will not be able to write VBA code. This is different than all the versions up to 2007. Once installed, you need to add the “Developer” tab to the ribbon. This is done on the Excel Options dialog, under the Popular category:

excel_options.png

Once that is done, you should see the “Developer” tab as part of the ribbon:

developer_tab.png

Our First Button

Open a new document and select the Developer tab. Then go to the Insert control and place a button on your document. This will pop up the “Assign Macro” dialog, just click on the “Add” button, which will bring up the VBA editor. Nothing special so far.

Before we can use any of Acrobat’s functionality, we need to make sure that VBA knows about the Acrobat objects. On the VBA dialog, select the “Tools>References” menu item. On the dialog that pops up, make sure that the TLB for your version of Acrobat is selected. This is what it looks like for my system:

references.png

Now we can add code that references the Acrobat objects to our button handler. Of course, before we do that, we need to decide what our button is actually supposed to trigger. Let’s start with something simple – let’s combine two PDF documents and save the result as a new document.

I’ll present the whole program first, and will then explain the different parts.

Sub Button1_Click()

    Dim AcroApp As Acrobat.CAcroApp

    Dim Part1Document As Acrobat.CAcroPDDoc
    Dim Part2Document As Acrobat.CAcroPDDoc

    Dim numPages As Integer

    Set AcroApp = CreateObject("AcroExch.App")

    Set Part1Document = CreateObject("AcroExch.PDDoc")
    Set Part2Document = CreateObject("AcroExch.PDDoc")

    Part1Document.Open ("C:\temp\Part1.pdf")
    Part2Document.Open ("C:\temp\Part2.pdf")

    ' Insert the pages of Part2 after the end of Part1
    numPages = Part1Document.GetNumPages()

    If Part1Document.InsertPages(numPages - 1, Part2Document,
		0, Part2Document.GetNumPages(), True) = False Then
        MsgBox "Cannot insert pages"
    End If

    If Part1Document.Save(PDSaveFull, "C:\temp\MergedFile.pdf") = False Then
        MsgBox "Cannot save the modified document"
    End If

    Part1Document.Close
    Part2Document.Close

    AcroApp.Exit
    Set AcroApp = Nothing
    Set Part1Document = Nothing
    Set Part2Document = Nothing

    MsgBox "Done"

End Sub

Save the document. When prompted for a filename and a filetype, select the type of “Excel Macro-Enabled Workbook” – otherwise the program you just added will get stripped out of the file.

Make sure that there are two files named Part1.pdf and Part2.pdf in the c:\temp directory.

Click the button and enjoy…

After the program is done, there will be a new file C:\Temp\MergedFile.pdf on your disk. Open that in Acrobat, and verify that it indeed contains the results of concatenating the two source files.

So, how does it work?

The whole program is in a button handler.

Sub Button1_Click()
...
End Sub

Let’s now look at the different parts of that handler.

At first, we need to setup a bunch of objects that we will use further down the code:

    Dim AcroApp As Acrobat.CAcroApp
    Dim Part1Document As Acrobat.CAcroPDDoc
    Dim Part2Document As Acrobat.CAcroPDDoc
    Dim numPages As Integer

The first statement sets up an object of type Acrobat.CAcroApp – this reflects the whole Acrobat application. If you look through the documentation, you’ll see that there are a number of things that can be done on the application level (e.g. minimizing or maximizing the window, executing menu items, retrieve preference settings, closing the application, …). The next two lines declare two objects of type Acrobat.CAcroPDDoc – these reflect the two documents that we need to open.

There are two different document types available in the OLE part of IAC: The AVDoc and the PDDoc. An AVDoc is one that gets opened in Acrobat’s user interface, the user can navigate through its pages, and do anything that you can do with a PDF document when you double-click on it to open it in Acrobat. A PDDoc on the other hand gets opened in the background. Acrobat still has access to it, and can manipulate it, but the user does not see it. This is useful if a program should quietly do its work without showing the user what’s going on.

Every AVDoc has a PDDoc behind the scenes, and that object can be retrieved via the AVDoc.GetPDDoc method. A PDDoc only has an associated AVDoc if it is actually shown in Acrobat, however, we cannot retrieve that AVDoc object from within the PDDoc. This sounds complicated, but once you get more familiar with how these things are used, it becomes second nature.

We also need an integer object to store the number of pages in the first document.

    Set AcroApp = CreateObject("AcroExch.App")
    Set Part1Document = CreateObject("AcroExch.PDDoc")
    Set Part2Document = CreateObject("AcroExch.PDDoc")

In the next step, we initialize the three Acrobat related objects. Nothing special here.

    Part1Document.Open ("C:\temp\Part1.pdf")
    Part2Document.Open ("C:\temp\Part2.pdf")

Now that our objects are initialized, we can use the methods to do something with the objects. In order to merge files, we need access to both the source files, so we have to call the Open() method on both these objects. The key to success is to specify the whole path name, directory and filename.

    numPages = Part1Document.GetNumPages()

The method InsertPages requires that we specify after which page to insert the second document. Because we want to insert the pages after the last page of the first document, we need to find out how many pages we have in that document. The GetNumPages() method does return that information.

This is also, where it becomes a bit tricky: Acrobat starts to count the pages in a PDF document at zero. So, if we want to insert the pages after the first page in the document, we need to insert after page number zero. If we want to insert after the second page, we need to insert after page number one… Because we want to insert the pages after the last page of the first document, we need to insert the pages after (lastPage-1). Again, this is a bit confusing, but after a while it gets easier.

    If Part1Document.InsertPages(numPages - 1, Part2Document,
		0, Part2Document.GetNumPages(), True) = False Then
        MsgBox "Cannot insert pages"
    End If

This is where Acrobat does all its work. The parameters of the InsertPages method are described in the Interapplication Communication API Reference document: InsertPages

Now we only have to save the document, do some cleanup and exit our program:

    If Part1Document.Save(PDSaveFull, "C:\temp\MergedFile.pdf") = False Then
        MsgBox "Cannot save the modified document"
    End If

    Part1Document.Close
    Part2Document.Close

    AcroApp.Exit
    Set AcroApp = Nothing
    Set Part1Document = Nothing
    Set Part2Document = Nothing

    MsgBox "Done"

With these steps, and the information in the API documentation, you should be able to write simple programs.

I’ll document the VB/JavaScript bridge in my next posting.

This entry was posted in Acrobat, PDF and tagged , , , , , . Bookmark the permalink.

109 Responses to Adobe Acrobat and VBA – An Introduction

  1. Pingback: Karl Heinz Kremer’s Ramblings » Acrobat, JavaScript and VB walk into a bar…

  2. Arne Grunert says:

    Hi, I am using Vista x64 and Office 2007.

    I get an errror in this part of the code:

    If Part1Document.InsertPages(numPages – 1, Part2Document,
    0, Part2Document.GetNumPages(), True) = False Then

    Any idea?

  3. Jens says:

    Perfect! This was the part of code I was looking for.
    My code added the PDF’s in the wrong order.

    Thanks!

  4. bla says:

    Is supposed to be all 1 line, not 2.

  5. khk says:

    I don’t think that makes a difference – the interpreter will put the line back together.

  6. Vishy says:

    I don;t find acrobat in references. I only find Acrobat Type library.

  7. khk says:

    What version of Acrobat are you using?

  8. Mike says:

    I have tried to use the above code in an office 2003 macro, with Adobe 8 with no success.

    I had to change the open statements to openAVDoc statements otherwise excel crashes when trying to open the file. After this, the number of pages is not calculated as the result for numPages is still zero eventhough the doc has 32. This could be why the InsertPages line fails, but I cant seem to get the correct information in order to complete this step.

    In addition, can you simply open an excel or word file in acrobat and have the conversion take place at that time?

  9. MeAndI says:

    Thanks for this great intro,

    this even works with Excel2000 from VBA (Vb6…) if you select Acrobat.tlb (“Acrobat 7.0 Type Lib..” / “Acrobat”).
    Now, reading / searching for Text patterns in a pdf via script shouldn’t be that great problem anymore, or should it? ;D

  10. khk says:

    Define “great problem” 🙂 It’s not easy to get text information out of a PDF document. You can use the JavaScript bridge and use the word finder in JavaScript to get access to the text.

  11. heidi says:

    Hello, thank you for this code very useful. i would like to add page number at the bottom of my PDF created. Do you know how can i do this in VBA?

  12. khk says:

    You can add page numbers via the VB2JS bridge by adding a form field or a text box and filling it with the page number. As the last step you can then flatten the page to “burn in” the interactive content you just added in order to convert it to real PDF content. Let me know if you need more detailed instructions.

  13. reg says:

    Thank you. It took me all day to find this information. It looks like this will only work if you have full Acrobat. What happens if I write code and the people using my code only have Acrobat Reader?

  14. khk says:

    Adobe Reader supports only a small number of functions. You need to be familiar with Adobe’s API documentation to determine what’s available in Reader vs. the full Acrobat. If somebody only has Reader installed, your program will not work, because the functions available to Reader are in a separate type library.

  15. Gautier thomas says:

    Thanks a lot for this page…and its author
    It was really helpful 🙂

  16. Norman Dolph says:

    K H – !
    You are VALUABLE!

    and lucid as well
    thanks,

  17. Greg says:

    This is my first time visiting your blog, and I want to commend you on writing a great article. This is a good foundation for manipulating PDF’s via MS Office, and I learned a lot reading this. I hope you write about this more…

  18. Thanks for the code.Working great.

  19. Carlos Alberto says:

    If Part1.pdf has only one page, and Part2.pdf has only a page, too, apears the message “Cannot insert pages”. I appreciate your help to resolve that situation.

  20. Roger says:

    This has is great, it really fast tracked me into the world of Adobe Acrobat remote controlled by VBA. Many thanks! Rather than insert my focus is to replace some text in the PDF. Any suggestions?

  21. This is exactly what I needed to satisfy a request from a customer. I’m now modifying your procedure so that it can accept an array of . pdf filenames.

    If you’d like a copy of the modified procedure, just let me know.

  22. Brenda says:

    Is there any way to have the filenames appear as bookmarks?

  23. Samet says:

    Wow. that is very great thanks KH!

  24. jaime granado says:

    is there code where we can take specific pages from pdf 1 to merge into pdf 2 or delete all pages in pdf1 except specific pages? Also I would like to highlight certain text from pdf1 in the new merged file.
    Thanks,
    Jaime

  25. prat says:

    i have one pdf file having 2000 pages but i need to find some data in pdf get some data on the basis of searching and saved those data in excel. is this possible in VBA?. can you give me VBA code for that.

    Thanks,
    Prat

  26. Steve says:

    How could I combine 3 or more pdf files using this VBA code?

  27. Wayne Gunn says:

    Ive been trying to find a way to manipulate the menu system in acrobat to no avail. The menu item of interest is the ‘View/Page Display/Single Page Continuous’ menu, which can be either checked or unchecked. To get right into it, what I need to do is:
    1. Obtain a reference to the menu item
    2. Get its checked/unchecked status
    3. Check it if needed

    That seems straightforward but it’s been hell trying to get a straight answer from the acrobat forum, the one guy that keeps responding seems to have a vested interest in insisting that I go about the task his many other ways, none of which works.

    Is it possible to do this? Version 9
    Thanks

  28. Wayne Gunn says:

    Additionally, I am using VBA

  29. Larry says:

    Hi I am using VB Excell 2007, and the API setinfo member of AcroExch.PDDoc to set a Coustom property in a PDF as follows

    retval = Part1Document.SetInfo(“DocSummary”, CommentStg)

    However API is limiting the string value to 256 characters. I have verified that the len of CommentStg is 456 char however only the first 256 are sent to the PDF.
    Any Ideas why? I also verified that a custom property value can be greater than 256 chars. So I asume it is something in the API that has a limit. If so is thier a way around it?

    Thanks

  30. Karl Heinz Kremer says:

    Wayne, not every menu is exposed via the API. You can use the JavaScript method App.listMenuItems() to find out what menu items are actually exposed. You will then need to map the item you are interested in to the list of items you are getting. In this case, you want the “View” menu – the good news is that it’s actually available via the API. The Page Display options are “SinglePage”, “OneColumn”, “TwoPages”, “TwoColumns”. The problem however is that you cannot get the “Checked” status for these menu items. You can in a plug-in, but not from JavaScript or VBA. You can check them, but you cannot find out if the are checked or not.

  31. Karl Heinz Kremer says:

    Larry, I assume that this is a limit of the API. Because I am not working for Adobe, I don’t have any exposure to the reason why that is. When you check the API documentation for “GetInfo”, you’ll see that a maximum of 512 bytes are returned by that call. I assume that we are dealing with Unicode characters, and every character uses two bytes. That would give you those 256 characters. You might be able to go through the JavaScript bridge and use the JavaScript method to get access to the custom property.

  32. Shiva Prasad says:

    Hi,

    I have a problem with pdf file which is sometimes text running outside the set margins. Now, i need to find out these instances in the 600 pages pdf file. I hope this is possible to identify these issues by overlapping all pages of the document to one page so that we will get to know if there are any such instances in the file.

    Can someone please write code for me?

    Regards,
    Shiva

  33. Karl Heinz Kremer says:

    Shiva, I don’t think anybody will write code for you for free to do that. If you are interested in a professional solution, feel free to get in touch with me via email. That’s what I do for a living 🙂

  34. Niek says:

    Hello Karl Heinz,

    First of all, thanks for this post. I notice that it’s quite old, but I recently found it and it’s been a great help!
    I have written a small app using parts of your example. I’m working with Windows 7, Excel 2013 and Acrobat XI Pro. On this computer it’s working like a charm. However, on another computer with Windows 8, Office 365 (the download version, not the cloud version) and Acrobat XI pro, I get “cannot insert pages”. Strange thing is other elements of the link with Acrobat are working fine, for example part1Document.open, part1document.save, jso.addWatermarkFromText(…). Any ideas?

    Best regards,
    Niek

  35. Karl Heinz Kremer says:

    I don’t have access to Office 365, so I cannot test your setup. You could try to run the VBA code as pure VB (or VBScript) outside of Office 365 to see if the problem is caused by Office, or something else. Here is some sample code that shows how you can use VBScript: http://khkonsulting.com/2013/01/prevent-the-save-dialog-when-printing-to-the-adobe-pdf-printer/

  36. Niek says:

    Hi,

    Thanks for the reply! Turns out the problem was with the number of pages: I had set the first argument of InsertPages to 2 and the Part1Document on the second computer only had 1 page… kind of a silly mistake I guess. Thanks again for this post and for your help. IThe vbscript example is useful as well by the way!

    Niek

  37. Dash says:

    Hi,
    I used your code and it did what I want, but for two files as I am using your code as a sub and calling it in another sub.. I gave it two input for Part1Document and Part2Document.. My question is what if I wanted to make the input dynamic and add as many pdfs I want to without having to open each one by hard coding it?
    Thanks

  38. Karl Heinz Kremer says:

    Dash – that’s just regular VBA: Just create loop, find out what files you need to combine and call you function with the two filenames. Again, that’s just a VBA problem and has nothing to do with Acrobat or PDF. If you don’t know how to create a function with arguments and call that function from within a loop, get a good VBA introduction that teaches the function concept.

  39. Will says:

    Hello,

    I’m trying to write VBA code to merge a few hundred PDFs into one as it loops through all the sheets (containing hyperlinks to PDFs) in a workbook. Your code was a great help to get me started but my code is extremely slow merging just two files at a time. Is there a way to merge a huge amount of PDF files faster?

    I have this vision in my head of a pyramid structure. On the first level, file1 merge with file2, file3 merge with file4, etc. Then on the second level, the result of the merger of file1 & file2 merge with the result from the merge of file3 & file4, and so on …..

    Thanks for any advice.

  40. Karl Heinz Kremer says:

    Will,

    you can certainly do it this way. In general, automating Acrobat via VBA is fairly slow. Acrobat is mainly an application that is designed for a user to sit in front of the screen, pushing buttons. For a server like environment (e.g. processing a few hundred files fast), I would use a standalone application using a PDF library or toolkit that was designed for this use.

  41. Will says:

    Karl,

    Thanks for the quick reply.
    Can you recommend “a standalone application using a PDF library or toolkit that was designed for this use”?
    I value your expert advice as it will save me days (and probably some cash) to trial & error different things to find a solution.

    Thanks for your time.

  42. Karl Heinz Kremer says:

    Will, I would write an application based on ABCPdf for anything that needs to run on Windows. For other environments, I might use iText.

  43. Phan Thong says:

    Hi Karl,
    Could you please advise me my concern?
    I have a pdf file with secured property (without password). I would like to use VBA to remove security of PDF file but I have not much experience about that property in VBA code. please help to instruct me for my reference.

    I am greatly appreciate your help.
    Thanks,
    Thong.

  44. Karl Heinz Kremer says:

    Thong, This cannot be done with VB.

  45. Himanshu says:

    Hi,
    I am very new to the VBA coding, the very first line in your code is giving me an error. the line is ” Dim AcroApp As Acrobat.CAcroApp “. please can you tell me why it is not working for me.
    Thanks in advance for your help!

  46. Karl Heinz Kremer says:

    You need to add a reference to the Acrobat type library to you project. This is not specific to using Acrobat in your VBA program, it’s something that you will have to do for any external library. I did describe in my tutorial how to do that.

  47. Mark Curtis says:

    Acrobat Acrobat has a PDFBinder plug-in example in the lastest SDK. It uses AVConversionToPDFHandler to convert files to PDF. Adobe’s plug-in sample code is written in C. I’m looking for the VBA code to use AVConversionToPDFHandler.
    Can you help me ?

    Thanks,

    Mark

  48. Karl Heinz Kremer says:

    Mark, you cannot cross interfaces, which means you cannot use API functions from the plug-in interface in the IAC environment. The plug-in interface is the most powerful API in the Acrobat SDK, and neither the JavaScript nor the IAC interface come even close.

  49. Mark Curtis says:

    Thanks Karl for your quick response.

    Mark

  50. Hi Karl,

    I’m new in the VBA for excel. Thanks for the valuable information you publish here on your blog. I hope you can help me so I can take my next step forward to control adobe files out of my excel application.
    I’m using the following VBA code to open pdf (http://www.devhut.net/2010/09/09/vba-word-open-a-word-document/). This code works excelent but the file has to be closed and opened each time. If you do not close the pdf file is popping up again by the next call but it doesn’t navigate to the desired page in the file.
    I have printed already both adobe files you have listed but this makes the problem only bigger, I’m lost in all this to solve my problem, altough I feel I’m close to solve the problem.
    If the file is already open I need code for :
    – so VBA knows the file is already open or not / if not open I continue to open the file as indicated in the hyperlink above
    – if pdf is already open/ the pdf file has to pop up
    – the pdf file has to open on the correct page as sent to the function
    many thanks on forehand
    Danny Focquaert

  51. Karl Heinz Kremer says:

    Danny, I don’t think you need to check to see if a file is already open: If you try to open it again via VBA, it should just become the active document. The following script assumes that there are there files A.pdf, B.pdf and C.pdf in c:\temp – it will then randomly open (or activate it if it’s already open) one of these files, and go to a random page:

    Dim AcroApp As Acrobat.CAcroApp
    
    Private Sub CommandButton1_Click()
        Dim avDoc As Acrobat.CAcroAVDoc
        Dim avPageView As Acrobat.CAcroAVPageView
        Dim files(2) As String
        files(0) = "c:\temp\A.pdf"
        files(1) = "c:\temp\B.pdf"
        files(2) = "c:\temp\C.pdf"
        
        If (AcroApp Is Nothing) Then
            Set AcroApp = CreateObject("AcroExch.App")
        End If
        AcroApp.Show
        Set avDoc = CreateObject("AcroExch.AVDoc")
        Dim r As Integer
        ' open a random document
        r = Int((2 - 0 + 1) * Rnd + 0)
        Call avDoc.Open(files(r), "")
        Dim p As Integer
        ' go to a random page
        p = Int((10 - 1 + 1) * Rnd + 1)
        Set avPageView = avDoc.GetAVPageView
        avPageView.GoTo (p - 1)
        Set avPageView = Nothing
        Set avDoc = Nothing
    End Sub
    
  52. Miguel says:

    Hi I have been very useful code.
    I’m from Spain and I do not understand English. But with the translator, I will try to ask a question.
    As he could from access VBA insert in pdf a text box or what you have in memory the clipboard, and always on the first page.
    Thank you very much. A greeting.

  53. Karl Heinz Kremer says:

    Miguel, if you can access the clipboard contents via VBA, then you can create a text annotation with the that information. Take a look at the Doc.addAnnot() method, which you can call via the JSObject: http://help.adobe.com/en_US/acrobat/acrobat_dc_sdk/2015/HTMLHelp/index.html#t=Acro12_MasterBook%2FJS_API_AcroJS%2FDoc_methods.htm%23TOC_addAnnotbc-1&rhtocid=_6_1_8_23_1_0
    See my other posts about using the JSObject (e.g. here: http://khkonsulting.com/2009/03/acrobat-javascript-and-vb-walk-into-a-bar/ and here: http://khkonsulting.com/2010/09/reading-pdf-form-fields-with-vba/)

  54. Laura says:

    Tjis is one of the only posts I have found useful!

    One question, what if I have more than 2 pdfs I am combining?
    I am not great at VBA code and am having trouble with this.

    Thank you!

  55. Laura says:

    Nevermind, I figured it out…just read a little bit closer :).

    Thank you for this awesome post!

  56. Victor says:

    Hi Karl, when I export a pdf to excel, the picture in the document is not exported. It is posible to export with the picture? Or, how do I select a picture in a pdf and paste it in excel with vba. It is the only picture in the document.

  57. Karl Heinz Kremer says:

    Victor, this is a case of “it is what it is” – if something does not show up, there is usually no method to make it show up. There are not many controls that specify how the PDF should be converted to Excel. The ones that are available you can see when you bring up Acrobat’s preferences, then select the “Convert from PDF” category and select “Excel Workbook”. You cannot select and then copy and paste with VBA.

  58. pri says:

    Is there any way to have the filenames appear as bookmarks?

  59. Michele says:

    Hi,
    I’m trying to read the annotations of a pdf file.

    Dim AcrApp As Acrobat.Acroapp
    Dim AcrAvDoc As Acrobat.AcroAVDoc
    Dim pdDoc As Acrobat.CAcroPDDoc
    Dim Jso As Object
    Dim Annots as variant
    Dim Annot As Object
    Dim Props As Object

    Set AcrApp = New Acrobat.Acroapp
    Set AcrAvDoc = AcrApp.GetActiveDoc
    Set pdDoc = AcrAvDoc.GetPDDoc
    Set Jso = pdDoc.GetJSObject

    Jso.syncAnnotScan
    Set Annots = Jso.GetAnnots(0) ‘ I expect to read the annotations of the sheet no. 1

    but here the application stops here with an error… “Type not correspondent”
    There is anything wrong in the declaration of Annots?

    Thanks,
    Michele.

  60. Karl Heinz Kremer says:

    The “jso.getAnnots()” method returns an array of elements, not just one annotation, so you need to declare your “Annots” variable as a Variant():

    Dim Annots() As Variant

  61. Karl Heinz Kremer says:

    I don’t understand your question. Where would the filenames come from? Are you planning on concatenating different PDF files into one, and then having a bookmark that brings you to the first page of each document? You can do that by using the “createChild()” method in the bookmark object. You can find out more about this here: https://acrobatusers.com/tutorials/print/auto_bookmark_creation
    If you want to use this method within VBA, you have to use the JSObject to reference JavaScript methods.

  62. Michele says:

    Dear Karl,
    with reference to your answer of July 8, 2016 at 3:27 pm,
    I have modified the declaration of Annots as per your suggestion
    Sub ReadAnnotations()
    Dim AcrApp As Acrobat.Acroapp ‘Application Acrobat
    Dim AcrAvDoc As Acrobat.AcroAVDoc ‘Document actif dans Acrobat
    Dim pdDoc As Acrobat.CAcroPDDoc
    Dim page As Acrobat.CAcroPDPage
    Dim Jso As Object
    Dim Rect(3) As Integer
    Dim pageRect As Object
    Dim Annots() As Variant
    Dim Annot As Object
    Dim Props As Object
    Dim Color(0 To 3) As Variant

    Set AcrApp = New Acrobat.Acroapp
    Set AcrAvDoc = AcrApp.GetActiveDoc
    Set pdDoc = AcrAvDoc.GetPDDoc
    Set Jso = pdDoc.GetJSObject
    Jso.syncAnnotScan
    Set Annots = Jso.getannots(0)

    Now I have the following error at the same point: impossible to assign to the matrix.

    If I modify the last row in “Set Annots() = Jso.getannots(0)”, the error is the same “impossible to assign to the matrix”.

    Can you suggest where is the error?

    Thanks in advance,
    Michele.

  63. Michele Monaco says:

    Hi,
    although I have not yet found a solution to the correct usage of the GetAnnots method (refer to my previous post), I have another question regarding the creation of a new annotation type as “Polygon”.

    Here too I think to face a similar problem I have with the GetAnnots method.

    The vertices is defined as an array of array in the Acrobat Javascript API, but it is suggested the refer to the PDF Reference.
    In the PDF Reference 1.7 I found nothing more anyway
    Vertices – array – (Required) An array of numbers representing the alternating horizontal and vertical coordinates, respectively, of each vertex, in default user space.

    So I tried to implement the following procedure:

    Sub CreateNewAnnotationPolygon()
    Dim AcrApp As Acrobat.Acroapp ‘Application Acrobat
    Dim AcrAvDoc As Acrobat.AcroAVDoc ‘Document actif dans Acrobat
    Dim pdDoc As Acrobat.CAcroPDDoc
    Dim page As Acrobat.CAcroPDPage
    Dim Jso As Object
    Dim path As String
    Dim popupRect(3) As Integer
    Dim Rect(3) As Integer
    Dim PolVertices(1, 3) As Variant ‘ only four vertices are needed
    Dim pageRect As Object
    Dim Annot As Object
    Dim Props As Object
    Dim Color(0 To 3) As Variant

    Set AcrApp = New Acrobat.Acroapp
    Set AcrAvDoc = AcrApp.GetActiveDoc
    Set pdDoc = AcrAvDoc.GetPDDoc
    Set Jso = pdDoc.GetJSObject
    If Not Jso Is Nothing Then
    ‘ Get size for page 0 and set up arrays
    Set page = pdDoc.AcquirePage(0)
    Set pageRect = page.GetSize
    Rect(0) = 20 ‘ to define the position of the annotation
    Rect(1) = pageRect.y – 10
    Rect(2) = 20 ‘ actually I doubt if it is correct to define also rect(2) and rect(3)
    Rect(3) = pageRect.y
    PolVertices(0, 0) = 0
    PolVertices(1, 0) = 10
    PolVertices(0, 1) = 0
    PolVertices(1, 1) = 0
    PolVertices(0, 2) = 20
    PolVertices(1, 2) = 10
    PolVertices(0, 3) = 20
    PolVertices(1, 3) = 0
    ‘ Create a new Polygon annot
    Set Annot = Jso.AddAnnot
    Set Props = Annot.getprops
    Props.Type = “Polygon”
    Props.bordereffectIntensity = 1
    Props.Width = 1
    Annot.setProps Props
    ‘ Fill in a few fields
    Set Props = Annot.getprops
    Props.page = 0
    Props.Rect = Rect
    Props.Vertices = PolVertices ‘ HERE THE PROCEDURE STOPS WITH THE ERROR “Property not supported by the object”
    Props.Author = “Michele”
    Props.Subject = “Example Polygon shape”
    Color(0) = “RGB”
    Color(1) = 1#
    Color(2) = 0#
    Color(3) = 0#
    Props.StrokeColor = Color
    Annot.setProps Props
    pdDoc.Close
    ‘MsgBox “Annotation added”
    Else
    MsgBox “Failed to open”
    End If
    Set Annot = Nothing
    Set Props = Nothing
    Set page = Nothing
    Set pageRect = Nothing
    Set Jso = Nothing
    Set pdDoc = Nothing
    Set AcrAvDoc = Nothing
    Set AcrApp = Nothing
    End Sub

    Can you suggest where is the error?

    Thanks in advance,
    Michele.

  64. Karl Heinz Kremer says:

    Michele, I am sorry, but debugging your code is a bit outside of the scope of what I can do for free on my blog. If you need my professional help, feel free to get in touch with me via email. My email address is on the “About” page.

  65. Markus D. says:

    Hi Karl, found your blog while searching for a solution to check the orientation of the pages into a pdf-file. If i am opening the original file on screen some pages are in Orientation Landscape, some Portrait. I am using VBA to open the file and check each page with “getRotate”. The documentation told me this should return a value “in degrees”. The result is always the same, it is Zero. I hoped to get “90” or something else then Zero in case of Orientation Landscape. Am i wrong ? Here are the relevant parts of my code (or the parts i hope they are relevant)

    Dim AcroApp As Acrobat.CAcroApp
    Dim docu1 As Acrobat.CAcroPDDoc
    Dim docu1page As Acrobat.CAcroPDPage

    Set AcroApp = CreateObject(“AcroExch.App”)
    Set docu1 = CreateObject(“acroexch.pddoc”)
    docu1.Open (oFile.path)

    For i = 0 To docu1.GetNumPages() ‘to check each page in this document
    docu1.AcquirePage (i) ‘hopefully moves focus to this page
    Set docu1page = docu1.AcquirePage(i)
    Debug.Print “Seite ” & i & “, Ausrichtung ” & docu1page.GetRotate
    Next i

    Thank you in advance and of course thanks a lot for all the other informations on your page. (And sorry for my lousy english.)
    Markus

  66. Karl Heinz Kremer says:

    Markus, unfortunately it’s not that simple. A landscape page does not necessarily have a rotation applied to it. The rotation property is only applied to the page content, so if the page content does not have to be rotated, you will not find the rotation flag set to anything but 0. To make matters even more confusing, even with a portrait page, it is possible to see a page rotation applied. You will need to get the page size, and then compare width and height, and if the page width is greater than the height, you are looking at a landscape page.

  67. Markus D. says:

    Thank you so much, Karl Heinz. I will try to read out the pagesize as you described it. The first attempt failed (“Objekt unterstützt diese Eigenschaft oder Methode nicht”), but i think i will convince the System to tell me the things i need.

  68. Markus D. says:

    Hello once again, Karl Heinz. As you suggested i added a few lines to my code:

    Dim AcroExchPageSize As Object
    Set AcroExchPageSize = docu1page.GetSize
    Debug.Print “Höhe ” & AcroExchPageSize.y & ” Breite ” & AcroExchPageSize.x

    Works properly, thanks for your idea.

  69. Karl Heinz Kremer says:

    Markus, glad that you figured it out. I was just about to ask you about how you are trying to get the page size.

  70. Dave Moore says:

    I am trying to populate a form from ACCESS 2016 VBA with Acrobat DC Standard. I have the Acrobat 10.0 Type Library as a Reference and my code compiles.
    When I try to execute I error out on the SET APP = CreateObject(“AcroExch.app) with
    “Automation Error: Library Not Registered”. I have not found a solution and hoping you can help me. My code is”
    Sub TestPopulate()
    PopulateMembershipForm 70
    End Sub
    Public Function PopulateMembershipForm(ByVal lngRcdId As Long)
    Dim WshShell As Object
    Dim sValue As String ‘value to inser into form field
    Dim sAcord As String ‘File name and path of pdf form document
    Dim sSaveAs As String ‘name to save popllated file as
    Dim x As Object
    Dim jso As Object
    Dim val As Variant
    Dim APP As Acrobat.AcroApp
    Dim AVDOC As Acrobat.AcroAVDoc
    Dim PDDOC As Acrobat.AcroPDDoc

    Set dbs = DBEngine.Workspaces(0).Databases(0)
    sAcord = “C:\Users\Dave\Documents\KWVA\membership Recruitment\Acrobat Forms\TestFillForm.pdf”
    On Error GoTo errHandler
    ‘open pdf fillable form
    Set WshShell = CreateObject(“Wscript.Shell”)
    WshShell.Run “Acrobat.exe ” & sAcord

    Set APP = CreateObject(“AcroExch.app”)
    Set AVDOC = CreateObject(“AcroExch.AVDoc”)
    Set AVDOC = APP.GetActiveDoc
    Set PDDOC = AVDOC.GetPDDoc
    Set jso = PDDOC.GetJSObject

    strQry = “SELECT RcdId, FirstName, LastName, MI, Adddress, City, ST, Zip FROM dbo_tblMembershipList WHERE (RcdId = & lngrcdid) ”
    Set rst = dbs.OpenRecordset(strQry)
    If Not (rst.EOF) Then
    Set x = jso.getfield(“LastName”)
    val = rst!LastName
    x.Value = val
    Set x = jso.getfield(“FirstName”)
    x.Value = val

    PDDOC.Save 1, “C:\Users\Dave\Documents\KWVA\membership Recruitment\Acrobat Forms\TestFillForm” & lngRcdId & “.pdf”
    AVDOC.Close 1

    DoEvents
    APP.CloseAllDocs
    DoEvents
    APP.Exit

    ‘ fcloseapp “AcrobatSDIWindow”
    End If
    Set APP = Nothing
    Set AVDOC = Nothing
    Set PDDOC = Nothing
    Set jso = Nothing
    errHandler:
    MsgBox Err.Number & “: ” & Err.Description, vbOKOnly, “Error”

    Exit_PopulateMembershipForm:
    Exit Function

    End Function

  71. Karl Heinz Kremer says:

    Dave, I am not a VB expert, so I am not the right person to ask. However, I have one comment: I never start the Acrobat application – it should get launched automatically when you run code that requires Acrobat to be running. You may want to remove the lines that start Acrobat from our code. Once you have the reference to the Acrobat application, you can then open the document via the normal API calls.

  72. Revathi says:

    Acrobat not found in reference of vb 6.0 application

  73. Karl Heinz Kremer says:

    Revathi, the Acrobat reference should be in the list of references if you have Adobe Acrobat installed. It will not be there if all you have is the free Adobe Reader.

  74. Scott says:

    Thank you for your sharing, I have complete my 1st VBA to handle PDF! ^_^
    I have something to share:

    1.In your article, these 3 code pieces are misplaced:
    ….
    We also need an integer object to store the number of pages in the first document.
    Set AcroApp = CreateObject(“AcroExch.App”)
    Set Part1Document = CreateObject(“AcroExch.PDDoc”)
    Set Part2Document = CreateObject(“AcroExch.PDDoc”)
    In the next step, we initialize the three Acrobat related objects. Nothing special here.
    Part1Document.Open (“C:\temp\Part1.pdf”)
    Part2Document.Open (“C:\temp\Part2.pdf”)
    Now that our objects are initialized, we can use the methods to do something with the objects. In order to merge files, we need access to both the source files, so we have to call the Open() method on both these objects. The key to success is to specify the whole path name, directory and filename.
    numPages = Part1Document.GetNumPages()

    2.At first, I can’t merge my own pdfs, but when I produce 2 new simple pdfs, they can be merged. And after a lot of thinking…. I found that my own pdfs have been set in protected mode, that’s why it won’t work!

    I have a routine job that I did everyday and I want it to be executed automatically. I’ll study you other article and try to complete my quest(if I can).

    Best wishs for you.

  75. Sarah says:

    Thanks a lot for the useful tutorial. It allowed me to get pretty far in automating the export of “factsheets” with different formulas and links in excel to PDF. However, now I’m stuck with a last issue that I can’t figure out. Do you have a hint how to proceed by any chance?

    The excel file contains links (to web pages) that I want to also be active in the PDF file. Hence, I set up a VBA script to convert my excel file to PDF using PDFMaker:
    […]
    ‘ settings for PDFMaker
    pmkr.GetCurrentConversionSettings stng
    stng.AddBookmarks = True
    stng.AddLinks = True
    stng.AddTags = False
    stng.ConvertAllPages = False
    stng.CreateFootnoteLinks = False
    stng.CreateXrefLinks = True
    stng.PrintActivesheetOnly = True
    stng.PromptForSheetSelection = False
    stng.OutputPDFFileName = pdfname
    stng.PromptForPDFFilename = False
    stng.ShouldShowProgressDialog = True
    stng.ViewPDFFile = False

    ‘ convert excel sheet to PDF file
    pmkr.CreatePDFEx stng, 0
    […]

    It all works nicely, except for the export of the links. Some of the parameters I set must be wrong I assume. When I create the PDF manually by using ACROBAT –> PDF erstellen, everything works fine. When I execute my VBA script, the link is not included in the PDF file, and my excel sheet gets modified: a text box is added around my cell with the link?!?

    Thanks in advance for any help!

  76. Karl Heinz Kremer says:

    Sarah, the PDFMaker interface is undocumented and unsupported, so we don’t know how it’s supposed to work, or if Adobe will break our software with the next update to Acrobat. I try to stay away from unsupported/undocumented functionality.

  77. Chris Mauldin says:

    Sorry for a dumb question *sigh* But do I need anything other than an Adobe Acrobat Professional license on the PC where the code will run? Or do I need a special SDK license. the stupid adobe site confuses me completely!!

  78. Karl Heinz Kremer says:

    Chris, all you need is Adobe Acrobat Standard or Pro.

  79. Juan Carlos says:

    Hi Karl,
    Thank you very much for the tips. I tryed to use it in Access but I can not load the library reference. I use Access 2016, and I have the Adobe Acrobat software installed. Do you know how can I use it in Access?
    Thanks a lot

  80. Alex says:

    I have about 1,000 pdf files and each file has about 50 pages. I want to split/extract the pages out of each file onto it’s own file (should be 1-3 pages). The pdf file contains Contract Name. I want the file to print every time it finds a new contract name. It is usually 1 contract per page, but some contract may have up to 3 pages (could be more but that is what I found so far). How can i do this? I have adobe acrobat and ms office 2010. I’m very familiar with vba but I am open to doing it with another language /technology. Any help is appreciated.

  81. Alex says:

    Also, I would like to have the contract name as part of the filename.

  82. Karl Heinz Kremer says:

    Juan, unfortunately, I don’t know how to make this work. I know that VBA in Access should work, but I am not using Access, so don’t have any first hand experience.

  83. Alex says:

    This code runs and creates a pdf file, but it is skipping the pages that don’t have the word “Information” on it.

    I am searching for the word “Information” and every time it finds it, it should print that page up to the next page where “information” shows up. 95% of the time it will be on every page of the pdf document, but 5% of the time, it could have an extra page or two in between where “information” is not on the page. When that happens I want the pdf file to print the page that has the word “Information” on it and all the following pages up to the page that next has the word “Information” on it.

    Dim WordToFind As String
    Dim PDFPath As String
    Dim App As Object
    Dim AVDoc As Object
    Dim PDDoc As Object
    Dim JSO As Object
    Dim i As Long
    Dim j As Long
    Dim Word As Variant
    Dim Result As Integer
    Dim x As Long
    Dim foundnew As Boolean
    Dim PDFNewName As String
    Dim page As Long
    Dim newPDF As Acrobat.CAcroPDDoc
    Dim lngPages As Long
    Dim NewName As String

    ‘Added the below declaration
    Dim SpecFl As String

    ‘Specify the text you want to search.
    WordToFind = “Information”

    ‘Specify the path of the sample PDF form.
    ‘Full path example:
    PDFPath = “C:\Audit Strategy\Audits\Federated Coop\PDF Extraction\Promo 41_Contracts_2018-03-06_03-53-39-PM.pdf”
    PDFNewName = Mid(PDFPath, 1, Len(PDFPath) – 4)

    ‘Check if the file exists.
    If Dir(PDFPath) = “” Then
    MsgBox “Cannot find the PDF file!” & vbCrLf & “Check the PDF path and retry.”, _
    vbCritical, “File Path Error”
    Exit Sub
    End If

    ‘Check if the input file is a PDF file.
    If LCase(Right(PDFPath, 3)) “pdf” Then
    MsgBox “The input file is not a PDF file!”, vbCritical, “File Type Error”
    Exit Sub
    End If

    On Error Resume Next

    ‘Initialize Acrobat by creating the App object.
    Set App = CreateObject(“AcroExch.App”)

    ‘Check if the object was created. In case of error release the objects and exit.
    If Err.Number 0 Then
    MsgBox “Could not create the Adobe Application object!”, vbCritical, “Object Error”
    Set App = Nothing
    Exit Sub
    End If

    ‘Create the AVDoc object.
    Set AVDoc = CreateObject(“AcroExch.AVDoc”)

    ‘Check if the object was created. In case of error release the objects and exit.
    If Err.Number 0 Then
    MsgBox “Could not create the AVDoc object!”, vbCritical, “Object Error”
    Set AVDoc = Nothing
    Set App = Nothing
    Exit Sub
    End If

    On Error GoTo 0

    ‘Open the PDF file.
    If AVDoc.Open(PDFPath, “”) = True Then

    ‘Open successful, bring the PDF document to the front.
    AVDoc.BringToFront

    ‘Set the PDDoc object.
    Set PDDoc = AVDoc.GetPDDoc

    ‘Set the JS Object – Java Script Object.
    Set JSO = PDDoc.GetJSObject

    ‘Search for the word.
    If Not JSO Is Nothing Then
    x = 0

    ‘Loop through all the pages of the PDF.
    For i = 0 To JSO.numPages – 1
    lngPages = 1
    ‘Loop through all the words of each page.
    For j = 0 To JSO.GetPageNumWords(i) – 1

    ‘Get a single word.
    Word = JSO.getPageNthWord(i, j)

    ‘If the word is string…
    If VarType(Word) = vbString Then

    ‘Compare the word with the text to be found.
    Result = StrComp(Word, WordToFind, vbTextCompare)

    ‘If both strings are the same.
    If Result = 0 Then
    ‘Select the word and exit.
    Call JSO.selectPageNthWord(i, j)

    Set newPDF = CreateObject(“AcroExch.pdDoc”)
    newPDF.Create

    NewName = PDFNewName & “_” & RTrim(LTrim(Str(i))) & “.pdf”
    newPDF.Open (PDFPath)
    newPDF.InsertPages -1, PDDoc, i, 1, 0
    newPDF.Save 1, NewName
    newPDF.Close
    Set newPDF = Nothing

    ‘lngPages = 1
    GoTo NextPage
    ‘Exit Sub
    Else
    lngPages = lngPages + 1
    End If

    End If
    NextWord:
    Next j
    NextPage:
    Next i

    ‘Word was not found, close the PDF file without saving the changes.
    AVDoc.Close True

    ‘Close the Acrobat application.
    App.Exit

    ‘Release the objects.
    Set JSO = Nothing
    Set PDDoc = Nothing
    Set AVDoc = Nothing
    Set App = Nothing

    ‘Inform the user.
    MsgBox “The word ‘” & WordToFind & “‘ could not be found in the PDF file!”, vbInformation, “Search Error”

    End If

    Else

    ‘Unable to open the PDF file, close the Acrobat application.
    App.Exit

    ‘Release the objects.
    Set AVDoc = Nothing
    Set App = Nothing

    ‘Inform the user.
    MsgBox “Could not open the PDF file!”, vbCritical, “File error”

    End If

  84. Chris says:

    Hi Karl,

    My goal is to enter data into empty fillable fields in a PDF document. In particular, I’m planning on filling data into IRS Form 8949 for my annual taxes. So far I haven’t had luck determining how to do this. I found one article that shows how to export the PDF text into a text document, but it doesn’t export data that I’ve saved in the fillable fields. I was hoping that if the code exported the fillable field data than I could reverse engineer the code to import data. I wonder if this is a security feature of the 8949, a limitation of the code that I used, or perhaps a complete limitation of the library? I’m using Windows 10, Excel 2013.

    After writing this it looks like one test I could do is to use a PDF that has no security features and see if fillable field data is accessible. I’ll reply back with the results.

    BTW, it’s really exciting to see how relevant your article is and that you’re still active in the comments section.

    Here’s the code to export PDF text to Text Document. It works for me, except it doesn’t extract fillable field data in tax form 8949

    Sub PDF_to_Text()

    ‘Source: “https://www.reddit.com/r/excel/comments/5n4484/vba_copying_data_out_of_pdf/”

    Dim TargetFile As String
    Dim OutputFile As String
    Dim AC_PD As Acrobat.AcroPDDoc
    Dim AC_Hi As Acrobat.AcroHiliteList
    Dim AC_PG As Acrobat.AcroPDPage
    Dim AC_PGTxt As Acrobat.AcroPDTextSelect
    Dim OS_FSO As Object
    Dim OS_TxtFile As Object
    Dim Ct_Page As Long
    Dim z As Long, j As Long, k As Long
    Dim T_Str As String

    Set OS_FSO = CreateObject(“Scripting.filesystemobject”)

    TargetFile = “F:\Cryptocurrency Ledgers\Supporting Documents\f8949 2017.pdf” ‘change to your PDF file
    OutputFile = “F:\Cryptocurrency Ledgers\Supporting Documents\PDFExtraction.txt” ‘change the output, .csv or .txt both work

    ‘Optional part I added
    ‘It quits the code if the TargetFile is not found.
    ‘You could also add in an error handler to notify you that the file was not found.
    If Dir(TargetFile) = “” Then Exit Sub

    ‘From original code
    Set AC_PD = New Acrobat.AcroPDDoc
    Set AC_Hi = New Acrobat.AcroHiliteList
    AC_Hi.Add 0, 32767
    With AC_PD
    .Open TargetFile
    Ct_Page = .GetNumPages

    Set OS_TxtFile = OS_FSO.createtextfile(OutputFile)

    For z = 1 To Ct_Page
    T_Str = “”
    Set AC_PG = .AcquirePage(z – 1)
    Set AC_PGTxt = AC_PG.CreateWordHilite(AC_Hi)
    If Not AC_PGTxt Is Nothing Then
    With AC_PGTxt
    For j = 0 To .GetNumText – 1
    T_Str = T_Str & .GetText(j)
    Next j
    End With
    End If
    OS_TxtFile.write T_Str
    Next z
    OS_TxtFile.Close
    End With

    ‘The next step would be to get the data from the output file,
    ‘in whatever way you see fit

    End Sub

  85. Ravi says:

    If I am using Nitro Pro 9, can I set this in VBA for merging pdf? if yes, can you please advise what should I write instead of AcroExch.App in below code?
    Set AcroApp = CreateObject(“AcroExch.App”)

  86. Karl Heinz Kremer says:

    Ravi, I am not familiar with what API NitroPro provides, but it is very likely different than the Acrobat API. You will have to get in touch with the makers of NitroPro to find out what the corresponding call is.

  87. Mark says:

    Hi,

    Thank you for this excellent article.

    I have some Excel 2010 VBA code that’s been working quite well with Adobe Acrobat XI Pro, but when I updated to 2017 Pro the same code crashes, in several places.

    Before I delve into the nitty gritty, just an obvious question: Have there been any substantial changes to the API or SDK with 2017 Pro? I can’t help but notice it’s very similar to DC, and I see a whole new set of documentation for DC. On the other hand the Interapplication Communication API Reference is dated November 2006 for Version 8.0?!?! Is there a later version?

    Most likely I’m not doing something right and was just getting by with XI, but something is now being enforced with Pro. Got to get a little deeper into it to figure out exactly what it is.

    Thanks.

  88. Karl Heinz Kremer says:

    Mark, as you’ve guessed based on the old documentation, there have not been any updates to the IAC API, so something that was running with Acrobat XI should still run with Acrobat DC. There are two reasons why that may not be the case anymore: Bugs in your own software (that did not show up in Acrobat XI), and bugs in Acobat DC. If you can confirm that e.g. a sample program from the API documentation does work with XI, but not with DC, I would assume you are dealing with a bug and you should report it: http://www.adobe.com/products/wishform.html

  89. Jordan says:

    So your code is of great interest to me. What I am trying to achieve is based on your example but a bit more complex. The functionality that I need, but don’t know how to code, is rather easy to state. Not sure if the difficulty is as easy.

    The other feature I would need is:
    – The ability to browse to a desired folder
    – Then combine all pdf files with in the desired folder
    – Then name the newly combined pdf
    – Then save the newly combined pdf in the same desired folder

    With regards to naming the combined pdf, The name will be based on the desired folder’s location. For example, the pdfs will be located in C:/… Company A, LLC/September 2018/. I would like the merged file to be named “Company A, LLC – September 2018 – Financial Statement.pdf”

    Based upon your example this would be possible. Is it possible and can you give me some advice or even assistance with creating such a macro?

    Thanks in advance,
    Jordan

  90. Karl Heinz Kremer says:

    Jordan, Most of what you want to do can be done in VBA (e.g. browse to a folder and find all PDF files in that folder), and is not specific to working with Acrobat. Here is how I would approach this:

    In You rVBA (e.g. Word or Excel macro), create a function that puts up a file selection dialog that allows the user to select a folder. Once you have the folder, iterate over all files in that folder and collect the PDF files in e.g. a list. Once that is done, open the first file that you found in Acrobat using IAC. Then for every other document in your list, open the document as a PDDoc and call PDDoc.InsertPages (https://help.adobe.com/en_US/acrobat/acrobat_dc_sdk/2015/HTMLHelp/index.html#t=Acro12_MasterBook%2FIAC_API_OLE_Objects%2FInsertPages.htm) to insert the pages of the just opened document at the end of the first document. Once done, save the newly created with with the desired filename in the folder that was selected. If you need my professional help with this, please feel free to get in touch with me via email.

  91. Stuart P says:

    Your code has helped me greatly and for that I thank you. However, the .pdfs I want to merge are on a SharePoint online site and using the url (“https://…sharepointonline.com/sites/…/mypdf.pdf”) as the path, doesn’t get the document. It works fine if I substitute a local path. Is this something that can be done? Thanks.

  92. Karl Heinz Kremer says:

    Stuart, unfortunately, I don’t have access to SharePoint, so I cannot give you any advice.

  93. Ekaterina Boehm says:

    Karl,

    I was wondering if you can shed some light on the pageNum property. I am trying to extract text from a specific page in a .PDF and I am using Acrobat Type Library 10.0 in Excel’s VBA function. I wanted to omit the use of AcroAVDoc object because I want to run this extraction on multiple documents in the background. So far I looked at the Java Script for Acrobat API Reference Guide and saw this property called pageNum. However when I am trying to access this property I get a Run Time Error 438. Any help on why I am getting this Ru Time Error will be greatly appreciated. Thank you

  94. Karl Heinz Kremer says:

    Ekaterina, numPage returns (or sets) the page that is currently being displayed in the Acrobat viewer. If you are not using an AVDoc, you do not have a document that can change it’s active page, that is very likely the reason why you are getting this error. But, if you are not displaying the PDF file, there is no need to use pageNum.

  95. Henrique Paes says:

    Hi everyone! Is there a way to copy the content of a PDF file (e.g. ctrl A + ctrl C) without opening the Acrobat, and then paste it on an Excel worksheet, via VBA?

  96. Euclides Vezga says:

    Thank you very much, excellent guide.

  97. I’ve been using a modified version of this code for about 6 years to create an uber document. My modification allows one to pass in an array of .pdf file names. There are (13) individual .pdf files that are combined into one larger document.

    Recently, I started getting failures on a combined document for one airplane. The combined document is much larger (~300 MB) versus similar documents for other airplanes (5~10 MB range). The failures were sporadic; the code would run to completion about 40% of the time. In addition, I had no failures when I stepped through the code, one line at a time, using the F8 key. I tried adding a few DoEvents statements, but that did not help. The error was traced to this line of code, usually occurring after the 7th or 8th .pdf file had been appended successfully:

    If Part1Document.Save(PDSaveFull, gstrFilePath & “ETOLBook.pdf”) = False Then

    I changed “PDSaveFull” to “PDSaveIncremental”:

    If Part1Document.Save(PDSaveIncremental, gstrFilePath & “ETOLBook.pdf”) = False Then

    So far, after testing over 20 times, I have not had a single failure.

    I also experimented with PDSaveFull + PDSaveCollectGarbage (6 passes / 2 failures) and PDSaveFull + PDSaveCollectGarbage + PDSaveLinearized (5 passes / 0 failures).

    For those who are using late binding (e.g. no checked reference needed to the Acrobat Library), one can declare constants with the following values:

    Const PDSaveIncremental = 0
    Const PDSaveFull = 1
    Const PDSaveLinearized = 4
    Const PDSaveCollectGarbage = 32

  98. Van der Stighelen Benjamin says:

    I’m looking for a vba to change the page labels of a PDF file.

  99. Lakshmi Telagi says:

    Hi Karl,

    In out project we are doing the similar steps to merge PDF files using VB.net 2019 program. We have installed Acrobat Adobe Pro 11 on Development server. Project works fine and able to generate merged PDF files. But on the test server we not allowed to install Acrobat Adobe Pro 11 and Project should be deployed as Setup.MSI by referencing only required Dlls. Because of that on test server merge pdf are failed to create with Active X error. Let us know if we have way to reference dlls or install any Adobe SDK files without installing Acrobat Adobe Pro on the test server.

  100. Karl Heinz Kremer says:

    Lakshmi, you cannot use Adobe Acrobat on a server – there are technical reasons, but more importantly, it is not licensed for server use. This means that you will have to look for a solution that does not require Adobe Acrobat. There are a number of options available, I would probably use something based on the free PDFBox library.

  101. Lakshmi Telagi says:

    Hi Karl,

    Thanks for your feedback. Do we have PDFBox library for VB.Net application? If so, can you send URL link.

    Thanks,
    Lakshmi Telagi

  102. Bhavesh Patel says:

    Dear Karl,

    Your Samples are working Fine.

    I have got an Issue while updating one Field

    Say I have Total, Tax and Grand Total

    I want to have a Forumula in Tax as Java Script

    Tax = Total * (10 % of Total)

    Grand Total = Total + Tax

    I am not able to do it inspite of lot of Efforts

    I have tried the Following

    field.SetJavaScriptAction “calculate”, “AFSimple_Calculate(“”ADD””,new Array(“”Total””,””Tax””);”

    Though it shows in the Java Script Properties, but does not Refresh the same

    How can I do this ?

    Thanking You,

    Bhaevsh

  103. Karl Heinz Kremer says:

    Bhaevesh, I would use the full JavaScript syntax instead of the simple calculation script. Something like ‘rc.value = this.getField(“Total”).value + this.getField(“Tax”).value;’ should do the job.

  104. Jeremy Auger says:

    Karl,
    I am looking for a way to send values from a Form in Access to a PDF. I have found the field values for the PDF using the built in Java module in Access, but have been unsuccessful sending values from Access to PDF.

    I have been able to use the SendKeys function to fill out the form, but once it gets to the first value on the second page, the screen flickers and it won’t proceed any further. This is the reason I would like to be able to just assign the values to the fields on the PDF form.

    I am using Access 2016 and have Adobe Acrobat DC on a Windows 10 system.

    Any advice is welcomed…I am a self-taught Access database novice of 1 year.

  105. Karl Heinz Kremer says:

    Jeremy, from VBA you can access the field values directly and don’t have to use the SendKeys function. Take a look here: http://khkonsulting.com/2010/09/reading-pdf-form-fields-with-vba/

  106. Mukesh says:

    Hello Karl,
    Can you please suggest me how to open Password Protected PDF File, and copy data from pdf and paste it to excel?

  107. Karl Heinz Kremer says:

    You need the password.

  108. Karl Heinz Kremer says:

    Henrique, you can read the form fields values via VBA: http://khkonsulting.com/2010/09/reading-pdf-form-fields-with-vba/

Leave a Reply

Your email address will not be published. Required fields are marked *