Reputation: 13
I had a function that did what I wanted for one row at a time. Now I want to apply that to multiple rows so I'm trying to use a forEach loop. I'm not throwing errors, but I'm also not getting what I want! (Nothing is output to the cell, and Logger.log only shows Range)
I'm trying to compare a list (from a row) of jobs employees worked the week against the main list of jobs available and then return just the list of worked jobs back to the spreadsheet in a specific cell.
The row in the spreadsheet has more than just the jobs in it, which is why I pull every third item. Some cells have more than one job code in them as well.
The initial one row function:
/**
* Test Returns the job codes assigned for the week
* must be entered like this: =TWOJOBS(CELL("address",B12)&":"&CELL("address",AC12))
* @param {Range} Employee's Info Range
* @return {List} How many days of work per job code
* @customfunction
*/
function TWOJOBS(pRange) {
//get the current active sheet
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("FULL YEAR 2021");
//get the Named Range of JOBS
var JobList = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("JOBS");
//get the Job Codes
var jobjob = JobList.getValues();
var jobjobjob = String(jobjob)
//get the length of the Job List
var joblength = jobjobjob.length;
//Logger.log(joblength);
//get the values from the input range
var empData = ss.getRange(pRange);
var empWeek = empData.getValues()[0];
var empDatalst = [];
for(var k=0; k<empWeek.length; k++){
empDatalst.push(String(empWeek[k]).split());
}
/*get every third item in the EmpDatalst array*/
const every_nth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1);
var empJobs = every_nth(empDatalst, 3);
var indivEmplJobs = [];
var innyEmJojo = [];
for(var i = 0; i<empJobs.length; i++){
//for(var j=0; j<empJobs[i].length; j++){
indivEmplJobs.push(String(empJobs[i]).split(";"));
}
for (var i = 0;i<indivEmplJobs.length;i++){
for(var j=0; j<indivEmplJobs[i].length; j++){
innyEmJojo.push((indivEmplJobs[i][j]).trim())
}
}
var jobsworked = [];
for(var i=0; i<joblength; i++){
if(innyEmJojo.includes(String((jobjob[i])))){
jobsworked.push(String((jobjob[i])));
}
}
And then the multi-row function (I have named ranges for each week):
/**
* Test Returns the job codes assigned for the week
* Assign this script to a button to get the info for the week
* @param {Range} Employee's Info Range
* @return {List} How many days of work per job code
* @customfunction
*/
function TestWeek29Jobs() {
//get the current active sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//get the Named Range of JOBS
var JobList = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("JOBS");
//get the Job Codes
var jobjob = JobList.getValues();
var jobjobjob = String(jobjob)
//get the length of the Job List
var joblength = jobjobjob.length;
//get the named range of the week
var empData = ss.getRangeByName("Week29");
//var empData = ss.getRange("B787:V787");
//get the values in the range
var empWeek = empData.getValues();
var empDatalst = [];
empWeek.forEach(function(person){
//Logger.log(empData.getRow());
for(var k=0; k<empWeek.length; k++){
empDatalst.push(String(empWeek[k]).split());
}//end k for
/*get every third item in the EmpDatalst array because every third is just the job code*/
const every_nth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1);
var empJobs = every_nth(empDatalst, 3);
var indivEmplJobs = [];
var innyEmJojo = [];
for(var i = 0; i<empJobs.length; i++){
indivEmplJobs.push(String(empJobs[i]).split(";"));
}//end i for loop
for (var i = 0;i<indivEmplJobs.length;i++){
for(var j=0; j<indivEmplJobs[i].length; j++){
innyEmJojo.push((indivEmplJobs[i][j]).trim())
}//end j for loop
}//end i for loop
var jobsworked = [];
for(var i=0; i<joblength; i++){
if(innyEmJojo.includes(String((jobjob[i])))){
jobsworked.push(String((jobjob[i])));
}//end if
}//end for
var text = ""
var row = empData.getRow();
var targetcell = ss.getRange("AA"+row);
for (var j=0; j<jobsworked.length; j++){
if(jobsworked[j] != ""){
text += jobsworked[j]+",";
}//end if
targetcell.setValue(text);
Logger.log(targetcell);
}//end for
}); //end of forEach
}//end of function
Can anyone help guide me if I'm WAY off or if I'm just missing something in the forEach functionality? Thanks in advance.
Upvotes: 1
Views: 2989
Reputation: 5163
The method Array.forEach(function(item) {})
will execute a function for each element of Array
, which is represented by item
.
In your implementation:
empWeek.forEach(function(person){
// code here
});
Since empWeek
is now a 2D array, each element is now a 1D array, so person
is now equal to empWeek[0]
, empWeek[1]
, so on, each is a 1D array.
So to access a single cell value, you need to put an index to person
:
for(var k=0; k<person.length; k++){
empDatalst.push(String(person[k]).split());
}
Also in the last code block, since you will be now writing to multiple rows, you need to increment row
for each execution, so you need to put an index on the forEach
function parameter. idx
starts from 0 and increments by 1 for each function execution.
empWeek.forEach(function(person, idx){
var empDatalst = [];
for(var k=0; k<person.length; k++){
empDatalst.push(String(person[k]).split());
}
// code here
var text = "";
var row = empData.getRow()+idx;
var targetcell = ss.getRange("AA"+row);
for (var j=0; j<jobsworked.length; j++) {
if (jobsworked[j] != "") {
text += jobsworked[j]+",";
}//end if
targetcell.setValue(text);
Logger.log(text);
}
});
Reference:
Upvotes: 2