(Google Sheets script) Clear Specific cells - google-apps-script

I have been tasked by my company to make an update to our sheet. The script needs to clear certain cells in a row based on the value of another cell. I have managed to find a script that deletes the whole required row, however that causes an issue with the rest of the document.
function deleteRows() {
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[14] == '' && row[6] == 'PREBOOKED') { // This searches all cells in columns A (change to row[1] for columns B and so on) and deletes row if cell is empty or has value 'delete'.
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
};
Is it possible to modify this to instead of deleting the row it just clears the content of the cells D - P?

You can use below code with modifications if necessary.
function deleteRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getDataRange().getValues();
values.forEach(function(v, i) {
// get row index
var row = i+1;
// look for required values in cells
if (v[14] == '' && v[6] == 'PREBOOKED') {
// might have to modify this line based on Sheets API
sheet.getRange('D'+row+':P'+row).clearContent();
}
});
}

i was able to do what i need with the following:
function deleteRows() {
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[14] == '' && row[6] == 'PREBOOKED') { // This searches all cells in columns A (change to row[1] for columns B and so on) and deletes row if cell is empty or has value 'delete'.
sheet.getRange((parseInt(i)+1), 6).clearContent();
sheet.getRange((parseInt(i)+1), 7).clearContent();
sheet.getRange((parseInt(i)+1), 10).clearContent();
sheet.getRange((parseInt(i)+1), 11).clearContent();
sheet.getRange((parseInt(i)+1), 12).clearContent();
rowsDeleted++;
}
}
};
thanks for your ideas folks!

Related

Googlesheet adding unwanted rows

I have two sheets (Sheet1 and Mirror) in a single google spreadsheet. I have some columns in the Mirror sheet which are being mirrored from Sheet1 using an array formula (={"Firstname";ARRAYFORMULA(INDIRECT("Sheet1!B2:B"))}).
I have rows being copied automatically from a google form into Sheet1. For some reason, periodically, about 500 empty rows are entered into the Mirror sheet and I have to manually delete them.
I have these googlesheet functions below that trigger on change. I have only deployed the function ReadRows and it works like a charm. Rather than deploying the second function (DeleteBlankRows) which might slow down my spreadsheet, I do like to know how I can figure out what is causing the extra periodic 500 blank rows to appear and stop it or I'd like any professional advice you can give.
Please see the sample scripts below. Thanks in advance.
function readRows() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
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] == 0 || row[1] == '') && (row[2] == 0 || row[2] == '')){
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
};
function DeleteBlankRows() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Mirror');
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] == 0 || row[1] == '')){
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
};
Updated answer:
The issue is that you need to delete the rows backwards for Sheet1 and then you don't need to use DeleteBlankRows for Mirror anymore. Replace your code with this one:
function readRows() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
var rows = sheet.getDataRange();
var values = rows.getValues();
for (var i = values.length - 1; i>=0; i--) {
var row = values[i];
if ((row[1] == 0 || row[1] == '') && (row[2] == 0 || row[2] == '')){
sheet.deleteRow(i+1);
}
}
};
To get rid of empty rows, you can simply filter them out before you copy them to the target sheet.
Change:
var values = rows.getValues();
to:
var values = rows.getValues().filter(r=>r[0]!='');
Assuming for every empty row, the cell in column A is also empty.
You can now remove the DeleteBlankRows unless you want to delete also the rows.

Modify Code - Delete Row If Cell Has any Data - Google Sheets / Google Apps Script

I would like to modify this code so that if there is any data(Numbers as well) in column 7, it will delete the entire row.
Currently whatever you put into the inverted commas in the If Statement, it deletes
what could you substitute that would do that ?
function DeleteCOMPLETED2() {
var sheet = SpreadsheetApp.getActive();
sheet.setActiveSheet(sheet.getSheetByName('RELOCATION'), 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[7] == "**if there is any data in column 7 then delete entire row**") {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}}}
Delete row if anything in column7
function DeleteCOMPLETED2() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('RELOCATION');
var values=sh.getDataRange().getValues();
var d=0;
values.forEach(function(r,i){if(r[6]){sh.deleteRow(i+1-d++);}});//column7
}

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.

How do I pass a number to .hideRow()?

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);
}
}
}

Google Apps Script - Find Row number based on a cell value

I'm looking for some assistance on find the row number for a cell that contains a specific value.
The spreadsheet has lots of data across multiple rows & columns. I'm looping over the .getDataRange and can located the cell containing the value I'm looking for. Once found I'd like to know the row that his cell is in, so that I can further grab additional cell values since I know exactly how many rows down and/or columns over the additional information is from the found cell.
Here is a bit of the code for finding the cell containing a specific string.
function findCell() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var dataRange = sheet.getDataRange();
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
var row = "";
for (var j = 0; j < values[i].length; j++) {
if (values[i][j] == "User") {
row = values[i][j+1];
Logger.log(row);
}
}
}
}
When outputting Logger.log(row) it gives me the values I'm looking for. I want to determine what row each value is in, so I can then go down X number of rows and over X columns to get the contents of other cells.
I don't know much about google apps but it looks like [i] is your row number in this circumstance.
So if you did something like:
function findCell() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var dataRange = sheet.getDataRange();
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
var row = "";
for (var j = 0; j < values[i].length; j++) {
if (values[i][j] == "User") {
row = values[i][j+1];
Logger.log(row);
Logger.log(i); // This is your row number
}
}
}
}
This method finds the row number in a particular column for a given value:
function rowOf(containingValue, columnToLookInIndex, sheetIndex) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets();
var dataRange = sheet[sheetIndex].getDataRange();
var values = dataRange.getValues();
var outRow;
for (var i = 0; i < values.length; i++)
{
if (values[i][columnToLookInIndex] == containingValue)
{
outRow = i+1;
break;
}
}
return outRow;
}
But if you do it like that, it won't refresh unless you change any of the parameters, that's because a custom function should be deterministic, that is, for the same parameters, it should always give the same result.
So instead, it's better to do it this way:
function rowOf(containingValue, range) {
var outRow = null;
if(range.constructor == Array)
{
for (var i = 0; i < range.length; i++)
{
if(range[i].constructor == Array && range[i].length > 0)
{
if (range[i][0] == containingValue)
{
outRow = i+1;
break;
}
}
}
}
return outRow;
}
In this case, you need to pass the full column range your looking for like so:
rowOf("MyTextToLookFor", 'MySheetToLookIn'!A1:A)
Where you would replace A by the colum of your choice, and MySheetToLookIn by your sheet's name and MyTextToLookFor by the text you are looking for.
This will allow it to refresh on adding rows and removing rows.
Since 2018 this can be done without a loop using flat().
function findRow(searchVal) {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var columnCount = sheet.getDataRange().getLastColumn();
var i = data.flat().indexOf(searchVal);
var columnIndex = i % columnCount
var rowIndex = ((i - columnIndex) / columnCount);
Logger.log({columnIndex, rowIndex }); // zero based row and column indexes of searchVal
return i >= 0 ? rowIndex + 1 : "searchVal not found";
}
ES6 gave us a one liner for this (but expanded for full detail).
function findRow() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss. getActiveSheet(); // OR GET DESIRED SHEET WITH .getSheetByName()
const dataRange = sheet.getDataRange();
const values = dataRange.getValues();
const columnIndex = 3 // INDEX OF COLUMN FOR COMPARISON CELL
const matchText = "User"
const index = values.findIndex(row => row[columnIndex] === matchText)
const rowNumber = index + 1
return rowNumber
}
This can be done with the Text Finder:
function findRow(searchValue){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var thisSheet = ss.getActiveSheet();
var tf = thisSheet.createTextFinder(searchValue)
var thisRow = tf.findNext().getRow()
return thisRow
}
Discovered through this post: Google App Scripts find text in spreadsheet and return location index
Implementing: https://developers.google.com/apps-script/reference/spreadsheet/text-finder
To find a row in a Google Sheets sheet based on the value of a specific column (in this case, the invoice_id column) and edit another column (in this case, the send column) in that row, you can use the following script:
// Replace "Sheet1" with the name of your sheet
var sheet = SpreadsheetApp.getActive().getSheetByName("Sheet1");
// Replace "A" with the column letter for the invoice_id column
// and "B" with the column letter for the send column
var invoiceIdColumn = "A";
var sendColumn = "B";
// Replace "12345" with the invoice_id you want to search for
var invoiceIdToSearch = "12345";
// Find the row number of the row with the matching invoice_id
var data = sheet.getDataRange().getValues();
var row = data.findIndex(row => row[invoiceIdColumn - 1] == invoiceIdToSearch) + 1;
// If a row with the matching invoice_id was found
if (row) {
// Set the value of the send column in that row to "true"
sheet.getRange(row, sendColumn).setValue(true);
}
This script will search through the entire sheet for a row with an invoice_id value that matches the invoiceIdToSearch variable, and then set the value of the send column in that row to true.
Note that this script assumes that the invoice_id column is the first column in the sheet (column A) and the send column is the second column (column B). If your columns are in different positions, you will need to adjust the invoiceIdColumn and sendColumn variables accordingly.