google sheets macro how to define a range [duplicate] - google-apps-script

I have this statement:
var destinationRange = destinationSheet.getRange("D26:E39");
and want to replace it with
var destinationRange = destinationSheet.getRange(daGrowaRange);
The reason I want to use daGrowaRange is not just cause da name, but that the range is not always the same.
D is a fixed constant value and never changes
E is a fixed constant
value and never changes
BUT
26 is dynamic and changes and
39 is an offset based on the 26 (in
this case 13 so 39 = 26+13, but the 13 is a variable value also).
I am sure that I could put this together in some ugly ass way, but I am sick of looking at my crappy code and want to learn how you crackz out there make it nice.
Thank you

You can use Template literals to accomplish this task:
const dValue = 26;
const eValue = dValue + 13;
const daGrowaRange = `D${dValue}:E${eValue}`;
const destinationRange = destinationSheet.getRange(daGrowaRange);

Related

Chekcing cell background of a merged cell

I have a range which I am trying to iterate and store the arrays present in an array until a specific case is encountered.
The data is as follows:
I am trying to iterate from D5:D and store in an object with their A1 notation.
This is what I tried,
var gg = Sheet_1.getRange("D5").getValue();
Concat_rows = {};
const COLUMN = 'D';
const START_LINE = 5;
const Filled_LAST_ROW = Sheet_1.getLastRow();
var LAST_ROW ;
//To get the last row to iterate upto
for (var i = START_LINE; i <= Filled_LAST_ROW; i++){
let cellcolor = Sheet_1.getRange(COLUMN+i).getBackground();
// Trying to check with the cell color to identify upto where to get the values from
if(cellcolor == "#c6d9f0"){
LAST_ROW = i;
break;
} else {continue;}
}
console.log(LAST_ROW);
Once I get that in D5:D I need to just iterate over D5:D26 then I need to pull the values and their A1 notations to store in an objet for further use
I have tried this for the above,
for(let h = START_LINE; h <= LAST_ROW; h++) {
let cellValue = Sheet_1.getRange(COLUMN+h).getValue()
if (cellValue.length >= 1) {
Concat_rows[cellValue] = COLUMN+h;
The problem is that the cell D27 is a merged cell and I am not able to figure out how to deal with it.
Only the top left cell of a merged range holds the value displayed in the user interface, so if you want the value of C27:D27 you could do SpredsheetAppg.getRange('C27:D27').getValue(). If the location of the merged range is static the solution is straight fortwarth, just add a condition and when the loop reach get the value from the merged range instead of the cell, in other words, instead of
let cellValue = Sheet_1.getRange(COLUMN+h).getValue()
use
let cellValue = h === 27
? Sheet_1.getRange('C27:D27').getValue()
: Sheet_1.getRange(COLUMN+h).getValue();
If the location isn't known your script needs to check the location of the merged cells but doing this on a loop it's very likely that will cause that the scripts exceeds the maximum execution time. Unfortunatelly the question doesn't include enough details to provide a specific simple way to handle this. The general advice is to use batch operations and in order of get the best possible performance use the Advanced Sheets Service instead of the Spreadsheet Service.

Looping Through Both Rows and Columns

I am self taught in Google Script and not very good at it... LOL One thing I have always struggled with is loops. :) Going to try and be as detailed as possible while still keeping this simple... What I need to do is:
Start at Row 113
Capture the values in the following columns:
B, D, F, S, AD, AM, AV, BB, BH, BK, BN, BQ, BT, BW, BZ, CC, CH, CM, CR, CW, and DB
Side note, in case it matters: the columns in-between all of the above are not blank
Starting at B225, paste each of those values horizontally
So, B113 is being pasted into B225, D113 is being pasted into C225, F113 into D225, so on and so forth until DB113 is pasted into V225
Repeat the above for Row 114 picking up where Row 113 left off - so, B114 is pasted into W225, D114 into X225, so on and so forth
Repeat again, for all rows 115 to 132 continuing to paste horizontally along Row 225
Below is what I was able to come up with after a lot of Google Research and a bunch of failed swings and misses. I am getting stuck on how to get the loop to move horizontally across the columns; turns out that A + 1 does not equal B... LOL
function testLoopTwo() {
var teamSheet = SpreadsheetApp.getActive();
for (var rowCounter = 113; rowCounter < 133; rowCounter = rowCounter + 1) {
teamSheet.getRange("B225").activate();
teamSheet.getCurrentCell().setValue(teamSheet.getRange('B' + rowCounter).getValues());
//This is were I am stuck... how do I move on to C225, D225, etc?
teamSheet.getCurrentCell().setValue(teamSheet.getRange('D' + rowCounter).getValues());
//now the active cell should move another column right, to column D
teamSheet.getCurrentCell().setValue(teamSheet.getRange('F' + rowCounter).getValues());
//active cell shifts right again, so now it would be column F
teamSheet.getCurrentCell().setValue(teamSheet.getRange('S' + rowCounter).getValues());
//So on and so forth...
}
};
Below was my original thought on how to approach this, but it doesn't work... The idea was a loop to run from Rows 113 to 132 then embedded within that loop another loop to capture each value from the looped role and paste it into Row 225, starting at Column B, one by one. I feel like this approach made more sense than my latest approach above, but I couldn't get either of them to work and not sure what it is that I am doing wrong... :(
function testLoop() {
var teamSheet = SpreadsheetApp.getActive();
for (var colCounter = 1; colCounter < 421; colCounter = colCounter + 1){
for (var rowCounter = 113; rowCounter < 133; rowCounter = rowCounter + 1) {
teamSheet.getRange(225,colCounter).setValue(teamSheet.getRange(rowCounter,1).getValue())
teamSheet.getRange(225,colCounter+1).setValue(teamSheet.getRange(rowCounter,3).getValue())
teamSheet.getRange(225,colCounter+2).setValue(teamSheet.getRange(rowCounter,5).getValue())
teamSheet.getRange(225,colCounter+3).setValue(teamSheet.getRange(rowCounter,18).getValue())
teamSheet.getRange(225,colCounter+4).setValue(teamSheet.getRange(rowCounter,29).getValue())
teamSheet.getRange(225,colCounter+5).setValue(teamSheet.getRange(rowCounter,38).getValue())
teamSheet.getRange(225,colCounter+6).setValue(teamSheet.getRange(rowCounter,47).getValue())
teamSheet.getRange(225,colCounter+7).setValue(teamSheet.getRange(rowCounter,53).getValue())
teamSheet.getRange(225,colCounter+8).setValue(teamSheet.getRange(rowCounter,59).getValue())
teamSheet.getRange(225,colCounter+9).setValue(teamSheet.getRange(rowCounter,62).getValue())
teamSheet.getRange(225,colCounter+10).setValue(teamSheet.getRange(rowCounter,65).getValue())
teamSheet.getRange(225,colCounter+11).setValue(teamSheet.getRange(rowCounter,68).getValue())
teamSheet.getRange(225,colCounter+12).setValue(teamSheet.getRange(rowCounter,71).getValue())
teamSheet.getRange(225,colCounter+13).setValue(teamSheet.getRange(rowCounter,74).getValue())
teamSheet.getRange(225,colCounter+14).setValue(teamSheet.getRange(rowCounter,77).getValue())
teamSheet.getRange(225,colCounter+15).setValue(teamSheet.getRange(rowCounter,80).getValue())
teamSheet.getRange(225,colCounter+16).setValue(teamSheet.getRange(rowCounter,85).getValue())
teamSheet.getRange(225,colCounter+17).setValue(teamSheet.getRange(rowCounter,90).getValue())
teamSheet.getRange(225,colCounter+18).setValue(teamSheet.getRange(rowCounter,95).getValue())
teamSheet.getRange(225,colCounter+19).setValue(teamSheet.getRange(rowCounter,100).getValue())
teamSheet.getRange(225,colCounter+20).setValue(teamSheet.getRange(rowCounter,105).getValue())
}
}
};
I really appreciate your help on this!! :D
Try this:
function copyvaluestoasingleline() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("teamSheet");
const vs = sh.getRange("A113:DB132").getValues();
let n = 2;//column counter starts at two and increments by arr[0].length
vs.forEach(([,b,,d,,f,,,,,,,,,,,,,s,,,,,,,,,,,ad,,,,,,,,,am,,,,,,,,,av,,,,,,bb,,,,,,bh,,,bk,,,bn,,,bq,,,bt,,,bw,,,bz,,,cc,,,,,ch,,,,,cm,,,,,cr,,,,,,,,,,db],i) => {
let arr = [[b,d,f,s,ad,am,av,bb,bh,bk,bn,bq,bw,bz,cc,ch,cm,cr,db]];//The assignment in the first parameter of the forEach method is something I learned from Tanaike.
sh.getRange(225,n,arr.length,arr[0].length).setValues(arr);
n+= arr[0].length;//add number of columns to column counter
});
Logger.log('First Line of Input: %s',JSON.stringify(vs[0]))
Logger.log('Output: %s', JSON.stringify(sh.getRange("225:225").getValues()[0]))
}
3:27:14 PM Notice Execution started
3:27:15 PM Info First Line of Input: ["A113","B113","C113","D113","E113","F113","G113","H113","I113","J113","K113","L113","M113","N113","O113","P113","Q113","R113","S113","T113","U113","V113","W113","X113","Y113","Z113","AA113","AB113","AC113","AD113","AE113","AF113","AG113","AH113","AI113","AJ113","AK113","AL113","AM113","AN113","AO113","AP113","AQ113","AR113","AS113","AT113","AU113","AV113","AW113","AX113","AY113","AZ113","BA113","BB113","BC113","BD113","BE113","BF113","BG113","BH113","BI113","BJ113","BK113","BL113","BM113","BN113","BO113","BP113","BQ113","BR113","BS113","BT113","BU113","BV113","BW113","BX113","BY113","BZ113","CA113","CB113","CC113","CD113","CE113","CF113","CG113","CH113","CI113","CJ113","CK113","CL113","CM113","CN113","CO113","CP113","CQ113","CR113","CS113","CT113","CU113","CV113","CW113","CX113","CY113","CZ113","DA113","DB113"]
3:27:15 PM Info Output: ["","B113","D113","F113","S113","AD113","AM113","AV113","BB113","BH113","BK113","BN113","BQ113","BW113","BZ113","CC113","CH113","CM113","CR113","DB113","B114","D114","F114","S114","AD114","AM114","AV114","BB114","BH114","BK114","BN114","BQ114","BW114","BZ114","CC114","CH114","CM114","CR114","DB114","B115","D115","F115","S115","AD115","AM115","AV115","BB115","BH115","BK115","BN115","BQ115","BW115","BZ115","CC115","CH115","CM115","CR115","DB115","B116","D116","F116","S116","AD116","AM116","AV116","BB116","BH116","BK116","BN116","BQ116","BW116","BZ116","CC116","CH116","CM116","CR116","DB116","B117","D117","F117","S117","AD117","AM117","AV117","BB117","BH117","BK117","BN117","BQ117","BW117","BZ117","CC117","CH117","CM117","CR117","DB117","B118","D118","F118","S118","AD118","AM118","AV118","BB118","BH118","BK118","BN118","BQ118","BW118","BZ118","CC118","CH118","CM118","CR118","DB118","B119","D119","F119","S119","AD119","AM119","AV119","BB119","BH119","BK119","BN119","BQ119","BW119","BZ119","CC119","CH119","CM119","CR119","DB119","B120","D120","F120","S120","AD120","AM120","AV120","BB120","BH120","BK120","BN120","BQ120","BW120","BZ120","CC120","CH120","CM120","CR120","DB120","B121","D121","F121","S121","AD121","AM121","AV121","BB121","BH121","BK121","BN121","BQ121","BW121","BZ121","CC121","CH121","CM121","CR121","DB121","B122","D122","F122","S122","AD122","AM122","AV122","BB122","BH122","BK122","BN122","BQ122","BW122","BZ122","CC122","CH122","CM122","CR122","DB122","B123","D123","F123","S123","AD123","AM123","AV123","BB123","BH123","BK123","BN123","BQ123","BW123","BZ123","CC123","CH123","CM123","CR123","DB123","B124","D124","F124","S124","AD124","AM124","AV124","BB124","BH124","BK124","BN124","BQ124","BW124","BZ124","CC124","CH124","CM124","CR124","DB124","B125","D125","F125","S125","AD125","AM125","AV125","BB125","BH125","BK125","BN125","BQ125","BW125","BZ125","CC125","CH125","CM125","CR125","DB125","B126","D126","F126","S126","AD126","AM126","AV126","BB126","BH126","BK126","BN126","BQ126","BW126","BZ126","CC126","CH126","CM126","CR126","DB126","B127","D127","F127","S127","AD127","AM127","AV127","BB127","BH127","BK127","BN127","BQ127","BW127","BZ127","CC127","CH127","CM127","CR127","DB127","B128","D128","F128","S128","AD128","AM128","AV128","BB128","BH128","BK128","BN128","BQ128","BW128","BZ128","CC128","CH128","CM128","CR128","DB128","B129","D129","F129","S129","AD129","AM129","AV129","BB129","BH129","BK129","BN129","BQ129","BW129","BZ129","CC129","CH129","CM129","CR129","DB129","B130","D130","F130","S130","AD130","AM130","AV130","BB130","BH130","BK130","BN130","BQ130","BW130","BZ130","CC130","CH130","CM130","CR130","DB130","B131","D131","F131","S131","AD131","AM131","AV131","BB131","BH131","BK131","BN131","BQ131","BW131","BZ131","CC131","CH131","CM131","CR131","DB131","B132","D132","F132","S132","AD132","AM132","AV132","BB132","BH132","BK132","BN132","BQ132","BW132","BZ132","CC132","CH132","CM132","CR132","DB132"]
3:27:16 PM Notice Execution completed
My data sheet is generated by putting the A1Notation of each cell so that you can tell what is being copied and where it came from.
array destructuring
It's a bit faster using Array.map and flattening it:
function copyThesevalues() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("teamSheet");
const vs = sh.getRange("A113:DB132").getValues();
let o = [vs.map(([,b,,d,,f,,,,,,,,,,,,,s,,,,,,,,,,,ad,,,,,,,,,am,,,,,,,,,av,,,,,,bb,,,,,,bh,,,bk,,,bn,,,bq,,,bt,,,bw,,,bz,,,cc,,,,,ch,,,,,cm,,,,,cr,,,,,,,,,,db],i) => [b,d,f,s,ad,am,av,bb,bh,bk,bn,bq,bw,bz,cc,ch,cm,cr,db]).flat()];
sh.getRange(225,2,o.length,o[0].length).setValues(o);
Logger.log('First Line of Input: %s',JSON.stringify(vs[0]))
Logger.log('Output: %s', JSON.stringify(sh.getRange("225:225").getValues()[0]))
}

Better/faster way to pass 50+ values from one Google sheet to another

I'm brand new to App Script, so please forgive my ignorance.
The Google sheet I use to hold student data is so long and unwieldy (50+ columns) that I decided to create another sheet to act as a front-end for data entry. Through hours of tutorial videos + bumbling trial and error, I've come up with a working script that takes values from my data entry form-like sheet ('Students') and passes those values to the first empty row in my destination/container sheet ('Master').
I'm really pleased with how the script working - except for the fact that it is ridiculously slow. Based on what I've read, I think I'm making too many calls to the Sheets API, and I need to figure out how to pass all the values from 'Students' to 'Master' en masse rather than one-by-one, but I don't have the skills to do that, and I can't seem to find an example.
I'm sure there's a really simple, elegant solution. Can anyone help?
Here's a little piece of my code (hopefully it's enough to see the inefficient strategy I'm using):
function submitStudentData(){
var caseloadManager = SpreadsheetApp.getActiveSpreadsheet();
var enterStudents = caseloadManager.getSheetByName('Students');
var masterSheet = caseloadManager.getSheetByName('Master');
var clearFields = enterStudents.getRangeList(['C6:C18', 'C22', 'E6:E18','G6:G14','G20','I6:I14','K6:K16', 'M6:M18']);
var blankRow = masterSheet.getLastRow()+1;
masterSheet.getRange(blankRow,1).setValue(enterStudents.getRange("Z1").getValue()); //Concatenated Student Name
masterSheet.getRange(blankRow,3).setValue(enterStudents.getRange("C6").getValue()); //First Name
masterSheet.getRange(blankRow,2).setValue(enterStudents.getRange("C8").getValue()); //Last Name
masterSheet.getRange(blankRow,4).setValue(enterStudents.getRange("C10").getValue()); //Goes By
masterSheet.getRange(blankRow,6).setValue(enterStudents.getRange("E6").getValue()); //DOB
masterSheet.getRange(blankRow,7).setValue(enterStudents.getRange("E8").getValue()); //Grade
masterSheet.getRange(blankRow,5).setValue(enterStudents.getRange("E10").getValue()); //Student ID
masterSheet.getRange(blankRow,10).setValue(enterStudents.getRange("E14").getValue()); //Last FIE
masterSheet.getRange(blankRow,11).setValue(enterStudents.getRange("Z2").getValue()); //Calculated FIE Due Date
masterSheet.getRange(blankRow,8).setValue(enterStudents.getRange("E12").getValue()); //Last Annual Date[enter image description here][1]
masterSheet.getRange(blankRow,13).setValue(enterStudents.getRange("G6").getValue()); //PD
masterSheet.getRange(blankRow,14).setValue(enterStudents.getRange("G8").getValue()); //SD
masterSheet.getRange(blankRow,15).setValue(enterStudents.getRange("G10").getValue()); //TD
masterSheet.getRange(blankRow,16).setValue(enterStudents.getRange("G3").getValue()); //Concatenated Disabilities
masterSheet.getRange(blankRow,18).setValue(enterStudents.getRange("G12").getValue()); //Program Type
masterSheet.getRange(blankRow,12).setValue(enterStudents.getRange("G14").getValue()); //Evaluation Status
masterSheet.getRange(blankRow,20).setValue(enterStudents.getRange("I6").getValue()); //DYS
masterSheet.getRange(blankRow,21).setValue(enterStudents.getRange("I8").getValue()); //GT
masterSheet.getRange(blankRow,19).setValue(enterStudents.getRange("I10").getValue()); //EB
masterSheet.getRange(blankRow,24).setValue(enterStudents.getRange("I12").getValue()); //ESY
masterSheet.getRange(blankRow,22).setValue(enterStudents.getRange("I14").getValue()); //BIP
masterSheet.getRange(blankRow,29).setValue(enterStudents.getRange("K6").getValue()); //TR
masterSheet.getRange(blankRow,30).setValue(enterStudents.getRange("K8").getValue()); //OT
It goes on and one like this for 52 values before clearing all the fields in 'Students.' It works, but it takes well over a minute to run.
I'm trying to attach a picture of my 'Students' form-like sheet in case my description isn't clear.
Thanks so much for helping a humble special educator who knows not what she's doing. :)
Image of 'Students' form/sheet
Read best practices Even though your data isn't a contiguous range it is part of one so get the whole range with getValues() and use the appropriate indices to access the ones that you want. In the end if will be much faster. You may not want to use setValues to write the data because of other issues like messing up formulas. Avoid the use of setValue() and getValue() whenever possible
function submitStudentData() {
const ss = SpreadsheetApp.getActive();
const ssh = ss.getSheetByName('Students');
const msh = ss.getSheetByName('Master');
const nr = msh.getLastRow() + 1;
const vs = ssh.getRange(nr, 1, ssh.getLastRow(), ssh.getLastColumn()).getValues();
let oA1 = [[vs[0][25], vs[7][2], vs[5][2], vs[9][2], vs[9][4], vs[5][4], vs[7][4], vs[11][4]]];
msh.getRange(msh.getLastRow() + 1, 1, oA1.length, oA[0].length).setValues(oA1);//This line replaces all of the below lines
msh.getRange(nr, 1).setValue(vs[0][25]);//Concatenated Student Name
msh.getRange(nr, 2).setValue(vs[7][2]); //Last Name
msh.getRange(nr, 3).setValue(vs[5][2]); //First Name
msh.getRange(nr, 4).setValue(vs[9][2]); //Goes By
msh.getRange(nr, 5).setValue(vs[9][4]); //Student ID
msh.getRange(nr, 6).setValue(vs[5][4]); //DOB
msh.getRange(nr, 7).setValue(vs[7][4]); //Grade
msh.getRange(nr, 8).setValue(vs[11][4]); //Last Annual Date[enter image description here][1]
You could also do a similar thing by using formulas to map all of the data into a single line or column making it much easier to run the scripts.
Here is the working example. Just complete the mapping array as desrbied in the code. The runtime is below 1 second.
const mapping= [
// enter the array [ sourceRange, destinationRow ] for each cell you want to copy form Students to Master
['Z1',1],
['C6',3],
['C8',2],
['C10',4],
['E6',6]
// ... and so on
]
function submitStudentData() {
console.time('submitStudentData')
const caseloadManager = SpreadsheetApp.getActive();
const enterStudents = caseloadManager.getSheetByName('Students');
const masterSheet = caseloadManager.getSheetByName('Master');
const data = enterStudents.getDataRange().getValues()
const destRow = []
mapping.forEach((m,i)=>{
[rowi,coli] = rangeToRCindex(m[0])
const destRowIndex = m[1] - 1
destRow[destRowIndex] = data[rowi][coli]
})
masterSheet.appendRow(destRow)
console.timeEnd('submitStudentData')
}
function rangeToRCindex(range){
const match = range.match(/^([A-Z]+)(\d+)$/)
if (!match) {
throw new Error(`invalid range ${range}`)
}
const col = letterToColumn(match[1])
const row = match[2]
return [row-1,col-1]
}
function letterToColumn(columnLetters) {
let cl = columnLetters.toUpperCase()
let col = 0
for (let i = 0; i < cl.length; i++) {
col *= 26
col += cl.charCodeAt(i) - 65 + 1
}
return col
}
As Cooper said you want to avoid reading and writing to the sheet(s) as much as possible. (I had the same issue when I started with Google Script)
This means that you should read the whole range into a variable and then write your rows out to the master sheet.
Below is an example of what you could use to avoid the setValue() and getValue() slowness you are experiencing
function submitStudentData(){
var caseloadManager = SpreadsheetApp.getActiveSpreadsheet();
var enterStudents = caseloadManager.getSheetByName('Students');
var masterSheet = caseloadManager.getSheetByName('Master');
var clearFields = enterStudents.getRangeList(['C6:C18', 'C22', 'E6:E18','G6:G14','G20','I6:I14','K6:K16', 'M6:M18']);
var blankRow = masterSheet.getLastRow()+1; //You will not need this
//First we will all the data from the students sheet. This will make and array of arrays [[row],[row],[row]].
studentData = enterStudents.getRange(1,1,enterStudents.getLastRow(),enterStudents.getLastColumn()).getValues()
Logger.log(studentData)
//We are going to build an array of arrays of the data that we want to write back to the master sheet. We will start by creating our first array
writeData = []
//Then we loop through all the student data
for (var i = 0; i < studentData.length; i++) {
Logger.log(studentData[i][0])
//We are selecting data from each row to add to our array. in "studentData[i][0]" the [0] is the column number (remember we are starting with 0)
rowData = []
rowData.push(studentData[i][0])
rowData.push(studentData[i][2])
rowData.push(studentData[i][1])
//Then we send the full row to the first array we made
writeData.push(rowData)
}
Logger.log(writeData)
// Now to write out the data. Normally it would not be a good idea to loop a write like this but this as an atomic operation that google will automatically batch write to the sheet.
for (var i = 0; i < writeData.length; i++) {
masterSheet.appendRow(writeData[i])
}
}
Hope this helps get you started.

Google Apps Script - Format value with 4 digits

I have a variable which needs to be formatted into a 4 digit format,
i.e. 4 would be 0004, or 38 would be 0038
I've tried using getNumberFormat as below but this gives me no luck. Looking around I'm struggling to find a clean solution to this?
var stringVal = 38;
var prettyVal = stringVal.getNumberFormat('0000');
worksheet.getRange(row+1, AUTOINC_COLUMN+1).setValue("GL"+prettyVal);
EDIT - It needs to be formatted before being placed into my spreadsheet - since I'll append the string 'GL' before the value to form the key
To achieve expected result, use below option
var stringVal = 38;
var format = "0000"
var prettyVal = stringVal.toString().length < 4 ? format.slice(stringVal.toString().length) + stringVal.toString() : stringVal ;
console.log(prettyVal)
I'm assuming you are referring to a spreadsheet. Once you have placed the value in a cell or cells you can setNumberFormat.
var range = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("A1");
range.setValue(38);
range.setNumberFormat("000#");

Function in Google Scripts adding value every minute and actively graphing

First off, I'm not a programmer, but I do have a little experience with Python. I'm a Math Teacher at a Science, Math, and Technology High School Magnet program and need help designing some code to do something for the school. Let me explain what I'm trying to do and then I'll show you what I've got.
We're running a program/competition for 35 teams where they are receiving a "population" increase of 1000 people every minute. I want to generate a script that adds 1000 to their total population each minute and graph it on a live graph. Some things to consider are that these populations are going to be hit with a deadly disease once every hour or so. This means that the 1000 that is added each minute would need to be easy and quick to change - to something like 875, 500, or -200 etc.
What I have:
function increment() {
var s = SpreadsheetApp.getActive().getSheetByName('Austin Test').getRange('G4');
var t = SpreadsheetApp.getActive().getSheetByName('Austin Test').getRange('G3');
var tur = parseInt(t.getValue());
var sur = parseInt(s.getValue());
s.setValue(sur + tur);
}
Where in cell G3 I have the value that I'm adding - 1000 - and in G4 I have the total population. I've also set a time-driven trigger for every minute.
I've run into an issue though - I need this function to run for 35 different teams. In the code I've written, it only works in cell G4. One option is to copy/paste/edit 35 times naming them as 'incrementG' 'incrementH' 'incrementI' etc. Is there a way I can edit this so that I can call it to any cell, without having to do this? Also, will I run out of allotted triggers per day?
I have additional questions, but figure I should start here.
If you want to manually control this function for other cells, one easy way is to tell the function to read the cell name which you entered somewhere, say, like Z1. Then call your function with that name you read earlier. Please refer to the code below.
function increment() {
var sheetAustin = SpreadsheetApp.getActive().getSheetByName('Austin Test')
var cellname1 = sheetAustin.getRange('Z1').getValue() // Get cell name 1
var cellname2 = sheetAustin.getRange('Z2').getValue() // Get cell name 2
var s = SpreadsheetApp.getActive().getSheetByName('Austin Test').getRange(cellname1)
var t = SpreadsheetApp.getActive().getSheetByName('Austin Test').getRange(cellname1)
var tur = parseInt(t.getValue())
var sur = parseInt(s.getValue())
s.setValue(sur + tur)
}
This modified code will read whatever cell name you entered in Z1 and Z2 respectively, then do your job as usual. Be aware that there is no fail check here, so there is error potential such as when you enter an invalid cell name though. Enter G4 to Z1 and G3 to Z2, then run the script, you will have the exact result as the code you showed us.
By changing the way you use getRange() through a loop, you might even let the script to calculate your result of all your team at once.. provided that all of the column you need to calculate is right next to each other.
Here's your code, with a loop for all the team :
function increment() {
var col = 7 // Column G is no.7
for(i = col, i < col + 35, i ++)
var s = SpreadsheetApp.getActive().getSheetByName('Austin Test').getRange(4, col) // Get row 4, column 7, which is G4
var t = SpreadsheetApp.getActive().getSheetByName('Austin Test').getRange(3, col) // Get row 3, column 7, which is G3
var tur = parseInt(t.getValue())
var sur = parseInt(s.getValue())
s.setValue(sur + tur)
}
}