How do I pass a number to .hideRow()? - google-apps-script

I got the following script from #Mike Grace's website:
// Deletes rows in the active spreadsheet that contain 'Yes' in column A
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[0] == 'Yes') {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
}
The script works well, but I would like to make a change to it, instead of calling .deleteRow() I want to use .hideRow() instead.
Because the .hideRow() method only accepts a range as far as I understand, I'm getting the following error:
How do I modify this script so that it hides the row instead of deleting them?

there are different hideRow / s () methods, one of them takes a row number as argument.
your code can be simplified like this :
function hideRowsWithYes() {
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getDataRange().getValues();
for (var i = 0; i < values.length; i++) {
if (values[i][0] == 'Yes') {
sheet.hideRows(1+i);
}
}
}
As usual, autocomplete makes the job easier...
Edit following comment :
to unhide row we don't have a simple method with row index so we need to define the range... code goes like this (i has a +1 because values is an array that starts from 0 while sheets are indexed from 1)
function unHideRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getDataRange().getValues();
var row;
var maxCol = sheet.getMaxColumns();
for (var i = 0; i < values.length; i++) {
if (values[i][0] == 'Yes') {
row = sheet.getRange(1+i, 1, 1, maxCol);
sheet.unhideRow(row);
}
}
}

Related

Apps Script Code wont delete a boolean Value - Apps Script / GoogleSheets

I have this code below that works fine for deleting rows containing certain text.
function DeleteTRUE(e) {
var sheet = SpreadsheetApp.getActive();
sheet.setActiveSheet(sheet.getSheetByName('HOLDING'), true);
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[4] == "TRUE") {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
}
However when I put a TRUE to try to delete a row (that has a checkbox) and someone checks it,
it doesnt work. It is being triggered from an onEdit currently with the word "MOVE" which is working as it should. would prefer if it was a checkbox that they checked and it deleted the row.
Thanks in advance
If I create default checkboxes equal true works for me fine
function deleteTRUE() {
var sheet = SpreadsheetApp.getActive();
sheet.setActiveSheet(sheet.getSheetByName('HOLDING'), true);
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[4] == true) {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
};
If you need check for "TRUE" you have override validation values.
It's very important you need to type 'TRUE 'FALSE for string interpretation.

Loop to disable function in onEdit script

I have a script that adds specific values to the last row of the sheet by clicking a checkbox (has yes/no values) and deletes the row by unchecking the same checkbox. It works fine
but as it is onEdit script - it keeps on going adding values. I am trying to loop all this job to check if the value already exists and if yes - do nothing. I developed the following but it does not work - keeps adding values with every edit. Here is the code
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet = ss.getActiveSheet()
var paramrange = sheet.getRange('A55:C60')
var destn = sheet.getRange(sheet.getLastRow()+1, 1)
var destnorma = sheet.getRange(sheet.getLastRow()+1, 2)
var orpac = sheet.getRange('E23')
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[0] == 'ORP Ac') {
} else{
if(orpac.getValue() == 'yes') {
var orpacn = 'ORP Ac';
var orpacnorm = '-150';
destn.setValue(orpacn)
destnorma.setValue(orpacnorm)
} else
{
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[0] == 'ORP Ac') {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}}
}
}}
Your second loop is inside the first loop and it uses the same index. That's a problem.
This might work better. But I can't tell since I don't have your data.
function onEdit() {
var ss=SpreadsheetApp.getActive()
var sheet=ss.getActiveSheet()
var paramrange=sheet.getRange('A55:C60')
var destn=sheet.getRange(sheet.getLastRow()+1, 1)
var destnorma=sheet.getRange(sheet.getLastRow()+1, 2)
var orpac=sheet.getRange('E23')
var orpacvalue=orpac.getValue();
var rows=sheet.getDataRange();
var numRows=rows.getNumRows();
var values=rows.getValues();
for (var i=0;i<numRows;i++) {
var row=values[i];
if (row[0]!='ORP Ac') {
if(orpacvalue=='yes') {
var orpacn = 'ORP Ac';
var orpacnorm = '-150';
destn.setValue(orpacn)
destnorma.setValue(orpacnorm)
} else
{
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var j = 0; j<numRows; j++) {
var row = values[j];
if (row[0] == 'ORP Ac') {
sheet.deleteRow((parseInt(j)+1) - rowsDeleted);
rowsDeleted++;
}
}
}
}
}
}
This appears to be a lot of script for a simple trigger which needs to complete in less than 30 seconds.

Find and write to next blank cells in a column using App maker

I need help with finding a number from a specific row in column A and write next to its blank cells in two different columns of the same row. e.g Find a number in COLUMN A2, Write to cells in COLUMN B2 and C2.
I have currently used filters and it hasn't helped.
function filterRange(filteredRange) {
return filteredRange == [2.0];
}
function findCellByValue() {
var ss = getSpreadSheet();
var sheet = ss.getActiveSheet();
var dataRange = sheet.getDataRange();
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
var range = values[i];
var filtered = range.filter(filterRange);
var newValue = filtered.concat(["Tee", "uhuuu"]);
console.log(newValue);
var ssheet = sheet.getRange("B2:C2");
console.log(ssheet.setValues([newValue]));
}
}
Anyways I have managed to find a workaround it though it is not the best possible solution but for this, it works.
function findCellByValue(cellValue) {
console.log(cellValue);
var ss = getSpreadSheet().getActiveSheet();
var range = ss.getRange("A2:A").getValues();
for(var i = 0; i < range.length; i ++)
{
if(range[i] == cellValue)
{
var Arrayvalues = range[i].concat(["test1","test2"]);
ss.getRange(i+2,1,1,3).setValues([Arrayvalues]);
i = range.length;
}
}

Google Apps Script for Removing Rows Containing Part of a Keyword

I want to delete the rows on Google Sheets that contain employees, tests, irrelevant submissions, and duplicate entries. My code needs to be standalone so that it can be used across my workplace.
Specifically, I want to:
Remove any rows that contain an email address belonging to a certain organization (ex: any email address that ends in #domainname.com). I've been using a piece of code to delete rows containing three specific email addresses belonging to my coworkers, but I was hoping to find a way to delete all employees in one sweep without coding in each individual email. Here's the code I've been using:
function delVtlEm() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[1] == 'isaac#domainname.com' ||
row[1] == 'danni#domainname.com' ||
row[1] == 'georgia#domainname.com') {
sheet.deleteRow((parseInt(i) + 1) - rowsDeleted);
rowsDeleted++;
}
}
}
Remove any rows that contain the word "login" from a comment section where "login" might be only part of the copy in that column. For example, someone might fill out a Contact Us form and ask in the comment section for help with their login info - but this isn't a qualified lead for my purposes. Their message may be "Hey, can you help me with my login?" or some other similar phrasing, which is why I want to delete any row containing "login" in any capacity.
Please let me know if you have any ideas or suggested code!
I have implemented the following smartDelete() function based on your code.
This function allows you to achieve the following,
Identify any number of domains (in badDomains array) to delete its corresponding rows.
Identify any number of words (in badWords array) to delete its corresponding rows.
Both of the two search criteria above are case-insensitive; you can change that by changing the regular expression modifier (stored in regExpModifiers) to "" or Null.
Actions above can be taken on three different columns (stored in fnameColumnNumber, emailColumnNumber and companyColumnNumber)
Let me know if you face any issues or have any feedback.
function smartDelete() {
// smartDelete settings goes here,
var badDomains = ["vtldesign\\.com", "parterreflooring\\.com"];
var badWords = ["Vital", "Parterre", "test"];
var fnameColumnNumber = 0;
var emailColumnNumber = 1;
var companyColumnNumber = 3;
var regExpModifiers = "i";
// Gain access data in the sheet
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
var deleteAction = false;
// delete procedure
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
deleteAction = false;
// check bad words
for (var j = 0; j <= badWords.length - 1; j++) {
var myPattern = new RegExp(badWords[j], regExpModifiers);
var status = row[fnameColumnNumber].toString().match(myPattern);
if (status) {
// match found, mark this row for delete
deleteAction = true;
break;
};
};
// check bad domains
for (var j = 0; j <= badDomains.length - 1; j++) {
var myPattern = new RegExp(badDomains[j], regExpModifiers);
var status = row[emailColumnNumber].toString().match(myPattern);
if (status) {
// match found, mark this row for delete
deleteAction = true;
break;
};
};
// check bad words
for (var j = 0; j <= badWords.length - 1; j++) {
var myPattern = new RegExp(badWords[j], regExpModifiers);
var status = row[companyColumnNumber].toString().match(myPattern);
Logger.log(status)
if (status) {
// match found, mark this row for delete
deleteAction = true;
break;
};
};
// execute delete.
if (deleteAction) {
sheet.deleteRow((parseInt(i) + 1) - rowsDeleted);
rowsDeleted++;
};
};
}
You can use indexOf('what to find') to look for a partial string. Also, don't delete rows in the Sheet individually. That is inefficient. Delete elements (rows) from the array, clear the sheet tab, and then set all the new values.
function delVtlEm() {
var i,row;
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
var arrayOfStringsToFind = ["whatToLookFor","whatToLookFor2","whatToLookFor3"];
for (i = 0; i <= numRows - 1; i++) {
row = values[i];
column1Value = row[0];//Get the value of column A for this row
column2Value = row[1];
column3Value = row[2];
if (arrayOfStringsToFind.indexOf('column1Value') !== -1) {
values.splice(i,1);//
}
if (column2Value.indexOf('#vtldesign.com') !== -1) {
values.splice(i,1);//Remove one element in the data array at index i
}
if (column3Value.indexOf('whatToLoookFor') !== -1) {
values.splice(i,1);//
}
}
sheet.clearContents();//clear the contents fo the sheet
sheet.getRange(1, 1, values.length, values[0].length);//Set new values
}

Deleting Rows in Google Sheets that Contain Values from Array or Second Spreadsheet

I am trying to create a script that lets me delete rows in a Google spreadsheet that contain specific text values. I am an extremely novice coder at best and tried modifying several similar scripts I found. The only one I can get to work is the following. However, my list of values will be long, potentially hundreds of terms, and the script I have here will be cumbersome to build out for this many values. I am guessing that having the values in an array or second spreadsheet would be much better. It is also case sensitive. I tried lifting code from other scripts to change to all lowercase but I can't get anything to work.
If you would be so kind as to share your collective knowledge, how can I modify this to achieve my goal?
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[1].indexOf("test") > -1) {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
if (row[1].indexOf("TEST") > -1) {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
};
Try this. If you delete rows, it's better to start from the bottom otherwise it messes with your indexing. DelA is the array of strings that you want to base your row removals on. The indexOf function returns something > -1 if it finds the one of the strings. Once it finds one it stops on that row after deleting it and moves up one. The row number is i + 1. I did not assume that you had a header row. If you have a header row then adjust your stop condition to i > 0.
function deleteMyRows()
{
var delA=['Test','Others'];
var sht = SpreadsheetApp.getActiveSheet();
var rng = sht.getDataRange();
var values = rng.getValues();
for (var i = values.length-1; i > -1; i--)
{
for(var j=0;j<values[i].length;j++)
{
for(var k=0;k<delA.length;k++)
{
if(values[i][j].indexOf(delA[k])>-1)
{
sht.deleteRow(i + 1);
break;
}
}
}
}
}
So maybe this is what you really need:
function deleteMyRows()
{
var delA=['Test','Others'];
var sht = SpreadsheetApp.getActiveSheet();
var rng = sht.getDataRange();
var values = rng.getValues();
for (var i = values.length-1; i > -1; i--)
{
for(var j=0;j<values[i].length;j++)
{
for(var k=0;k<delA.length;k++)
{
var lcval=String(values[i][j]).toLowerCase();
var lcdel=String(delA[k]).toLowerCase();
if(lcval.indexOf(lcdel)>-1)
{
sht.deleteRow(i + 1);
break;
}
}
}
}
}