VBA - Tips
Summary & Introduction
Adobe Acrobat Professional
 
Adobe Acrobat

VBA Control of Adobe Acrobat Professional

Adobe Acrobat Professional is more automatically controlled by JavaScript, another computer language, but Adobe has provided Inter-Application Communication (IAC) that allows VBA to interface with JavaScript.

From any primary VBA application such as Microsoft Word or CorelDraw you can control Acrobat Professional to;

combine multiple Acrobat files into one,
delete pages from an Acrobat file,
count the number of pages in an Acrobat file,
insert a page into an Acrobat file,
move pages including reversing the page order,
search an Acrobat file for text,
copy text,
crop pages,
rotate pages,
save or save to another pdf,
work with bookmarks although it is it bit limited.


All the code on this page can be run from any application that fully supports VBA, such as Microsoft Word, PowerPoint, Excel, CorelDraw etc.

When controlling Acrobat reference Adobe Acrobat __ Type Library. ie acrobat.tlb
The __ undersores represent the version of acrobat. ie 9.0 or 10 etc.
With the Adobe Acrobat Type Library you can define 3 important objects.
acroApp is the acrobat object whilst acroAVDoc and acroPDDoc are the acrobat's methods and properties.

In books and on the internet you can find definitions with an additional C in front of definitions such as CAcroApp, CAcroAVDoc, CAcroPDDoc, CAcroPDTextSelect, CAcroHiliteList etc.
The leading C can be dispensed with for VBA. It has no effect.

acroApp
    Dim <Your Variable Name> As Acrobat.acroApp
    Set <Your Variable Name> = CreateObject("AcroExch.App")

CloseAllDocs() As BooleanCloses all open documents. You can close each individual AVDoc by calling AVDoc.Close().
Exit() As BooleanExits the Acrobat viewer. Applications should call App.Exit() before exiting.
GetActiveDoc() As ObjectGets the frontmost document.
GetActiveTool() As StringGets the name of the currently active tool.
GetAVDoc(Index As Long) As ObjectGets an AcroExch.AVDoc by its index in the list of open AVDocs. Use App.GetNumAVDocs () to get the number of AVDocs.
GetFrame() As ObjectGets the window's frame.
GetInterface(Name As String) As Object
GetLanguage() As StringGets a code that specifies which language the Acrobat viewer's user interface is using.
GetNumAVDocs() As LongGets the number of open AcroExch.AVDocs.
GetPreferenceEx(Type As Integer)Gets a value from the preferences file.
Hide() As BooleanHides the Acrobat viewer.
Lock(LockedBy As String) As BooleanLocks the Acrobat viewer.
Maximize(vbMaximize As Long) As BooleanMaximizes the Acrobat viewer.
MenuItemExecute(MenuItemName As String) As BooleanExecutes the menu item whose language-independent menu item name is specified.
MenuItemIsEnabled(MenuItemName As String) As BooleanIs the specified menu item enabled?
MenuItemIsMarked(MenuItemName As String) As BooleanIs the specified menu item marked?
MenuItemRemove(MenuItemName As String) As BooleanRemoves the menu item whose language-independent menu item is specified.
Minimize(Minimize As Long) As BooleanMinimizes the Acrobat viewer.
Restore(Restore As Long) As BooleanRestores the Acrobat viewer.
SetActiveTool(ButtonName As String, Persistent As Long) As BooleanSets the active-tool to the tool whose name is specified.
SetFrame(Rect As Object) As BooleanSets the window's frame to the specified rectangle.
SetPreferenceEx(Type As Integer, val) As BooleanSets a value in the preferences file.
Show() As BooleanThis shows the Acrobat application but only pdf's opened with AVDoc will be visible.
ToolButtonIsEnabled(ButtonName As String) As BooleanIs the specified toolbar button enabled?
ToolButtonRemove(ButtonName As String) As BooleanRemoves the specified button from the toolbar.
Unlock() As BooleanObsolete: One should use UnLockEx (LockedBy As String)
UnlockEx(LockedBy As String) As BooleanUnlocks the Acrobat viewer if it was previously locked. Specify the application as a string.

acroAVDoc
    Dim <Your Variable Name> As Acrobat.acroAVDoc
    Set <Your Variable Name> = CreateObject("AcroExch.AVDoc")

BringToFront() As BooleanBrings the window to the front.
ClearSelection() As BooleanClears the current selection.
Close(NoSave as Long) as BooleanCloses a document. You can close all open AVDocs by calling App.CloseAllDocs().
FindText(Text As String, CaseSensitive As Long, WholeWordsOnly As Long, Reset As Long) As BooleanFinds the specified text.
GetAVPageView() As ObjectGets the associated AcroAVPageView.
GetFrameGets the rectangle specifying the window's size and location.
GetParentPDDoc() As ObjectGets the associated CAcroPDDoc of the Collection's Parent. NULL if not a Collection.
GetPDDoc() As ObjectGets the associated AcroPDDoc
GetTitle() As StringGets the window's title.
GetViewMode() As LongGets the current document view mode.
IsValid() As BooleanDetermines whether the AcroAVDoc is still valid.
Maximize(vbMaximize As Long) As BooleanMaximizes the window if vbMaximize is true.
Open(FullPath As String, TempTitle As String) As BooleanOpen(Path & name of pdf, Temp pdf title if "" then pdf file name is used)
OpenInWindowEx(FullPath As String, hWnd As Long, openFlgs As Long, UseOpenParams As Long, PageNum As Long, PageMode As Integer, ZoomType As Integer, Zoom As Long, Top As Integer, Left As Integer) As BooleanOpens a PDF file and displays it in a user-specified window.
PrintPages(FirstPage As Long, LastPage As Long, PSLevel As Long, BinaryOk As Long, ShrinkToFit As Long) As BooleanPrints a specified range of pages.
PrintPagesEx(FirstPage As Long, LastPage As Long, PSLevel As Long, BinaryOk As Long, ShrinkToFit As Long, Reverse As Long, FarEastFontOpt As Long, EmitHalftones As Long, PageOption As Long) As BooleanPrints a specified range of pages. (Supports new print features.)
PrintPagesSilent(FirstPage As Long, LastPage As Long, PSLevel As Long, BinaryOk As Long, ShrinkToFit As Long) As BooleanPrints a specified range of pages without displaying any dialog box.
PrintPagesSilentEx(FirstPage As Long, LastPage As Long, PSLevel As Long, BinaryOk As Long, ShrinkToFit As Long, Reverse As Long, FarEastFontOpt As Long, EmitHalftones As Long, PageOption As Long) As BooleanPrints a specified range of pages without displaying any dialog box. (Supports new print features.)
SetFrame(Rect As Object) As BooleanSets the window's size and location.
SetTextSelection(AcroPDTextSelect As Object) As BooleanSets the document's selection to the specified text selection.
SetTitle(Title As String) As Boolean>Sets the window's title.
SetViewMode(Type As Long) As BooleanSets the mode in which the document will be viewed.
ShowTextSelect() As BooleanChanges the view so that the current text selection is visible.

acroPDDoc
    Dim <Your Variable Name> As Acrobat.acroPDDoc
    Set <Your Variable Name> = CreateObject("AcroExch.PDDoc")

AcquirePage(Page As Long) As ObjectAcquires the specified page.
ClearFlags(Flags As Long) As BooleanClears a document's PDDocFlags.
Close as BooleanCloses a file.
Create() As BooleanCreates a new AcroExch.PDDoc.
CreateTextSelect(Page As Long, AcroRect As Object) As ObjectCreates a text selection from the specified rectangle on the specified page.
CreateThumbs(FirstPage As Long, LastPage As Long) As BooleanCreates thumbnail images for the specified page range in a document.
CropPages(StartPage As Long, EndPage As Long, OddOrEvenPagesOnly As Integer, AcroRect As Object) As BooleanCrops the specified pages.
DeletePages(StartPage As Long, EndPage As Long) As BooleanDeletes pages from a file.
DeleteThumbs(StartPage As Long, EndPage As Long) As BooleanDeletes thumbnail images from the specified pages in a document.
GetFileName() As StringGets the name of the file associated with this CAcroPDDoc.
GetFlags() As LongGets a document's PDDocFlags.
GetInfo(sInfoKey As String) As StringGets the value of a specified key in the document's info dictionary.
GetInstanceID() As StringGets the instance ID from the ID array in the document's trailer.
GetJSObject() As ObjectGets the JavaScript object for this document. eg. getField("FieldName")
GetNumPages() As LongGets the number of pages in a file.
GetPageMode() As LongGets a value indicating the current PDViewMode.
GetPermanentID() As StringGets the permanent ID from the ID array in the document's trailer.
InsertPages(InsertPageAfter As Long, PDDocSource As Object, StartPage As Long, NumPages As Long, InsertFlags As Long) As BooleanInserts a copy of a page into a particular location.
MovePage(lMoveAfterThisPage As Long, lPageToMove As Long) As BooleanMoves a page to another location within the same document.
Open(FullPath As String) As BooleanOpens a file.
OpenAVDoc(TempTitle As String) As ObjectOpens a window and displays the document in it.
ReplacePages(StartPage As Long, PDDocSource As Object, StartSourcePage As Long, NumPages As Long, MergeTextAnnotations As Long) As BooleanReplaces pages in a file with those from a specified file.
Save(Type As Integer, FullPath As String) As BooleanSaves a document.
SetFlags(Flags As Long) As BooleanSets a document's PDDocFlags.
SetInfo(InfoKey As String, Buffer As String) As BooleanSets the value of a key in a document's info dictionary.
SetPageMode(PageMode As Long) As BooleanSets the Acrobat viewer to display one of the PDViewMode.

Opening Acrobat
There are 2 ways to open Acrobat.
Visibly as an AVDoc or hidden as PDDoc.
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.
You cannot retrieve the AVDoc object from within the PDDoc.


Open a PDF Visibly
'AVDoc's are visible versions of Acrobat.
'Every AVDoc has a PDDoc behind the scenes, and that object can be retrieved via the AVDoc.GetPDDoc method.

    Dim acroApp As Acrobat.acroApp
    Dim avDoc As Acrobat.acroAVDoc
        
    Set acroApp = CreateObject("AcroExch.App")
    Set avDoc = CreateObject("AcroExch.AVDoc")
        
    'avDoc.Open FileLocation, TitleToDisplay
    avDoc.Open "D:\Users\User\Desktop\Test.pdf", "PDF Title"
    avApp.Show
        
    'The next 2 lines to refer to the PDDoc from an AVDoc
    Dim pdDoc As Acrobat.AcroPDDoc
    Set pdDoc = acroDoc.GetPDDoc
        
    Set pdDoc = Nothing
    Set avDoc = Nothing
    Set acroApp = Nothing
    

Hidden PDF
PDDoc are hidden Acrobat documents.
AVDoc are visible Acrobat documents.
You cannot retrieve the AVDoc object from within the PDDoc but a PDDoc will allow you to open its associated AVDoc.

    Dim pdDoc As Acrobat.AcroPDDoc 'or .CAcroPDDoc
        
    Set pdDoc = CreateObject("AcroExch.PDDoc")

    pdDoc.Open "D:\Users\User\Desktop\Test.pdf"
    'The acrobat is now open but invisible.
        
    'Create an AVDoc from a PDDoc if you wish to make the pdf visible.
    'OpenAVDoc and give the pdf a title that is not necessarily the name of the file.
    pdDoc.OpenAVDoc "Title"
        
    'When you manually close a visible acrobat the acrobat application will close.
    'However if you did not make acrobat visible then you can not easily close acrobat.
    'You should use the following code to close the hidden acrobat application.
    'pdDoc.Close
        
    Set pdDoc = Nothing
    Set acroApp = Nothing
      


Closing Acrobat
Sometimes for what ever reason Acrobat will not close with acroApp.Exit
To force a closure you can use the following API code.
The code is written for a 64 bit system.
The 2 Declare statements and Const must be before any Subs or Functions, and they must not be within a sub or Function.

      Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
      Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
      Public Const WM_CLOSE = &H10
          
      Sub CloseAcrobat()
          Dim hwnd As LongPtr
          hwnd = FindWindow("AcrobatSDIWindow", vbNullString)
          'Close down Notepad.
          SendMessage hwnd, WM_CLOSE, 0&, 0&
      End Sub

Determine the Number of Pages in an Open PDF

    Dim acroApp As acroApp
    Dim avDocAs AcroAVDoc
    Dim pdDoc As AcroPDDoc
    Dim intNoPages As Integer
          
    'Create an Acrobat object.
    Set acroApp = CreateObject("AcroExch.App")
      
    'Get the already opened PDF file.
    Set avDoc = acroApp.GetActiveDoc
      
    'Get the pdDoc of the avDoc.
    Set pdDoc = avDoc.GetPDDoc
      
    intNoPages = pdDoc.GetNumPages
      
    Set pdDoc = Nothing
    Set avDoc = Nothing
    Dim acroApp As Nothing
  


Move Pages in a PDF
Acrobat numbers pages from zero. The first page is zero.

MovePage(x, y) moves single pages.
MovePage(New page No, Old page No)
If x = y then no pages move.

To move a page to the front.
MovePage(0, Old page No)

To move page 4 to page 8.
MovePage(7,3)


To Move Pages In An Already Opened PDF

    Dim acroApp As acroApp
    Dim avDoc As AcroAVDoc
    Dim pdDoc As AcroPDDoc
    Dim bnSuccess As Boolean
        
    'Create an Acrobat object.
    Set acroApp = CreateObject("AcroExch.App")
        
    'Get the already opened PDF file.
    Set avDoc = acroApp.GetActiveDoc
        
    Set pdDoc = avDoc.GetPDDoc
        
    'ie Move to page 4, page 2.
    bnSuccess = pdDoc.MovePage(3, 1)
    'or
    'pdDoc.MovePage 3, 1
        
    Set pdDoc = Nothing
    Set avDoc = Nothing
    Set acroApp = Nothing
    


Moving Through the Pages of a PDF File.
There does not appear to be a defined variable for a collection of Pages.
So you cannot use For each Page in pdDoc.Pages
Instead you must step through the pdf file via each page number.
Remember page 0 is the first page.

    Dim pdDoc As AcroPDDoc
    Dim acroPage As AcroPDPage
    Dim intPageCounter As Integer
        
    Set pdDoc = CreateObject("AcroExch.PDDoc")
        
    'The path is case sensitive.
    pdDoc.Open ("D:\Users\User\Desktop\Test.pdf")
        
    'Get each page.
    For intPageCounter = 0 To pdDoc.GetNumPages - 1
        Set acroPage = pdDoc.AcquirePage(lngPageCounter)
        'Some code goes here.
        Set acroPage = Nothing
    Next intPageCounter
    pdDoc.Close
        
    Set pdDoc = Nothing
    


Rotate a Page
A page in a pdf that has been rotated remembers its degree of rotation.
This previous rotation angle can be determined by using GetRotate.
To return the rotation back to the original angle when the pdf was created you use SetRotate 0.

If a page has already been been rotated to get it to rotate a further 90 degrees use
    acroPage.SetRotate acroPage.GetRotate + 90

    Dim acroApp As Acrobat.acroApp
    Dim pdDoc As Acrobat.AcroPDDoc
    Dim acroPage As AcroPDPage
        
    Set acroApp = New acroApp
    acroApp.Show
    '.Maximize
    'If the argument is a positive number, the Acrobat application is maximized.
    'If the argument is 0 the Acrobat application is returned to its normal state.
    acroApp.Maximize 1
        
    Set pdDoc = New AcroPDDoc
    pdDoc.Open "D:\Users\Graeme\Desktop\Test.pdf"
    pdDoc.OpenAVDoc "Working Doc"
        
    'Set page object
    Set acroPage = pdDoc.AcquirePage(0)
    acroPage.SetRotate 90
        
    'Other Methods & Properties are;
    'acroPage.AddAnnot
    'acroPage.AddNewAnnot
    'acroPage.CopyToClipboard
    'acroPage.CreatePageHilite
    'acroPage.CreateWordHilite
    'acroPage.CropPage
    'acroPage.Draw
    'acroPage.DrawEx
    'acroPage.GetAnnot
    'acroPage.GetAnnotIndex
    'acroPage.GetDoc
    'acroPage.GetNumAnnots
    'acroPage.GetNumber
    'acroPage.GetRotate(Degrees clockwise)
    'acroPage.GetSize
    'acroPage.RemoveAnnot
    'acroPage.SetRotate
        
    Set acroPage = Nothing
    Set pdDoc = Nothing
    Set acroApp = Nothing
    


Reverse the Page Order of a PDF

    Dim acroApp As acroApp
    Dim pdDoc As AcroPDDoc
    Dim intNoPages As Integer
    Dim intInsertPageNo As Integer
        
    Set acroApp = CreateObject("AcroExch.App")
        
    Set pdDoc = CreateObject("AcroExch.PDDoc")
        
    'pdDoc.Open (Case sensitive full path to pdf)
    pdDoc.Open ("C:\Users\User\Desktop\Test.pdf")
        
    'Determine the total number of pages in the original document.
    intNoPages = pdDoc.GetNumPages()
        
    '***************************************************************
    'Important: Acrobat numbers pages from zero being the first page.
    'This makes it confusing.
    '***************************************************************
        
    'Copy a page from the back of pdDoc towards the front of pdDoc.
    'intInsertPageNo does not just move pages but copies them as well.
    'InsertPages(nInsertPageAfter As Long, iPDDocSource As Object, lngStartPage As Long, lnNoPages As Long, lngInsertBookmarks As Long) As Boolean
    'If nInsertPageAfter = -1 then place copy before 1st page.
    'If nInsertPageAfter = 0 then place copy after 1st page.
    'If nInsertPageAfter = 1 then place copy after 2nd page.
    'lngInsertBookmarks = 0 ie False do not merge Bookmarks.
        
    For intInsertPageNo = 1 To intNoPages
        pdDoc.InsertPages intInsertPageNo - 2, pdDoc, intNoPages - 1, 1, 0
    Next intInsertPageNo
        
    'Delete the original pages.
    'DeletePages(nStartPage As Long, nEndPage As Long)
    'For some reason acrobat remembers the page numbers of the original sheets, not their new position.
    pdDoc.DeletePages intNoPages, intNoPages * 2 - 1
        
    'Save the pdf.
    'Insert your path and file name here for the new pdf.
    If pdDoc.Save(PDSaveFull, "C:\Users\User\Desktop\Reversed.pdf") = False Then
        MsgBox "Cannot save the modified pdf."
    End If
        
    pdDoc.Close
    acroApp.Exit
    Set pdDoc = Nothing
    Set acroApp = Nothing
    


Shuffle Pages
Switch the page positions so that the even and odd pages swap positions.

    Dim acroApp As acroApp
    Dim pdDoc As AcroPDDoc
    Dim intNoPages As Integer
    Dim intInsertPageNo As Integer
        
    Set acroApp = CreateObject("AcroExch.App")
    Set pdDoc = CreateObject("AcroExch.PDDoc")
        
    'The pages in pdDoc will be placed in reverse order.
    pdDoc.Open ("C:\Users\User\Desktop\Test.pdf")
    'Determine the total number of pages in the original document.
    intNoPages = pdDoc.GetNumPages()
        
    intInsertPageNo = 0
        
    '***************************************************************
    'Important: Acrobat numbers pages from zero being the first page.
    'This makes it confusing.
    '***************************************************************
        
    'InsertPages(nInsertPageAfter As Long, iPDDocSource As Object, _
    'lngStartPage As Long, lnNoPages As Long, lngInsertBookmarks As Long) As Boolean
    'lngInsertBookmarks = 0 ie False do not merge Bookmarks.
    'Insert the 1st page to the 2nd page. ie Move every 2nd page back.
    For intInsertPageNo = 0 To intNoPages Step 2
        pdDoc.InsertPages intInsertPageNo + 1, pdDoc, intInsertPageNo, 1, 0
        'InsertPages moves a copy of a page but does not delete the original page so it must be deleted.
        'DeletePages(nStartPage As Long, nEndPage As Long)
        pdDoc.DeletePages intInsertPageNo, intInsertPageNo
    Next intInsertPageNo
        
    'Save the pdf. If you want you can save the pdf to another name so as not to alter the original file.
    If pdDoc.Save(PDSaveFull, "C:\Users\User\Desktop\Test.pdf") = False Then
        MsgBox "Cannot save the modified document"
    End If
        
    pdDoc.Close
    acroApp.Exit
    Set pdDoc = Nothing
    Set acroApp = Nothing
    

Issue date 2021_09_25