Deleting rows in bulk google sheets using Google Apps Script - google-apps-script

I have a bulk sheet(more that 10000 rows) and 5 filters. I have to delete row if any of 5 columns is TRUE.

Delete row with five "TRUE"
function lfunko2() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Leads");
const vs = sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getValues();//row 2 is start of data
let d = 0;
vs.forEach((r, i) => {
if(r.filter(c => c == "TRUE").length > 4) {
sh.deleteRow(i + 2 - d++);
}
});
}

Related

Partial Match Not Working in Google Sheets

I have this sheet tab that contains these columns:
In another tab, I have this column:
I want the result to be like this:
I have this formula that I'm using that somewhat works:
=IFERROR(TEXTJOIN(" ",TRUE,QUERY(ARRAYFORMULA(IF(REGEXMATCH($B2,Masterlist!$A$2:$A$139),Masterlist!$A$2:$A$139,"")),"where Col1 is not null")))
but the result I'm getting is like this:
function lfunko() {
const ss = SpreadsheetApp.getActive();
const sh1 = ss.getSheetByName("Sheet1");
const [h1, ...vs1] = sh1.getDataRange().getDisplayValues();
let obj1 = {};
h1.forEach((h, i) => { obj1[h] = i + 1; });
const code = sh1.getRange(2,obj1["Activity Code"],sh1.getLastRow() - 1).getDisplayValues().flat().map(c => c.replace(/ /g,''));
const sh2 = ss.getSheetByName("Sheet2");
const [h2, ...vs2] = sh2.getDataRange().getDisplayValues();
let obj2 = {};
h2.forEach((h, i) => { obj2[h] = i + 1; });
const acct = sh2.getRange(2,obj2["Account"],sh2.getLastRow() - 1).getDisplayValues().flat();
let arr = [["Activity Code","Account"]]
acct.forEach((a,i) =>
code.forEach(c => {
if(~c.indexOf(a)) {
arr.push([c,a]);
}
}
));
Logger.log(JSON.stringify(arr));
const sh3 = ss.getSheetByName("Sheet3");
sh3.clearContents();
sh3.getRange(1,1,arr.length, arr[0].length).setValues(arr);
}
Sheet1:
A
1
Activity Code
2
_account1_immediate
3
_lunch_account2
4
_break_account3_lunch
5
_break account 3
Sheet2:
A
1
Account
2
account1
3
account2
4
account3
5
account11
Sheet3:
A
B
1
Activity Code
Account
2
_account1_immediate
account1
3
_lunch_account2
account2
4
_break_account3_lunch
account3
5
_breakaccount3
account3

onOpen if column B is blank fill column A with todays date

I have a spreadsheet where there is a value in column B and in column A is inserted a date, and i want to create a script that when the spreadsheet is open, inside the function onOpen (){}, checks if there is a cell in column B filled but left with column A (date) blank, then automatically inserts todays date, this needs to be done via app script, can anyone give some light?
Timesheet Example
If columnB and not Column A then insert Date into column A
function onOpen() {
ifBAndNotA();
}
function ifBAndNotA() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");//change sheet name as required
const sr = 2;//data startrow;
const vs = sh.getRange(sr, 1, sh.getLastRow() - sr + 1, 2).getValues();
vs.forEach((r, i) => {
if (!r[0] && r[1]) {
sh.getRange(i + sr, 1).setValue(new Date()).setNumberFormat("dd/MM/yyyy");
}
});
}

I am comparing two consecutive cells within a column and if value matches then next sr no and if value doesn’t match then start from 1

I want to create a formula in which column c is dependent on value of two consecutive cells in column B . E.g if cell B1 and cell B2 both are same then C2 = c1+1 and if they does not match then C2= 1. I want to make this formula in arrayformula so I don’t need to copy and paste in all cells. I used this formula if(B2<>B1,1,C1+1) in cell C2. Any help will be appreciated. If you have app script solution I don’t mind learning it.
C = a[i - 1][0] == r[0] ? a[i - 1][0] + 1 : 1
function myfunk(col = 1, num = 1) {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet0');
const sr = 2;//data start row
let vs = sh.getRange(sr, 2, sh.getLastRow() - sr + 1, 1).getValues().map((r, i, a) => {
if (i > 0) {
return [a[i - 1][0] == r[0] ? a[i - 1][0] + 1 : 1];
} else {
return [''];
}
});
sh.getRange(sr, 3, vs.length, vs[0].length).setValues(vs);
}

Google Sheets script - For each used cell in range 1, if cell value exists in range 2, get range 2 match's row number

I feel I have this script almost working as intended, but I am unsure as to where to place certain components of the procedure within the for loop to achieve the desired result. Tunnel vision is very much in effect right now, it's entirely possible I am overthinking a simple task. Please let me know if I can describe the issue more clearly. Any suggestions or pointers towards an existing resource are helpful.
Setup: Sheet one contains a dynamic vertical list of text values starting in cell I3 going down. Sheet two contains a dynamic vertical list of text values starting in range A2 going down, and has a similar set of text values in the same rows in column B.
Goal:
Get the value of each used cell in Sheet1 column I (range one)
Get the value of each used cell in Sheet2 column A (range two)
For each used cell in range one, check the value of each range one
cell to see if the value exists in range two
If a match exists, get the row number of the cell in range two that
contains the value (there will only ever be a single match if a match
exists)
Get the value of the cell on that same row in Sheet2 column B
Set the above value as the cell value in the row containing the value
found in both ranges on Sheet1 Column M
Below is what I have been able to come up with. I am able to get it to function up to the last step. It seems the matching rowNumber variable is not updating with each for loop.
// Get values of range one
var lastRowRangeOne = sheetone.getRange('I3').getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
var rangeOneValues = sheetone.getRange('I3:I' + lastRowClientColumn).getValues();
// Get values of range two
var sheettwo = spreadsheet.getSheetByName('Sheet2');
var sheettwoLastRow = sheettwo.getLastRow();
var sheettwoList = sheettwo.getRange('A2:A' + sheettwoLastRow).getValues();
var sheettwoListFlat = sheettwoList.map(function(row) {return row[0];});
for (var i = 0; i< rangeOneValues.length ; i++){ // for each row in range one
if (sheettwoListFlat[i] == rangeOneValues[i]) { // if the range one value exists in range two
var rowNumber = sheettwoListFlat.indexOf(rangeOneValues[i]) + 3; // get the row number of the matching value found in range two
var sheetOneColumnMValue = sheettwo.getRange('B' + rowNumber).getValue(); // get the cell value of the same row in sheet two column B
var sheetOneRowNumber = i + 3; // get the row number of the range one value
sheetone.getRange('M' + sheetOneRowNumber).setValue(sheetOneColumnMValue); // set the cell value of sheet one column M row x, where x is sheetOneRowNumber
}
}
If you print the value of sheettwoListFlat, it has only 5 elements. Once the iterator of for loop reaches 5 or more it will automatically set if (sheettwoListFlat[i] == rangeOneValues[i]) { to false. Also the statement will only work if the elements of the same index of both arrays are equal.
It would be also more efficient if you search the Sheet1 using the values of Sheet2 since Sheet2 has lesser value.
Here I used TextFinder to find the text within a range.
Using Sheet2 values as search key
Code:
function myFunction() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheetone = spreadsheet.getSheetByName('Sheet1');
var lastRowRangeOne = sheetone.getRange('I2').getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
var rangeOneValues = sheetone.getRange('I2:I' + lastRowRangeOne);
var sheettwo = spreadsheet.getSheetByName('Sheet2');
var sheettwoLastRow = sheettwo.getLastRow();
var sheettwoList = sheettwo.getRange('A2:B' + sheettwoLastRow).getValues();
for (var i = 0; i < sheettwoList.length; i++){
var find = rangeOneValues.createTextFinder(sheettwoList[i][0]).findNext()
if(find){
var sheetOneRowNumber = find.getRow();
sheetone.getRange('M' + sheetOneRowNumber).setValue(sheettwoList[i][1]);
}
}
}
Using Sheet1 values as search key
Code:
function myFunction() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheetone = spreadsheet.getSheetByName('Sheet1');
var lastRowRangeOne = sheetone.getRange('I2').getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
var rangeOneValues = sheetone.getRange('I2:I' + lastRowRangeOne).getValues();
var sheettwo = spreadsheet.getSheetByName('Sheet2');
var sheettwoLastRow = sheettwo.getLastRow();
var sheettwoList = sheettwo.getRange('A2:B' + sheettwoLastRow);
for (var i = 0; i< rangeOneValues.length ; i++){ // for each row in range one
var find = sheettwoList.createTextFinder(rangeOneValues[i][0]).findNext();
if(find){
var rowNumber = find.getRow()
var sheetOneColumnMValue = sheettwo.getRange('B' + rowNumber).getValue(); // get the cell value of the same row in sheet two column B
var sheetOneRowNumber = i + 2;
sheetone.getRange('M' + sheetOneRowNumber).setValue(sheetOneColumnMValue);
}
}
}
Output:
Note: Both produce the same output but using Sheet2 values as search key is more faster than the other.
function compareTwoCols() {
const c1 = 'COL1';//column names
const c2 = 'COL3';
const ss1 = SpreadsheetApp.openById(gobj.globals.datagenid);//data set 1
const sh1 = ss1.getSheetByName('Sheet1');
const [hd1, ...vs1] = sh1.getDataRange().getValues();
let col1 = {};
hd1.forEach((h, i) => { col1[h] = i });
const ds1 = vs1.map((r, i) => {
return r[col1[c1]];
});
const ss2 = SpreadsheetApp.openById(gobj.globals.ssid);//data set 2
const sh2 = ss2.getSheetByName('Sheet0');
const [hd2, ...vs2] = sh2.getDataRange().getValues();
let col2 = {};
hd2.forEach((h, i) => { col2[h] = i });
const ds2 = vs2.map((r, i) => {
return r[col2[c2]]
});
let matches = { pA: [] };
let idx = -1;
ds1.forEach((e, i) => {
let from = '';
do {
idx = ds2.indexOf(e, from);
if (~idx) {
if (!matches.hasOwnProperty(e)) {
matches[e] = [];
matches[e].push({ val1: e, row1: i + 2, col1: col1[c1] + 1, row2: idx + 2, col2: col2[c2] +1 });
matches.pA.push(e);
} else {
matches[e].push({ val1: e, row1: i + 2, col1: col1[c1] + 1, row2: idx + 2, col2: col2[c2] + 1});
}
from = idx + 1;
}
} while (~idx);
});
Logger.log(JSON.stringify(matches));
}
Spreadsheet1 Sheet1:
COL1
COL2
COL3
COL4
COL5
3
4
2
3
4
2
6
6
1
4
5
1
7
5
5
9
8
7
9
5
7
9
0
8
1
8
2
8
7
9
5
8
7
9
9
1
2
0
8
6
2
7
4
0
3
8
2
0
2
6
Spreadsheet2 Sheet0:
COL1
COL2
COL3
COL4
COL5
5
1
2
7
6
4
5
7
8
2
6
3
8
1
5
0
7
6
3
6
4
7
6
1
7
5
6
9
2
1
3
0
2
2
8
4
5
0
8
1
1
3
9
2
2
3
6
7
0
3
Matches Object:
{
"2":[
{
"val1":2,
"row1":3,//ds1 row 3
"col1":1,
"row2":2,//ds2 row 4
"col2":3
},
{
"val1":2,
"row1":3,//ds1 row 3
"col1":1,
"row2":8,//ds2 row 8
"col2":3
},
{
"val1":2,
"row1":10,
"col1":1,
"row2":2,
"col2":3
},
{
"val1":2,
"row1":10,
"col1":1,
"row2":8,
"col2":3
}
],
"7":[
{
"val1":7,
"row1":6,
"col1":1,
"row2":3,
"col2":3
},
{
"val1":7,
"row1":6,
"col1":1,
"row2":11,
"col2":3
}
],
"8":[
{
"val1":8,
"row1":7,
"col1":1,
"row2":4,
"col2":3
},
{
"val1":8,
"row1":11,
"col1":1,
"row2":4,
"col2":3
}
],
"9":[
{
"val1":9,
"row1":5,
"col1":1,
"row2":7,
"col2":3
},
{
"val1":9,
"row1":5,
"col1":1,
"row2":10,
"col2":3
}
],
"pA":[//just an array of all of the matches
2,
9,
7,
8
]
}

Google Sheets: split cells vertically and copy surrounding row entries

I need to do the following to optimize this sheet:
split each multi-line cell in column B so each email address will appear on a new row inserted under the original row.
Copy the data from cells in column A on the original row
I tried split+transpose formulas and a script I found here, but that is returning an error.
Here is the script:
function split_rows2(anArray) {
var res = anArray.reduce(function(ar, e) {
var splitted = e.slice(3, 12).map(function(f) {return f.toString().split(",").map(function(g) {return g.trim()})});
var temp = [];
for (var j = 0; j < splitted[0].length; j++) {
temp.push(e.slice(0, 3).concat(splitted.map(function(f) {return f[j] ? (isNaN(f[j]) ? f[j] : Number(f[j])) : ""})).concat(e.slice(12, 20)));
}
Array.prototype.push.apply(ar, temp);
return ar;
}, []);
return res;
}
=ArrayFormula(QUERY(SPLIT(FLATTEN({A2:A&"♦"&SPLIT(B2:B,",")}),"♦"),"select * where Col2 is not null",0))
Before:
Col1
Col2
A
1,2,3
B
4,5
After:
Col1
Col2
A
1
A
2
A
3
B
4
B
5
A multiline cell implies that they are delimited by line feeds '\n' not commas
function myfunk() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet0');
let vs = sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getValues();
sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).clearContent();
vs.forEach((r, i) => {
let t = r[1].toString().split('\n');
if (t.length > 1) {
t.forEach((e, j) => {
if(j == 0) {
r[1] = e;
} else {
let arr = Array.from(r, x => '');
arr[1] = e;
vs.splice(i + j, 0 , arr)
}
});
}
});
sh.getRange(2, 1, vs.length, vs[0].length).setValues(vs);
}
Sheet 0 after:
COL1
COL2
COL3
COL4
0
4
19
17
5
8
10
7
0
a
21
19
b
c
9
14
17
0