6 Replies Latest reply on Jun 27, 2014 2:55 PM by George_Johnson

    JavaScript and VBA: The Saga Continues - A JSObject Question.

    MaxCO2012 Level 1

      The JavaScript code below, in concjunction with some VBA code, applies a PDF417 barcode image to the upper right hand corner of a PDF. Based on some clever suggestions by George Johnson and Gilad D I'm first adding a button field to the document, and then adding an icon to that button; the icon being a flattened PDF that contains the barcode image. The creation of the barcode image PDF is a whole other story, which I can post if anyone cares.

       

      The JS code works well when I run it with a PDF open and I choose “Apply Barcode” from the newly created menu item. Incidentally, it also works when I run it from the console. Also, based on what I've read (thanks Karl Kremer), one can't call the "InsertPDF417Barcode" function directly from VBA, hence the creation of a new menu item and the reference to the intermediate function "myAdd417Barcode".

       

      So, what I am working to do is to execute this script from a VBA sub, which is also listed below. But, when the “jso.myAdd417Barcode” line (in the VBA code) executes (or doesn't) I get an error – “doc is undefined”, which is clearly an Acrobat error being thrown.

       

      Isn’t “doc” being “defined” by having “this” in my “app.addMenuItem” line? Suggestions?

       

      Any help will be greatly appreciated.

       

      Thanks.

       

      My JS Code (in a folder-level script):

      var InsertPDF417Barcode = app.trustedFunction( function(doc)

                      {

                                      app.beginPriv();

                                                      var bcIconFileName = "/C/Temp/bcTmpImage.pdf";

                                                      var t = doc.addField("bcFormID", "button", 0, [396, 756, 576, 720]);

                                                                      t.display = display.visible;

                                                                      t.buttonPosition = position.iconOnly;

                                                                      t.buttonScaleHow = scaleHow.proportional;

                                                                      t.buttonScaleWhen = scaleWhen.always;

                                                                      t.buttonFitBounds = true;

                                                                      t.setButtonIcon

                                                      var x = doc.importIcon("myIcon", bcIconFileName, 0);

                                                      var f = doc.getField("bcFormID");

                                                      var i = doc.getIcon("myIcon")

                                                      var y = f.buttonSetIcon(i);

                                      app.endPriv();

                      });

       

      function myAdd417Barcode(doc)

                      {

                                      InsertPDF417Barcode(doc);

                      }

       

      var menuParent = (app.viewerVersion<10)? "DocumentProcessing":"Edit";

                      app.addSubMenu({

                                      cName:"myTools",

                                      cUser:"My Custom Tools",

                                      cParent:menuParent,

                                      nPos:((app.viewerVersion<10)? 0:7)

                                      });

                      app.addMenuItem({

                                      cName:"myPDF417Barcode",

                                      cUser:"Apply Barcode",

                                      cParent:"myTools",

                                      cExec:"myAdd417Barcode(this);",

                                      nPos:1

                                      });

       

      My VBA Code:

      Sub BarcodeDoc_PDF417(pdfFileName As String)

          Dim AVDoc As Acrobat.CAcroAVDoc

          Dim PDDoc As Acrobat.CAcroPDDoc

          Dim myApp As Acrobat.CAcroApp

          Dim jso As Object

          Dim bcTmpFile As String

              bcTmpFile = "C:\Temp\bcTmpFile.pdf"

              Set myApp = CreateObject("AcroExch.App")

              Set AVDoc = CreateObject("AcroExch.AVDoc")

                  If AVDoc.Open(pdfFileName, "") Then

                      Set PDDoc = AVDoc.GetPDDoc

                      Set jso = PDDoc.GetJSObject

                           jso.myAdd417Barcode

                           PDFSave PDDoc, bcTmpFile

                           myApp.CloseAllDocs

                           myApp.Exit

                      Set AVDoc = Nothing

                      Set jso = Nothing

                      Set PDDoc = Nothing

                      Set myApp = Nothing

                  Else

                      MsgBox "Document not found:" & vbCrLf & pdfFileName

                  End If

      End Sub

        • 1. Re: JavaScript and VBA: The Saga Continues - A JSObject Question.
          Test Screen Name Most Valuable Participant

          You need to use "this" with a lot of care; the JavaScript API tells you when it is valid. Other times it might work, but causes horrible traps. You use "this" in

          app.addMenuItem({

                                          cName:"myPDF417Barcode",

                                          cUser:"Apply Barcode",

                                          cParent:"myTools",

                                          cExec:"myAdd417Barcode(this);"

          ...

          and I doubt that is a valid context for "this". The whole point of passing "doc" into the routines that were created was to avoid using "this" in a bad context.

          • 2. Re: JavaScript and VBA: The Saga Continues - A JSObject Question.
            Test Screen Name Most Valuable Participant

            Also, why can't you use myPDF417Barcode from JavaScript? Do you have a reference for this? (You might be right, but it seems surprising).

            • 3. Re: JavaScript and VBA: The Saga Continues - A JSObject Question.
              Karl Heinz Kremer Adobe Community Professional

              Let's take a look at your code:

               

                             Set jso = PDDoc.GetJSObject

                              jso.myAdd417Barcode

                              PDFSave PDDoc, bcTmpFile

               

              Your function definition of myAdd417Barcode requires the doc variable being passed in. You are not doing this, so that may be the reason for your error message. In the next line, you are calling PDFSave, which is not one of the IAC API function, I assume you mean PDDoc.Save

               

              Based on my experience, you do not have to pass in the "this" pointer to a function you call via the jso. This means you can rewrite your JS code like this:

               

                   function myAdd417Barcode()

                   {

                           InsertPDF417Barcode(this);

                    }

               

              This should then work with the VBA code to call myAdd417Barcode.

              • 4. Re: JavaScript and VBA: The Saga Continues - A JSObject Question.
                MaxCO2012 Level 1

                Thanks Karl.

                 

                PDFSave is actually a sub I wrote in VBA that does a little more than save the PDF. It makes use of the PDDoc.Save IAC function, but also "kills" the PDF if it already exists, etc.

                 

                I took a lot of what I put together from your "ramblings" site and some stuff from a few others. I suppose I misunderstood some of what I read.

                 

                Thanks for your input. Iw ill adjust and give it a go.

                 

                Thanks also TSN. Yes, I get that the use of "this" can be problematic, but I ran across a thread that laid things out this way so I gave it a try. Not being able to call my JavaScript routine directly from the JSObject was also something I read. That's why I am going through a menu item. I suppose I can try it the other way, I was just trusting the author. This is the link to which I am referring:

                 

                Acrobat, JavaScript and VB walk into a bar… | Karl Heinz Kremer's Ramblings

                • 5. Re: JavaScript and VBA: The Saga Continues - A JSObject Question.
                  MaxCO2012 Level 1

                  Update.

                   

                  Karl's suggestion works perfectly. Thanks again!

                   

                  Also, I think I misunderstood the whole menu thing. I took it out and all is well.

                  • 6. Re: JavaScript and VBA: The Saga Continues - A JSObject Question.
                    George_Johnson MVP & Adobe Community Professional

                     

                    You need to use "this" with a lot of care; the JavaScript API tells you when it is valid. Other times it might work, but causes horrible traps. You use "this" in

                    app.addMenuItem({

                                                    cName:"myPDF417Barcode",

                                                    cUser:"Apply Barcode",

                                                    cParent:"myTools",

                                                    cExec:"myAdd417Barcode(this);"

                    ...

                    and I doubt that is a valid context for "this". The whole point of passing "doc" into the routines that were created was to avoid using "this" in a bad context.

                     

                    That's the correct way to pass a document object for code triggered by a custom menu item that affects the current document.