how to set two variables for a for loop - Javascript - javascript

I want to set two variables in a for loop in JavaScript.
function onOpen(cf) {
var ss = SpreadsheetApp.getActive();
var startRow = 2; // First row of data to process
var numRows = 4;
var sheet1 = ss.getSheetByName("Sheet1");
//for (var n in ss.getSheets()){ {
for (var ree = startRow, n in ss.getSheets(); ree <= numRows; ree++){ {
var rangeToCheck = sheet1.getRange(ree, 1);// column D in row ree
var accesslist = sheet1.getRange(ree,2);
var namee = rangeToCheck.getValue();
var folder = DriveApp.createFolder(namee);
This doesn't seem to work. Does anyone know any alternatives?

So you just need one variable, because they are proportional:
var sssheets=ss.getSheets();//performance improvement
var ssoffset=0;// i think its -1 in your examples
for(var ree=1;ree<=numRows && ree-ssoffset<sssheets.length; ree++){
var sheet = sssheets[ree-ssofset];
...
}

Related

Null value returned by a Google sheet regex

I am trying to write a script in Google sheet that should extract a piece of a string using a regex.For example if I have "test test $1.00 test test" I would like to extract only "1.00"
What I have done so far is:
function myFunction() {
var regExp = new RegExp("\$(.*)\s+");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getDataRange();
var values = range.getValues();
var item_description = 0;
var quantity = 1;
var quantity_flat = [];
var item_flat = [];
for (var j = 0; j < values[quantity].length; j++) {
if (values[quantity][j] == "") {
quantity_flat.push(0);
} else {
quantity_flat.push(values[quantity][j]);
}
}
for (var j = 0; j < values[item_description].length; j++) {
var test = regExp.exec(values[item_description][j]);
item_flat.push(test);
}
}
When I check the type of test, I get that it is an Object and has a value of null.
Not sure where is the error. Ideally, I would like to get back a number so that I can push it in an array.
Thanks!

How to get the Sheet Data in array with loop

Below are my sheet data (Table)and I am trying to get the data using loop however result is not generating in the expected format
I Need data in ["11:00-12:00", "13:00-14:00"] however it's generating in 11:00-12:0013:00-14:00
Expacted result is
var msg = ["11:00-12:00", "13:00-14:00"]
Sheet Data
function showData(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var values = sheet.getDataRange().getValues();
var msg = "";
for(var i = 0; i < values.length; i++) {
if(values[i][0] === "A") {
msg += values[i][1]
}
Logger.log(msg)
}
With the way you are doing this, you are just making one large string. Instead of creating a string variable msg, you should make it an array and add using the .push() method.
msg should be a array and not a string
Use Array#push to push items
function showData(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var values = sheet.getDataRange().getValues();
var msg = [];
for(var i = 0; i < values.length; i++) {
if(values[i][0] === "A") {
msg.push(values[i][1])
}
}
Logger.log(msg)
}

Concatenation Code runs excruciatingly slowly google script

My Concatenation function is running excruciatingly slow, on only 28 rows of data it takes almost 4 minutes to run and I have other code I need to run so I hit the Max execution time in Google sheets
If I was running a similar process in Excel this would take maybe 15-30 sec
Everything is in memory, I can't see (with my limited knowledge of javascript) why my code is so slow
Thanks
A Google sheet with data
//Sheet Name
//Values in Range to be overwritten by Header names
//List of Header names
//New Header Name 1
//New Header Name 2
function AsAboveSoBelow_Offers_Asks() {
AsAboveSoBelow('Elements',
["I can offer", "I have a ask"],
["Header1","Header2","Header3","Header4","Header5","Header6",
"Header7","Header8","Header9","Header10","Header11",
"Header12","Header13","Header14"],
"Offers",
"Asks");
}
function AsAboveSoBelow(shtName, arrPBV, arrHeaders, newHeader1, newHeader2) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName(shtName);
var LC = s.getLastColumn();
var r = s.getDataRange();
var v = r.getValues();
var start = new Date();
var temp ="";
//Dim A
var A = [];
for (var i = 0; i < v.length; i++) {
A[i] = [];
for (var j = 0; j <= arrPBV.length - 1; j++) {
A[i][j] = '';
}
}
for(var e = 0; e <= arrPBV.length - 1; e++) {
var search_Term = arrPBV[e];
for(var row = 0; row < v.length; row++) {
for(var col = 0; col <= arrHeaders.length - 1; col++) {
var col2 = HTN(shtName,arrHeaders[col])
var replace_Term = arrHeaders[col];
if(v[row][col2-1].toString().indexOf(search_Term) > -1) {
temp = temp + replace_Term + "|"
}
}
//remove trailing pipe
A[row][e] = temp.replace(/\|(?=\s*$)/, '')
temp = ""
}
}
A[0][0]= newHeader1
A[0][1]= newHeader2
s.getRange(1, v[0].length +1, v.length,A[0].length).setValues(A);
var end = new Date();
var executiontime = end - start;
Logger.log(executiontime);
};
//Helper function
function HTN(shtName,cheader){
var headers =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName(shtName).getDataRange().getValues().shift();
var colindex = headers.indexOf(cheader);
return colindex+1;
}
You want to reduce the process cost of your script.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification point:
In your script, HTN() is used as the for loops. And the function includes SpreadsheetApp.getActiveSpreadsheet().getSheetByName(shtName).getDataRange().getValues().shift();. In your script, the Spreadsheet and sheetName are not changed. So headers is always same. I thought that this might be the main modification point.
Modified script:
Please modify your script as follows.
function AsAboveSoBelow_Offers_Asks() {
AsAboveSoBelow(
'Elements',
["I can offer", "I have a ask"],
["Header1","Header2","Header3","Header4","Header5","Header6","Header7","Header8","Header9","Header10","Header11","Header12","Header13","Header14"],
"Offers",
"Asks"
);
}
function AsAboveSoBelow(shtName, arrPBV, arrHeaders, newHeader1, newHeader2) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName(shtName);
// var LC = s.getLastColumn(); // It seems that this is not used.
var r = s.getDataRange();
var v = r.getValues();
var start = new Date();
var temp ="";
//Dim A
var A = [];
for (var i = 0; i < v.length; i++) {
A[i] = [];
for (var j = 0; j <= arrPBV.length - 1; j++) {
A[i][j] = '';
}
}
var h = s.getRange(1, 1, 1, s.getLastColumn()).getValues()[0]; // Added
for(var e = 0; e <= arrPBV.length - 1; e++) {
var search_Term = arrPBV[e];
for(var row = 0; row < v.length; row++) {
for(var col = 0; col <= arrHeaders.length - 1; col++) {
var col2 = h.indexOf(arrHeaders[col]) + 1; // Modified
var replace_Term = arrHeaders[col];
if(v[row][col2-1].toString().indexOf(search_Term) > -1) {
temp = temp + replace_Term + "|"
}
}
//remove trailing pipe
A[row][e] = temp.replace(/\|(?=\s*$)/, '')
temp = ""
}
}
A[0][0]= newHeader1
A[0][1]= newHeader2
s.getRange(1, v[0].length +1, v.length,A[0].length).setValues(A);
var end = new Date();
var executiontime = end - start;
Logger.log(executiontime);
};
Note:
In my environment, the process time of the modified script was about 5 seconds.
If this was not the direct solution, I apologize.

Get the first empty row in multidimensionnal array

I have a question about a function where I'm trying to get a first look at a multidimensional array.
To explain my problem: In a sheet, I manage my roadmap with projects. A project is composed by 4 rows where I have some information (Project Name, Estimated Team, Timeline ...).
And In my timeline, I need to retrieve the first empty rows in multiple arrays (the first non empty is the startDate).
The problem, I have 4 teams in this multidimensional array, and (for example), the start date can be in the 1st team array for the project A, but the start date can be also in the 3rd team array for the project B.
In my function, I'm trying to get to the start date, but my first step is to check the first array ... (projectRange and after in the code)
So ... I think the best way should be check every rows in the first column, and continue like this to the getLastColumn, right?
So, how can I manage my Loop with this way?
function findLastRow(column) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(roadmapSS);
var startRow = 11;
var startCol = 11;
var dataLength = sheet.getLastRow()-(startRow+2);
var rangeData = sheet.getRange(startRow, 2, sheet.getLastRow(), sheet.getLastColumn());
var dataValues = rangeData.getValues();
var projectsList = rangeData.getValues();
var projectDatas = {};
var projectRange = null;
var projectName = null;
var projectPlan = {};
var realStart = null;
for (var i = 0; i < dataLength; i+=4) {
projectDatas = projectsList[i];
var step = startRow+i;
var realStartRange = startRow+i+1
for (var j = 0; j < 1; j+=4) {
projectName = projectDatas[j];
}
projectRange = ([step, startCol, 4, sheet.getLastColumn()]).toString();
var projectPlan = sheet.getRange(step, startCol, 4, sheet.getLastColumn()).getValues();
for (var k = 0; k < projectPlan.length; ++k) {
realStart = projectPlan[k];
for (var l = 0; l < realStart.length; ++l) {
if (realStart[l] != '') {
break;
}
}
}
//sheet.getRange(realStartRange, 2).setValue(columnToLetter([l]))
console.log(projectName, [l], columnToLetter([l]));
}
}
In fact, i'm trying to get the first column of B in this example (because it's the first non empty occurence :
var projectTimeline = [
['','','A','A','','A'],
['','B','B','','B',''],
['','','','C','C',''],
['','','','','D','D']
]
I found my solution :
I throughed the column first, and then the row. It worked, I founded the column :)
function findFirstDate (timeline) {
for (var col = 0; col < timeline[0].length; col++) {
for (var row = 0; row < 4; row++) {
if (timeline[row][col] != '') {
return [col];
}
}
}
}

getting code to run on multiple sheets in a spreadsheet

I have 4 sheets in my GoogleSheets spreadsheet.
I need the code below to run on every sheet EXCEPT the one called "MRS summary".
I can't seem to get that 'for' loop (the one with the 'g' variable) to work though, because the code only runs for the ACTIVE sheet. But I do know that the Logger.log(g) line is picking up the right indexes...so I think the 'for g' loop is working in the sense that it knows what sheets to look at, but the rest of the code only does what it's supposed to do on the ACTIVE sheet....but I need it to run on every sheet except the one called "MRS summary". Any thoughts?
function SearchCols()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
skip = ['MRS summary'];
for (var g = 0, len3 = sheets.length; g < len3; g++)
{
var name = sheets[g].getName()
if (skip.indexOf(name) > -1) continue;
{
var expen = ss.getSheetByName("MRS summary")
var sheet1 = expen.getRange("A13:A210").getValues();
var searchCol1 = expen.getRange ('B13:B210').getValues();
var searchCol2 = expen.getRange ('A13:A210').getValues();
var searchCol3 = expen.getRange('C13:C210').getValues();
var searchCol4 = expen.getRange('D13:D210').getValues();
var searchCol = ss.getRange('A13:A210').getValues();
var searchVal = ss.getRange('B4').getValue();
for (var i = 0, len = searchCol2.length; i < len; i++)
for (var j = 0, len2 = searchCol1.length; j < len2; j++)
{
if (searchCol2[j][0] == searchVal && searchCol1[j][0] ==
searchCol[i][0])
{
col1[g].getRange(i + 13, 4).setValue(searchCol3[j][0])
col1[g].getRange(i + 13, 5).setValue(searchCol4[j][0])
}
}
}
Logger.log(g);
}
}

Categories