These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

Troubleshooting Calculations

HR Lady4
Registered: Nov 2 2010
Posts: 25

Ok so new problem.
 
I'm using Acrobat 9 Pro.
 
I have a text field called " Score" and a second text field called "Score 1"
 
Score and Score 1 are currently averaging numbers from combo boxes. At the end of my form I have (2) text fields called "Section 1" and "Section 2". Section 1 is pulling the number from "Score" and Section 2 is pulling the number from "Score 1". I then have another text field entitled "Overall Rating" and that field is averaging the numbers in Section 1 and Section 2. My problem is that because my "Score" is able to be blank, it puts in a zero in "Section 1" and therefore my total average score in my "Overall Rating" is counting the zero.
 
So example:
If Section 1=0
Section 2=3
My Overating Rating is saying =1.5
It should say 3 because I don't want Section 1 to count if it is blank.
Please help!!

My Product Information:
Acrobat Pro 9.0, Windows
gkaiseril
Expert
Registered: Feb 23 2006
Posts: 4307
What are the values that could be averaged?

What are the possible range of averaged values?

Can you force the value of the average to a null if no average is computed?

Allowing for a null average would allow for an average of zero if this is a possible computation result that should be included in a later calculation but a null value could then be excluded from other calculations.

George Kaiser

HR Lady4
Registered: Nov 2 2010
Posts: 25
So in my first section I have Rating 1, Rating 2, Rating 3, Rating 4, and Rating 5. Each of those combo boxes have scores from 1-5 with .25 incriments (So 1, 1.25, 1.50, 2, etc.)

In my second section I have Rating 6-12 with the same values of 1-5 with .25 incriments.

How would I force the value to a null when averaged?

I do have a script in my first section entitled "Score"
It follows:
// Custom calculate script for text field
(function () {

var v;
var count = 0;
var sum = 0;

// Loop through combo boxes
for (var i = 1; i < 6; i++) {
v = getField("Rating " + i).value;
if (v !== " ") {
count++; // Increment counter
sum += v; // Add value to sum
}
}

// Calculate average
if (count) {
event.value = sum / count;
} else {
event.value = "";
}

})();

gkaiseril
Expert
Registered: Feb 23 2006
Posts: 4307
Since you are repeating a count, sum, and divide or average calculation multiple times, I would have used a couple of document level functions. Also since only the values or fields names change for the calculations one could create a parameter of an array and then process the values or names in the array.
  1. function FieldNames2Values(aNames) {
  2. /*
  3. from the list of passed field names
  4. create an array of the values of those
  5. fields as a string variable
  6. */
  7. var aValues = new Array();
  8. // loop through the names
  9. for(i = 0; i < aNames.length; i++) {
  10. // get the value of the named field
  11. aValues[i] = this.getField(aNames[i]).valueAsString;
  12. } // end for loop array names
  13. return aValues;
  14. } // end FieldNamee2Values
  15.  
  16. function Count(aValues) {
  17. /*
  18. count the number of values that are numbers
  19. excluding any blanks, nulls, or other Not a Number values
  20. */
  21. // a variable to count the number of numeric values
  22. var nCount = 0;
  23. // loop through array of values
  24. for(i = 0; i < aValues.length; i++) {
  25. // test for non blank, not null and not NaN
  26. if( (aValues[i] != "") & (aValues[i] != " ") & (!isNaN(aValues[i]) ) ) {
  27. // count the passed item
  28. nCount++
  29. } // end if not null, not blank, not NaN
  30. } // end for loop of values
  31. // if no items counted force result to Null
  32. if (nCount == 0) nCount = '';
  33. // return the computed count
  34. return nCount;
  35. } // end Count
  36.  
  37. function Sum(aValues) {
  38. /*
  39. sum the number of values that are numbers
  40. excluding any blanks, nulls, or other Not a Number values
  41. */
  42. // variable for the computed sum
  43. var nSum = 0;
  44. // loop through the fields
  45. for(i = 0; i < aValues.length; i++) {
  46. // test for non blank, not null and not NaN
  47. if( (aValues[i] != "") & (aValues[i] != " ") & (!isNaN(aValues[i]) ) ) {
  48. // sum the passed item
  49. nSum += Number(aValues[i]);
  50. } // end if not null, not blank, not NaN
  51. } // end for loop of values
  52. // if sum is zero force to null
  53. if (nSum == 0) nSum = "";
  54. // return computed sum
  55. return nSum;
  56. } // end Sum
  57.  
  58. function Average(aValues) {
  59. /*
  60. compute the average excluding null, spaces and other Not a Number values
  61. */
  62. // variable for result
  63. var nAverage = "";
  64. // count the values
  65. var nCount = Number(Count(aValues));
  66. // if counted items then compute average
  67. if(nCount != 0) {
  68. // compute the average with the sum and count of the numeric values
  69. nAverage = Number(Sum(aValues)) / nCount;
  70. } // end compute average
  71. // return the computed average or null if no average computed
  72. return nAverage;
  73. } // end Average

The custom calculation for "Score 1" is then:
  1. event.value = Average(FieldNames2Values(["Rating 1", "Rating 2",
  2. "Rating 3", "Rating 4", "Rating 5"]) );

The custom calculation for "Score 2" is:
  1. event.value = Average(FieldNames2Values(["Rating 6", "Rating 7",
  2. "Rating 8", "Rating 9", "Rating 10", "Rating 11", "Rating 12"]) );

And the custom calculation for the overall score is:
The custom calculation for "Score 2" is:
  1. event.value = Average(FieldNames2Values(["Score 1", "Score 2"]) );

George Kaiser

HR Lady4
Registered: Nov 2 2010
Posts: 25
I cut and pasted all of the scripts and they aren't working.

It confusing to explain versus visually seeing it.

So I have a 3 page pdf.
Page 1- I have a section of goals that have rating scales next to them. The ratings go from 1,1.25,1.50,1.75,2.00, etc... up to 5. I also have a blank rating that is the default.
I currently have a script that is working where if a goal isn't filled out them it won't count in the average.
So I have combo box fields, "Rating 1, Rating 2, Rating 3, Rating 4, Rating 5. Then I have a text field called "Score" which averages up the ratings.

Page 2- I have (7)combo boxes with the same rating scale of 1-5. The are called "Rating 6-12" Then I have a "Score 1" at the botton that is averaging those fields.

Page 3- I have a text field called "Section 1" which pulls the "Score" from page 1.
I have another text field bellow called "Section 2" which pulls the Score 1" from page 2.
Then I have a text field called "Overall Rating" which averages out the "Section 1" and "Section 2" score.

However if the "Section 1 or 2" is 0 or blank, I don't want it to count towards the "Overall Rating"

Hope I explained it better.
gkaiseril
Expert
Registered: Feb 23 2006
Posts: 4307
See Sum Numeric Values Only for a working example with drop down and text fields.It is hard to properly cut and paste code from the revised forum.

The document level scripts:

function FieldNames2Values(aNames) {
/*
from the list of passed field names
create an array of the values of those
fields as a string variable
*/
var aValues = new Array();
// loop through the names
for(i = 0; i < aNames.length; i++) {
// get the value of the named field
aValues[i] = this.getField(aNames[i]).valueAsString;
} // end for loop array names
return aValues;
} // end FieldNamee2Values

function Count(aValues) {
/*
count the number of values that are numbers
excluding any blanks, nulls, or other Not a Number values
*/
// a variable to count the number of numeric values
var nCount = 0;
// loop through array of values
for(i = 0; i < aValues.length; i++) {
// test for non blank, not null and not NaN
if( (aValues[i] != "") & (aValues[i] != " ") & (!isNaN(aValues[i]) ) ) {
// count the passed item
nCount++
} // end if not null, not blank, not NaN
} // end for loop of values
// if no items counted force result to Null
if (nCount == 0) nCount = '';
// return the computed count
return nCount;
} // end Count

function Sum(aValues) {
/*
sum the number of values that are numbers
excluding any blanks, nulls, or other Not a Number values
*/
// variable for the computed sum
var nSum = 0;
// loop through the fields
for(i = 0; i < aValues.length; i++) {
// test for non blank, not null and not NaN
if( (aValues[i] != "") & (aValues[i] != " ") & (!isNaN(aValues[i]) ) ) {
// sum the passed item
nSum += Number(aValues[i]);
} // end if not null, not blank, not NaN
} // end for loop of values
// if sum is zero force to null
if (nSum == 0) nSum = "";
// return computed sum
return nSum;
} // end Sum

function Average(aValues) {
/*
compute the average excluding null, spaces and other Not a Number values
*/
// variable for result
var nAverage = "";
// count the values
var nCount = Number(Count(aValues));
// if counted items then compute average
if(nCount != 0) {
// compute the average with the sum and count of the numeric values
nAverage = Number(Sum(aValues)) / nCount;
} // end compute average
// return the computed average or null if no average computed
return nAverage;
} // end Average

Score 1:
event.value = Average(FieldNames2Values(["Rating 1", "Rating 2", "Rating 3", "Rating 4", "Rating 5"]) );

Score 2:
event.value = Average(FieldNames2Values(["Rating 6", "Rating 7", "Rating 8", "Rating 9", "Rating 10", "Rating 11", "Rating 12"]) );

Overall average:
event.value = Average(FieldNames2Values(["Score 1", "Score 2"]) );

George Kaiser

HR Lady4
Registered: Nov 2 2010
Posts: 25
Yea! It seems to be working so far.
HR Lady4
Registered: Nov 2 2010
Posts: 25
Last question,

When I save the file and email it to someone, they say they can only save a blank copy. Why is that?

gkaiseril
Expert
Registered: Feb 23 2006
Posts: 4307
They have Reader and you have not provided a copy of the form with "Extended Reader Rights".

George Kaiser

HR Lady4
Registered: Nov 2 2010
Posts: 25
For some reason after I saved the file the formulas aren't working.

So page 1: "Score" I put in
// Custom calculate script for text field
(function () {

var v;
var count = 0;
var sum = 0;

// Loop through combo boxes
for (var i = 1; i < 6; i++) {
v = getField("Rating " + i).value;
if (v !== " ") {
count++; // Increment counter
sum += v; // Add value to sum
}
}

// Calculate average
if (count) {
event.value = sum / count;
} else {
event.value = "";
}

})();

Page 2 under "Score 1" I put:
event.value = Average(FieldNames2Values(["Rating 6", "Rating 7", "Rating 8", "Rating 9", "Rating 10", "Rating 11", "Rating 12"]) );

Page 3 under "Overall rating" I put:
event.value = Average(FieldNames2Values(["Section 1", "Section 2"]) );

HR Lady4
Registered: Nov 2 2010
Posts: 25
I downloaded the pdf file you sent. When I add in the calculation under my own field, nothing pops up. It is blank.
Where you talk about the document level functions, do I use all those codes under one field or seperate them?
HR Lady4
Registered: Nov 2 2010
Posts: 25
Got it to work. Thank you for your help.
gkaiseril
Expert
Registered: Feb 23 2006
Posts: 4307
For document level functions, there is a special document area for this code, So where does JavaScript live in Acrobat?" and Entering Document Scripts by Thom Parker. Placing the function scripts in this special location will allow Acrobat to initialize this code and make it available to all form fields. Placing a function in a form field will keep the function uninitialized and not available until that form field is processed. This can result in a function never being initialized because the location of the code within field where the code is located is never accessed or processed.Acrobat JavaScript is an interpretive language so the code needs to be syntax scanned and tokenized before it can be processed and this process only occurs as the individual pieces of code are encountered in the normal processing of the PDF.

George Kaiser