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

Convert Excel "Large" Function to JavaScript

bettymac
Registered: Mar 13 2009
Posts: 19
Answered

Hi, I'm creating a form with a calculation that basically equals the "Large" function in Excel. For example, I need the 'Total' Field to be the sum of the 3 highest amounts from 4 amount fields. I've been looking everywhere for an example, but can't find anything. Is there any way to convert this formula to JavaScript?? I'm clueless! Thanks very much!

My Product Information:
Acrobat Pro 8.1, Windows
try67
Expert
Registered: Oct 30 2008
Posts: 2398
Let's say you have the 4 values in 4 variables: field1, field2, field3, field4;
You put them in an array, sort it, and then grab just the last 3 three items.
var arr = new Array(field1, field2, field3, field4);
arr.sort();
var result = arr[1]+arr[2]+arr[3];

- AcrobatUsers Community Expert - Contact me personally at try6767 [at] gmail [dot] com
Check out my custom-made scripts website: http://try67.blogspot.com

gkaiseril
Online
Expert
Registered: Feb 23 2006
Posts: 4307
Try67,

I believe you need to provide a compare function to sort the array descending and JavaScirpt array elements are numbered using the zero base.

George Kaiser

try67
Expert
Registered: Oct 30 2008
Posts: 2398
If the array contains numbers you can sort it as is. If the fields are strings you just need to multiple them by one before adding to the array. I'm aware of the fact that arrays are 0-based. I purposefully ignored the first element (element 0) to get the three highest ones, which is what the OP wanted to achieve.

- AcrobatUsers Community Expert - Contact me personally at try6767 [at] gmail [dot] com
Check out my custom-made scripts website: http://try67.blogspot.com

gkaiseril
Online
Expert
Registered: Feb 23 2006
Posts: 4307
Well that would work as long as your numbers all have the same number of digits, but might not always work.

For example using the values of 1, 2, 100, 45, 55, 66,77 and your code

var arr = new Array(1, 2, 100, 45, 55, 66, 77); console.println('arry unsorted: ' + arr.join(', ') );var result = arr[1] + arr[2] + arr[3];console.println(   result) // sort arrayarr.sort();console.println('array sorted: ' + arr.join(', ') );// compute resultvar result = arr[1] + arr[2] + arr[3];console.println(   result)

Returns the following results:

Quote:
arry unsorted: 1, 2, 100, 45, 55, 66, 77
147
array sorted: 1, 100, 2, 45, 55, 66, 77
147

true
Because JavaScript is trying to sort as a numeric string value and not a numberic value. But the top three nubmers are 100, 77, and 6 and their sum is 243.

George Kaiser

try67
Expert
Registered: Oct 30 2008
Posts: 2398
You're right about the sorting function not working properly here. I wasn't aware of this issue.
But you've also made an error in adding items 1, 2, 3 because your array has more then 4 items.
In fact it should be items 'last', 'last-1', 'last-2'...

- AcrobatUsers Community Expert - Contact me personally at try6767 [at] gmail [dot] com
Check out my custom-made scripts website: http://try67.blogspot.com

gkaiseril
Online
Expert
Registered: Feb 23 2006
Posts: 4307
I find the following generalized method works and meets the need of the OP:

// sort numeric descending compare functionfunction compareNumbersDescending(a, b) {return Number(b) - Number(a);}// end sort numeric descending compare function // Large funcitonfunction Large(aValues, nValues) {// returns the largest nValues  from the array of vlaus aValues// sort the array aValuesaValues.sort(compareNumbersDescending);// compute the sum of the first nValuesvar sum = 0;for(i = 0; i < nValues; i++) {sum += Number(aValues[i]);}return sum; // return sum} // end Large Function  // define an array of valuesvar arr = new Array(1, 2, 100, 45, 55, 66, 77, 5); console.println('arry unsorted: ' + arr.join(', ') );var result = arr[1] + arr[2] + arr[3];console.println(   result) // sort arrayarr.sort();console.println('array sorted: ' + arr.join(', ') );// compute resultvar result = arr[1] + arr[2] + arr[3];console.println(   result) // sort arrayarr.sort(compareNumbersDescending);console.println('array sorted numeric descending: ' + arr.join(', ') );// compute resultvar result = arr[0] + arr[1] + arr[2];console.println(   result)// print large for various large n itemsconsole.println('Large 1: ' + Large(arr, 1) );console.println('Large 2: ' + Large(arr, 2) );console.println('Large 3: ' + Large(arr, 3) );console.println('Large 4: ' + Large(arr, 4) );console.println('Large 5: ' + Large(arr, 5) );console.println('Large 6: ' + Large(arr, 6) );console.println('Large 7: ' + Large(arr, 7) );console.println('Large 7: ' + Large(arr, 8) );

And this produces the following results:

Quote:
arry unsorted: 1, 2, 100, 45, 55, 66, 77, 5
147
array sorted: 1, 100, 2, 45, 5, 55, 66, 77
147
array sorted numeric descending: 100, 77, 66, 55, 45, 5, 2, 1
243
Large 1: 100
Large 2: 177
Large 3: 243
Large 4: 298
Large 5: 343
Large 6: 348
Large 7: 350
Large 7: 351

true

George Kaiser

try67
Expert
Registered: Oct 30 2008
Posts: 2398
Nicely done.

- AcrobatUsers Community Expert - Contact me personally at try6767 [at] gmail [dot] com
Check out my custom-made scripts website: http://try67.blogspot.com

bettymac
Registered: Mar 13 2009
Posts: 19
thanks very much to both of you, but I have no clue how to apply this to my form. i have fields Total1, Total2, Total3 & Total4 that I need to sum the 3 highest values of those 4. Do I need to replace something in your code with those field names?? sorry...I'm JavaScript impaired.
gkaiseril
Online
Expert
Registered: Feb 23 2006
Posts: 4307
There are a couple of things you need to do.

1. Enter the following code, 2 funcitons, as a document level script, [link:www.acrobatusers.com/tutorials/2007/07/js_document_scripts]Entering Document Scripts[/url]:

// sort numeric ascending compare functionfunction compareNumbers(a, b) {return Number(a) - Number(b);}// end sort numeric descending compare function // Large funcitonfunction Large(aValues, nValues) {// returns the largest nValues  from the array of values aValues// sort the array aValuesaValues.sort(compareNumbers);// reverse the sort results - descending orderaValues.reverse();// compute the sum of the first nValuesvar sum = 0;for(i = 0; i < nValues; i++) {sum += Number(aValues[i]);}return sum; // return sum} // end Large Function

You then will need a custom calculation script to place the values of the the fields to order and sum into an array and call the 'Large()' function:

// build array of values to find the sum of the largest values fromvar fMyArray = new Array(this.getField('Total1').value,this.getField('Total2').value,this.getField('Total3').value,this.getField('Total4').value);// sum the 3 largest valuesevent.value = Large(fMyArray, 3); // sum the 3 largest values

George Kaiser

bettymac
Registered: Mar 13 2009
Posts: 19
WOW!!!! I DID IT. IT WORKED. THANKS SO MUCH!!!