Im learning JS and Google apps script. Im just working on examples to help learn. Something Im sure is simple that Im stuck on. Is there a way to print out Dell and HP count using the same variable? I know I could add a second variable counter2 and use that but just looking understand preferred methods . I tried to comment out what I have tried. The sheet Im referencing has 100 Dell and 400 HP.
var ss= SpreadsheetApp.getActiveSpreadsheet();
var es = ss.getSheetByName("School1");
var ms = ss.getSheetByName("School2");
var hs = ss.getSheetByName("School3");
var esValues = es.getDataRange().getValues();
var counter = 0;
//var esValues = es.getRange('A:C').getValues();
Logger.log(esValues.length);
for(var i = 0; i < esValues.length; i++){
var data= esValues[i];
var first = data[1];
var last = data[0];
var middle = data[2];
var studentid = data[3];
var device = data[4];
if(device.includes("Dell")){
counter++;
//Logger.log(`Dell count is ${counter}`); //When add here it prints same line 100+ times
} else if(device.includes("HP")){
counter++;
}
}
Logger.log(`Dell count is ${counter}`)//Printing same count 500
Logger.log(`Hp count is ${counter}`)//Printing same count 500
}```
So when logging the total of two different items using one variable isn't the way to do it. In your case both of your conditions will increase counter so while your for loop goes through it will always bump counter so it will hit 500 which is the total number of devices. Try something like this.
var ss= SpreadsheetApp.getActiveSpreadsheet();
var es = ss.getSheetByName("School1");
var ms = ss.getSheetByName("School2");
var hs = ss.getSheetByName("School3");
var esValues = es.getDataRange().getValues();
var counterDell = 0;
var counterHP = 0; // New for just HP
//var esValues = es.getRange('A:C').getValues();
Logger.log(esValues.length);
for(var i = 0; i < esValues.length; i++){
var data= esValues[i];
var first = data[1];
var last = data[0];
var middle = data[2];
var studentid = data[3];
var device = data[4];
if(device.includes("Dell")){
counterDell++;
//Logger.log(`Dell count is ${counter}`); //When add here it prints same line 100+ times
} else if(device.includes("HP")){
counterHP++;
}
}
Logger.log(`Dell count is ${counterDell}`)//Printing same count 500
Logger.log(`Hp count is ${counterHP}`)//Printing same count 500
}
When there are only HP and Dells in device field, it could be resolved.
But if there are more values can be used in device field, there is no solution rather than using two counters.
If only HD and Dells are used, try this one.
var ss= SpreadsheetApp.getActiveSpreadsheet();
var es = ss.getSheetByName("School1");
var ms = ss.getSheetByName("School2");
var hs = ss.getSheetByName("School3");
var esValues = es.getDataRange().getValues();
var counter = 0;
//var esValues = es.getRange('A:C').getValues();
Logger.log(esValues.length);
for(var i = 0; i < esValues.length; i++){
var data= esValues[i];
var first = data[1];
var last = data[0];
var middle = data[2];
var studentid = data[3];
var device = data[4];
if(device.includes("Dell")){
counter++;
}
}
Logger.log(`Dell count is ${counter}`)
Logger.log(`Hp count is ${esValues.length - counter}`)
}```
Related
I have a sheet with over 3000 points (lat, long). I am running the following code to calculate distance of each point from 9 reference points and writing the minimum distance next to each point in the sheet. The code runs fine but is slow and times out before running for all the points. How can I make the following code more efficient - so that it reads, computes and writes back the data faster?
/*
******************************
Reference Points
Point_A 41.166866 -76.151926
Point_B 41.087500 -76.204694
Point_C 40.540960 -75.704900
Point_D 40.401080 -75.589600
Point_E 40.326130 -75.642500
Point_F 40.167480 -75.921500
Point_G 40.093370 -76.084700
Point_H 39.974450 -76.063000
Point_I 39.722350 -76.156000
********************************
*/
var SpreadsheetID = "ABC";
var SheetName = "XYZ";
function DistanceCalculator() {
var ss = SpreadsheetApp.openById(SpreadsheetID)
var sheet = ss.getSheetByName(SheetName);
//Select the column
var columnToCheck = sheet.getRange("A:A").getValues();
// Get the last row in the column
var lastRow = getLastRowSpecial(columnToCheck);
// Ref point latitude
var Latitude_Point_A = 41.166866;
var Latitude_Point_B = 41.087500;
var Latitude_Point_C = 40.540960;
var Latitude_Point_D = 40.401080;
var Latitude_Point_E = 40.326130;
var Latitude_Point_F = 40.167480;
var Latitude_Point_G = 40.093370;
var Latitude_Point_H = 39.974450;
var Latitude_Point_I = 39.722350;
// Ref point longitude
var Longitude_Point_A = -76.151926;
var Longitude_Point_B = -76.204694;
var Longitude_Point_C = -75.704900;
var Longitude_Point_D = -75.589600;
var Longitude_Point_E = -75.642500;
var Longitude_Point_F = -75.921500;
var Longitude_Point_G = -76.084700;
var Longitude_Point_H = -76.084700;
var Longitude_Point_I = -76.156000;
for( var i=1; i<=lastRow;i++){
//Reading Lat_Long from the sheet
var Lat_Check = sheet.getRange(i,2).getValue();
var Long_Check = sheet.getRange(i,3).getValue();
//Calculating distance between each point and reference points
var distance01 = calculateDistance(Latitude_Point_A,Longitude_Point_A,Lat_Check,Long_Check);
var distance02 = calculateDistance(Latitude_Point_B,Longitude_Point_B,Lat_Check,Long_Check);
var distance03 = calculateDistance(Latitude_Point_C,Longitude_Point_C,Lat_Check,Long_Check);
var distance04 = calculateDistance(Latitude_Point_D,Longitude_Point_D,Lat_Check,Long_Check);
var distance05 = calculateDistance(Latitude_Point_E,Longitude_Point_E,Lat_Check,Long_Check);
var distance06 = calculateDistance(Latitude_Point_F,Longitude_Point_F,Lat_Check,Long_Check);
var distance07 = calculateDistance(Latitude_Point_G,Longitude_Point_G,Lat_Check,Long_Check);
var distance08 = calculateDistance(Latitude_Point_H,Longitude_Point_H,Lat_Check,Long_Check);
var distance09 = calculateDistance(Latitude_Point_I,Longitude_Point_I,Lat_Check,Long_Check);
//measuring minimum distance
var minimumDistance = Math.round(Math.min(distance01,distance02,distance03,distance04,distance05,distance06,distance07,distance08,distance09))
sheet.getRange(i,4).setValue(minimumDistance);
}
}
function calculateDistance(Ref_Lat, Ref_Long, Looped_Lat, Looped_Long){
var p = 0.017453292519943295; // Math.PI / 180
var c = Math.cos;
var a = 0.5 - c((Looped_Lat - Ref_Lat) * p)/2 +
c(Ref_Lat * p) * c(Looped_Lat * p) *
(1 - c((Looped_Long - Ref_Long) * p))/2;
var result = 7926 * Math.asin(Math.sqrt(a)); // 2 * R; R = 3963 miles
return result
};
function getLastRowSpecial(range){
var rowNum = 0;
var blank = false;
for(var row = 0; row < range.length; row++){
if(range[row][0] === "" && !blank){
rowNum = row;
blank = true;
}else if(range[row][0] !== ""){
blank = false;
};
};
return rowNum;
};
Sample Spreadsheet Screenshot
I believe your goal is as follows.
You want to reduce the process cost of your script.
In your script, getValue and setValue are used in a loop. I thought that this might be the reason for your issue. In this case, at first, the values are retrieved from the sheet and the values are processed, then, the values are put to the sheet. This flow is suitable for reducing the process cost. I think that "Best Practice" will be useful for understanding your issue. Ref
Also, I thought that when the process cost of your script is reduced, a little ingenuity might be required to be used for modifying your script. So I propose one of several modified scripts as a reference. Please modify your script as follows.
From:
for( var i=0; i<lastRow;i++){
//Reading Lat_Long from the sheet
var Lat_Check = sheet.getRange(i,2).getValue();
var Long_Check = sheet.getRange(i,3).getValue();
//Calculating distance between each point and reference points
var distance01 = calculateDistance(Latitude_Point_A,Longitude_Point_A,Lat_Check,Long_Check);
var distance02 = calculateDistance(Latitude_Point_B,Longitude_Point_B,Lat_Check,Long_Check);
var distance03 = calculateDistance(Latitude_Point_C,Longitude_Point_C,Lat_Check,Long_Check);
var distance04 = calculateDistance(Latitude_Point_D,Longitude_Point_D,Lat_Check,Long_Check);
var distance05 = calculateDistance(Latitude_Point_E,Longitude_Point_E,Lat_Check,Long_Check);
var distance06 = calculateDistance(Latitude_Point_F,Longitude_Point_F,Lat_Check,Long_Check);
var distance07 = calculateDistance(Latitude_Point_G,Longitude_Point_G,Lat_Check,Long_Check);
var distance08 = calculateDistance(Latitude_Point_H,Longitude_Point_H,Lat_Check,Long_Check);
var distance09 = calculateDistance(Latitude_Point_I,Longitude_Point_I,Lat_Check,Long_Check);
//measuring minimum distance
var minimumDistance = Math.round(Math.min(distance01,distance02,distance03,distance04,distance05,distance06,distance07,distance08,distance09))
sheet.getRange(i,4).setValue(minimumDistance);
}
To:
var values = sheet.getRange("B1:C" + lastRow).getValues();
var ar = [[Latitude_Point_A, Longitude_Point_A], [Latitude_Point_B, Longitude_Point_B], [Latitude_Point_C, Longitude_Point_C], [Latitude_Point_D, Longitude_Point_D], [Latitude_Point_E, Longitude_Point_E], [Latitude_Point_F, Longitude_Point_F], [Latitude_Point_G, Longitude_Point_G], [Latitude_Point_H, Longitude_Point_H], [Latitude_Point_I, Longitude_Point_I]];
var res = values.map(([b, c]) => [Math.round(Math.min(...ar.map(e => calculateDistance(...e, b, c))))]);
sheet.getRange(1, 4, res.length).setValues(res);
In this modification, from your script, it supposes that the 1st row is not the header row. Please be careful about this.
In this modification, the values are retrieved from the sheet by getValues, and then, the retrieved values are calculated and put to the sheet by setValues.
Note:
When I saw your script, I thought that an error occurs at var Lat_Check = sheet.getRange(i,2).getValue(); because the 1st value of i is 0. And in the function calculateDistance, Ref_Lat, Ref_Long are not used. So I'm worried that your showing script might be different from the script that you have the issue with. So, when you test the above modification, when an error occurs, can you confirm whether your showing script is the correct script for your situation. And, please provide the sample Spreadsheet for replicating the issue as the image. By this, I would like to confirm it.
References:
map()
getValues()
setValues(values)
I'm trying to write a code to show the user is IN or OUT on the google deployed web app.
The data is recorded in the Google sheet as seen in the screen shot
What Im trying to do is to show the status of an employee on the web-app is he IN or OUT based on the google sheet records.
Here is my code
//Status in/out
function statusIdication(){
var user = Session.getActiveUser().getEmail();
var employee = AdminDirectory.Users.get(user).name.fullName;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mainSheet = ss.getSheetByName("MAIN");
var lastRow = mainSheet.getLastRow();
var lastColoum = mainSheet.getLastColumn();
for (var j = 1; j <= lastRow; j++){
var mainSheet2 = ss.getSheetByName("MAIN").getRange(j,5).getValues();
var mainSheet3 = ss.getSheetByName("MAIN").getRange(j,1).getValues();
var status = (mainSheet2 =="IN" && mainSheet3 == employee) ;
if (status = true){
var notification = "IN";
Logger.log(notification);
}
else{
var notifaction2 = "OUT";
}
}
}
Example - If last entry of Employee Peter = IN then return status as IN or else OUT.
I'm not sure where i went wrong, I'm getting an empty out put.
Issues:
As far as I can see you have the following two issues:
In the if condition you are using an assignment operator = instead of equality operator ==. Because you assign the value true to status, the first if block statements gets executed everytime.
The second issue has to do here:
var mainSheet2 = ss.getSheetByName("MAIN").getRange(j,5).getValues();
var mainSheet3 = ss.getSheetByName("MAIN").getRange(j,1).getValues();
var status = (mainSheet2 =="IN" && mainSheet3 == employee) ;
You are using getValues but this returns a 2D array. You should use getValue() instead because you are referring to a single cell. As a result the comparison in the last line will work as well.
Note that you are using ss.getSheetByName("MAIN") three times. It is a good practice to use the variable you stored it, otherwise you make unnecessary calls.
Solution:
function statusIdication(){
var user = Session.getActiveUser().getEmail();
var employee = AdminDirectory.Users.get(user).name.fullName;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mainSheet = ss.getSheetByName("MAIN");
var lastRow = mainSheet.getLastRow();
var lastColoum = mainSheet.getLastColumn();
for (var j = 1; j <= lastRow; j++){
var mainSheet2 = mainSheet.getRange(j,5).getValue();
var mainSheet3 = mainSheet.getRange(j,1).getValue();
var status = (mainSheet2 =="IN" && mainSheet3 == employee) ;
if (status == true){
var notification = "IN";
Logger.log(notification);
}
else{
var notifaction2 = "OUT";
}
}
}
Optimized solution:
Get the full data instead of iteratively calling getRange and getValue:
function statusIdication(){
var user = Session.getActiveUser().getEmail();
var employee = AdminDirectory.Users.get(user).name.fullName;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mainSheet = ss.getSheetByName("MAIN");
var data = mainSheet.getDataRange().getValues();
for (var j = 0; j < data.length; j++){
var row = data[j];
var mainSheet2 = row[4];
var mainSheet3 = row[0];
var status = (mainSheet2 =="IN" && mainSheet3 == employee) ;
if (status == true){
var notification = "IN";
Logger.log(notification);
}
else{
var notifaction2 = "OUT";
}
}
Upon checking, it seems that your condition checker for the status is written incorrectly. Instead of status = true, you should use status == true. This is because if you try to write it as the latter, it will always be considered true and your conditional statement will not be assessed as false and will not go to the else statement.
Also, you are missing a logger if the condition falls into the else statement. Is this expected? If not, you can try adding it.
I have a rota (a fixed order of rotation (as of persons or duties)) that I've already had help with this week. It's up & running as is, but for simpler reading I'd like to transpose it.
You can see the transposed sheet as I'd like it here
The current script is for the pre-transposed table.
It would search Column 0 for the date. If it was was 7 days away it would retrieve the name from Column 1 & match it with e-mail address in separate sheet etc.
What I'd like to do is instead have the Date in Row 0 & then subsequent names in Row 1 etc etc
I've tried various things. I've stepped through the code & can see what it's doing, & I've done some reading through about 2 dimensional arrays, but I can't seem to find a way of getting the code to work down through columns, instead of across the rows.
Here's the code:
function sendEmails() {
var ss1 = SpreadsheetApp.getActiveSpreadsheet();
var sh1 = ss1.getSheetByName("Rota")
ss1.setActiveSheet(sh1);
var rotalink = "https://docs.google.com/spreadsheets/d/1LgzUWSAGA2kbpar8r5nosU1bSHF7nrtvtUiHS3nB_e8";
var sheet = SpreadsheetApp.getActiveSheet();
// Fetch the range
var dataRange = sheet.getRange("B3:G50")
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var today=new Date();
var timecell = new Date(row[0]);
var timediff = new Date();
var one_day=1000*60*60*24;
var daystogo = Math.ceil((timecell.getTime()-today.getTime())/(one_day));
if (daystogo==7) {//only e-mail people with one week to go. To change that alter the "7" to the number of days you want
var subject = "Rota reminder!";
var emailAddress = [];
var message;
message = "Hello \n\n"+
"You are down to help at Youth Café this week. \n\n" +
"Please see the below rota for your role \n\n" +
"If you have any questions or problems let us know at thameyouthcafe#gmail.com \n\n" +
"Remember, you can check the rota anytime by clicking on the link below: \n\n"+
rotalink
for (var x = 1; x < 5; x++) { // 5 because emails are till col4
// var emailAddress = []; // Start by collecting the non-blank emails in an array
if (getEmailFromName(row[x]) != "") {
emailAddress.push(getEmailFromName(row[x]))
}
}
emailAddress = emailAddress.join(); // Join the array to get a comma separated string
MailApp.sendEmail(emailAddress, subject, message);
}
}
}
and here's the getEmailFromName function that matches with SKey (which I presume comes from the "i" variable in the first function?
function getEmailFromName(sKey) {
// to use this function, don’t put anything in the first column (A) or row (1).
// Put the name (i.e. the key, or what we’re looking for) in column B.
// Put what we want to return in column C.
var columnToSearch = 1; //column B
// Set the active sheet to our email lookup
var ss1 = SpreadsheetApp.getActiveSpreadsheet();
var sh1 = ss1.getSheetByName("EmailContactList")
ss1.setActiveSheet(sh1);
var data = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
var line = -1;
for( var i = 0; i < data.length; i++ ) {
if( data[i][columnToSearch] == sKey ) {
line = i;
break;
}
}
if( line != -1 ) {
//do what you want with the data on "line"
return data[line][2]; //value on column C of the matched line
}
else {
return "";
// if criteria is not found
}
}
Try it this way:
function sendEmails() {
var ss1 = SpreadsheetApp.getActive();
var sh1 = ss1.getSheetByName("Rota")
ss1.setActiveSheet(sh1);
var rotalink = "https://docs.google.com/spreadsheets/d/1LgzUWSAGA2kbpar8r5nosU1bSHF7nrtvtUiHS3nB_e8";
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange("B3:G50")
var data = dataRange.getValues();
for (var i=0;i<dataRange.length;i++) {
var row = data[i];
var today=new Date();
var timecell = new Date(row[0]);
var timediff = new Date();
var one_day=1000*60*60*24;
var daystogo = Math.ceil((timecell.getTime()-today.getTime())/(one_day));
if (daystogo==7) {
var subject = "Rota reminder!";
var emailAddress = [];
var message = Utilities.formatString('Hello\n\nYou are down to help at Youth Café this week.\n\n Please see the below rota for your role \n\nIf you have any questions or problems let us know at thameyouthcafe#gmail.com \n\nRemember, you can check the rota anytime by clicking on the link below: \n\n%s',rotalink);
for (var x=1;x<5;x++) {
if(data[i][x]) {
emailAddress.push(data[i][x]);
}
}
MailApp.sendEmail(emailAddress.join(), subject, message);
}
}
}
Managed to solve it - thank you for your contributions. Turned out it was incredibly simple.
Just had to change this line:
var timecell = new Date(data[0])
to this:
var timecell = new Date(data[0][i])
so it iterates through the first row of each column.
Thanks to info gathered from here, and direct help in other posts. An idiot like me has managed to form something resembling a script :)
And it does exactly what it should, with right results, perfectly. Happy days.
But unfortunately it can take a while to execute (part of the reason its slow, is slow formula in the google sheet, hoping to replace formula with on demand scripts like this one and ditch most bulky formula)
Until I get to that stage, I was hoping someone would take a peek at it, and see if there is any overhead/bloat/processing that could be saved.
My current thoughts are that I'm checking the data more than once, when I could try to check all if's at the same time.
I'm also writing to the sheet a few times, perhaps it would be better to put returned values in an array and write once.
So I'm trying to look into that, but I'm still quite new at all this.
Code simply count's form responses based on a value and date then outputs results to a report.
function snapshot() {
var dateColumn = 2;
var findColumn = 4;
var toFind = "Yes - Complete (going ahead)";
var daysWorth = 31;
var target = "Snapshot";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var targetSheet = ss.getSheetByName(target);
var sheet = ss.getSheetByName('Form Responses');
var values = sheet.getDataRange().getValues();
var today = new Date();
var thisMorning = today;
thisMorning.setHours(0);
thisMorning.setMinutes(0);
var completed = 0;
var attempted = 0;
var totAtt = 0;
var totCom = 0;
for (var i = 0; i < daysWorth; i++){
var startGap = new Date().setTime(thisMorning.getTime() - i*24*60*60*1000);
var endGap = new Date().setTime(thisMorning.getTime() - (i-1)*24*60*60*1000);
for(var counter in values){
var testDate = new Date(values[counter][dateColumn -1]);
if (testDate > startGap && testDate < endGap && values[counter][findColumn -1] == toFind)
{completed++;
totCom++;}
if (testDate > startGap && testDate < endGap)
{attempted++;
totAtt++}
}
var output = new Date(startGap);
//Logger.log("since "+output+" we had: "+completed+" completed and: "+attempted+" attempted");
targetSheet.getRange(i+2,1).setValue(output);
targetSheet.getRange(i+2,2).setValue(attempted);
targetSheet.getRange(i+2,3).setValue(completed);
targetSheet.getRange(i+2,4).setValue(completed/attempted*100);
var completed = 0;
var attempted = 0;
}
targetSheet.getRange(1,1).setValue("Date");
targetSheet.getRange(1,2).setValue("Attempted");
targetSheet.getRange(1,3).setValue("Completed");
targetSheet.getRange(1,4).setValue("Success Rate");
targetSheet.getRange(33,1).setValue("Totals");
targetSheet.getRange(33,2).setValue(totAtt);
targetSheet.getRange(33,3).setValue(totCom);
targetSheet.getRange(33,4).setValue(totCom/totAtt*100);
}
Thanks for reading :)
EDIT
So here it is, with suggested edits and working.
function snapshot() {
var dateColumn = 2;
var findColumn = 4;
var toFind = "Yes - Complete (going ahead)";
var daysWorth = 31;
var target = "Snapshot";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var targetSheet = ss.getSheetByName(target);
var sheet = ss.getSheetByName('Form Responses');
var values = sheet.getDataRange().getValues();
var today = new Date();
var thisMorning = today;
thisMorning.setHours(0);
thisMorning.setMinutes(0);
var archive = [];
var completed = 0;
var attempted = 0;
var totAtt = 0;
var totCom = 0;
for (var i = 0; i < daysWorth; i++){
var startGap = new Date().setTime(thisMorning.getTime() - i*24*60*60*1000);
var endGap = new Date().setTime(thisMorning.getTime() - (i-1)*24*60*60*1000);
for(var counter in values){
var testDate = new Date(values[counter][dateColumn -1]);
if (testDate > startGap && testDate < endGap && values[counter][findColumn -1] == toFind)
{completed++;
totCom++;}
if (testDate > startGap && testDate < endGap)
{attempted++;
totAtt++}
}
var output = new Date(startGap);
if(!completed/attempted)
{var success = 0;}
else
{var success = completed/attempted*100;}
archive.push( [output, attempted, completed,success] );
var completed = 0;
var attempted = 0;
}
var headers =[["Date","Attempted","Completed","Success Rate"]];
var footers =[["Totals",totAtt,totCom,totCom/totAtt*100]];
targetSheet.getRange(1,1,1,4).setValues(headers);
targetSheet.getRange(2,1).offset(0, 0, archive.length, archive[0].length).setValues(archive);
targetSheet.getRange(33,1,1,4).setValues(footers);
}
Thanks for the feedback and if anyone has anymore, I'm all ears.
"perhaps it would be better to put returned values in an array and write once." - yep, gotta figure out how to .setValues() once.
targetSheet.getRange(i+2,1).setValue(output);
targetSheet.getRange(i+2,2).setValue(attempted);
targetSheet.getRange(i+2,3).setValue(completed);
targetSheet.getRange(i+2,4).setValue(completed/attempted*100);
should be some thing like...
myArray.push( [output, attempted, completed, completed/attempted*100] );
then outside the loop...
targetSheet.getRange('A1').offset(0, 0, myArray.length, myArray[0].length).setValues(myArray);
Here, sums[i].value is getting right values but when I want to keep a grand total of all Sum, it is failing.
function calc() {
var amounts = document.getElementsByName("Amount");
var prices = document.getElementsByName("Price");
var sums = document.getElementsByName('Sum');
var tax = document.getElementsByName('Tax');
var total = document.getElementsByName('Total');
for (var i = 0; i < amounts.length; i++) {
sums[i].value = amounts[i].value * prices[i].value;
total[0].value = total[0].value + sums[i].value;
// only this line is not working
}
}
Plain HTML is strings, all the way down, and var amounts = document.getElementsByName("Amount"); followed by amounts.value means you now have string values. Since + is also a string operator, JavaScript will happily turn "2"+"4" into "24", which looks like it did maths, but wrong, when in fact it didn't do math at all.
Convert all values that need to be numbers into numbers, first:
var amounts = document.getElementsByName("Amount");
....
var amount = parseFloat(amounts.value); // NOW it's a number
...
Replace your code with :
for (var i = 0; i < amounts.length; i++) {
sums[i].value = parseFloat(amounts[i].value) * parseFloat(prices[i].value);
total[0].value = parseFloat(total[0].value) + parseFloat(sums[i].value);
// only this line is not working
}
sums[i].value = parseFloat(amounts[i].value) * parseFloat(prices[i].value);
total[0].value = parseFloat(total[0].value) + parseFloat(sums[i].value);
This should help you.
Remove the .value while adding and multiplying
function test()
{
var amounts = new Array();
amounts[0] = "4";
amounts[1] = "6";
amounts[2] = "10";
var prices = new Array();
prices[0] = "4";
prices[1] = "6";
prices[2] = "10";
var sums = new Array();
var total = 0;
for (var i = 0; i < amounts.length; i++) {
sums[i] = parseInt(amounts[i]) * parseInt(prices[i]);
total= parseInt(total) + parseInt(sums[i]);
// only this line is not working
//alert(total); is 152
}
}