6 Replies Latest reply on May 15, 2016 7:40 PM by Madmaxneo

    How do I turn the following script into a Document Level Javascript?

    Madmaxneo Level 1

      Here is the current script that I have in a button:

       for (var i=0;i<115;i++) 
      { 
      this.getField("Ranks"+i).value= 
      this.getField("Ranks"+i).value+ 
      this.getField("RanksA"+i).value; 
      this.getField("RanksA"+i).value=0; 
      }
      

      I would like to change this into a DLJ that is only called when I hit a button. But I have not been able to figure it out.

       

      I am thinking that the following may work:

      function returnAddRnksArray(num) 
      { 
      for (var i=0;i<115;i++) 
      {this.getField("Ranks"+i).value= 
      this.getField("Ranks"+i).value+ 
      this.getField("RanksA"+i).value; 
      this.getField("RanksA"+i).value=0; 
              return [-18, 0.25];}
      }
      

      But I am not sure how to use a button to call that function.

       

      The reason I am trying to do this is because the first script I have is really slow when calculating the entire document. As it was explained by others here DLJ's can be faster. This is simply an idea I have to speed up the sheet some. I am not really sure how to have it only call the function when I hit the button and not when I first open the PDF.

        • 1. Re: How do I turn the following script into a Document Level Javascript?
          gkaiseril MVP & Adobe Community Professional

          Have you looked at the MDN JavaScript Reference for the function object or the function statement?

           

          You define the function using the "function" statement and give the function a name and optional input parameters. One uses the optional return statement to end a function or end and return an optional value.

           

          I see no use of the "num" parameter, so it might not be necessary and if not supplied will throw an error on execution of the function.

           

          Once a function has been defined it can be executed at any time or in any action by calling the function's name. In your case

           

          // define  the function;

          function returnAddRnksArray(num)  
          {  

          / *

          explaination of the functions purpose, inputs, and returned outputs;

          */

           

          for (var i=0;i<115;i++)  
          {
          this.getField("Ranks"+i).value=  
          this.getField("Ranks"+i).value+  
          this.getField("RanksA"+i).value;  
          this.getField("RanksA"+i).value=0; 
                  return [-18, 0.25];} 

           

          // call the function and set the value of a new variable;

          var aNumber = new Array( returnAddRnksArray(123));
          console.println(aNumber.join("; "));

          • 2. Re: How do I turn the following script into a Document Level Javascript?
            Madmaxneo Level 1

            Thanks, I will look at that when I get the chance. One thing though. I noticed there is an extra line in the last section above that reads "return [-18, 0.25];".

            But it should read "return value;".

             

            After looking over the sheet I think I realized why it is so slow when doing that calculation. And if I am correct changing that function above to a button that calls a DLJ will not speed up the document any.

            I will try to explain. I will use a single line but this is actually done 115 times.

            In the script above I describe the fields "RanksA" and "Ranks" for this explanation I will use row "1", meaning "RanksA1" and so one where the "1" replaces the "+i" addition for the entire set of 115 fields.

            In this row there are the following fields:

            Ranks1, Rank Bns.1, Stat Bns.1, Spec Bns.1 and Total Bns.1

            Where:

            Rank Bns.1 value is determined from the value in Ranks1

            Stat Bns.1 value is determined from the value of the two stats it represents

            Spec Bns.1 value is determined from the value of other fields that are input manually

            Total Bns.1 value is determined by adding all the above values together. This calculation is in a consolidated script box and automatically calculated every time a number changes.

            Now every time I hit the button with the script at the beginning of this thread the sheet automatically does all those calculations for each and every single 115 rows. It starts with adding the new ranks from RanksA1 to Ranks1 and then clearing out RanksA1. The fact that it changes Ranks1 is what causes each line to be recalculated even if there are no changes.

            I am wondering if the sheet would calculate faster if I just put the script or formulas in the fields they pertain to instead of either in a DLJ or a consolidated script box. For example; I would put the script that adds all those fields together in the Total Bns.1 field. I would have to write all these scripts out for each individual field.

             

            But do you think that may speed up the sheet some?

            • 3. Re: How do I turn the following script into a Document Level Javascript?
              maxwyss Level 4

              Just commenting on the last paragraph:

               

              Definitely NOT in individual fields (because of the way the field event processing sequence in Acrobat works).

               

              Therefore, if the recalculation should happen regularly (meaning with every change of some field contents in the document), the script would be in the Calculate event of a hidden, readonly field, otherwise not involved in the whole calculation.

               

              If the recalculation should happen only at specific events (pageOpen, documentOpen, etc.), it should be attached to that event.

               

              Document-level function or in field? Definitely define a document-level function, which can be called from the field. As it has been mentioned, the Document-level function is interpreted once, and then available for whenever it is called, it will be faster than if it had to be interpreted every time the script gets called.

               

              Additional ways to speed up:

               

              • instead of doing the calculations in many field rows, manage the data in a 2-dimensional array, and only when the calculations are done, refresh the fields from the array. Note that arrays can not be stored in the file but only strings (or streams), which means that you will have to concatenate the arrays into strings when you are saving (at latest), and recreate them when opening the file.

               

              • while field values are processed, and especially if fields are shown or hidden based on that processing, suppress the refresh by embracing the part of the script with this.delay = true and this.delay = false.

               

              • to suppress excessive useless recalculations, suppress them by embracing the part of the script with this.calculate = false and this.calculate = true, followed by this.calculateNow to force the recalculation.

               

              Hope this can help.

              • 4. Re: How do I turn the following script into a Document Level Javascript?
                Madmaxneo Level 1

                I use the following in the consolidated script I have:

                this.delay = true ;
                this.calculate = false ;
                

                at the beginning, and

                this.calculate = true ;
                this.delay = false ;
                

                at the end.

                 

                You mention:

                Therefore, if the recalculation should happen regularly (meaning with every change of some field contents in the document), the script would be in the Calculate event of a hidden, readonly field, otherwise not involved in the whole calculation.

                 

                The calculation of the fields "Total Bns" +i (0 through 114) does happen regularly. So as soon as any of the other numbers are changed (e.g. "Ranks" +i) it causes the calculation order to recycle. What I believe is happening is that there are "Ranks"+i fields that do not get changed but they cycle anyway and that causes the whole script to also cycle which slows the whole document down. That calculation is in a consolidated script field with about 1000 lines of other script/code that also happens regularly.

                 

                The reason I mention using individual field calculations is because when the "Total Bns" +i calculation for all 114 fields is in a consolidated script does it not automatically go through the whole calculation process when even one number is changed? That is using this calculation script in the consolidated script I mentioned earlier:

                for (var i=0;i<115;i++)   
                this.getField("Ranks"+i).value=   
                this.getField("Ranks"+i).value+   
                this.getField("RanksA"+i).value;   
                this.getField("RanksA"+i).value=0;  
                

                That is also with the this.delay=true to suppress excessive processing.

                • 5. Re: How do I turn the following script into a Document Level Javascript?
                  gkaiseril MVP & Adobe Community Professional

                  I would check the Acrobat JavaScript console for any errors and check your field calculation order. You may have another calculation whose result is used in the calculation not being updated until after the consolidated field has been computed.

                   

                  I set the return value to the array of [-18, 0.25] because that was in the code provided.

                  • 6. Re: How do I turn the following script into a Document Level Javascript?
                    Madmaxneo Level 1

                    Yeah the [-18,0.25] was my fault.

                     

                    Ever since I had to load up the new DC I have not even messed with the Acrobat Javascript console.