Automatically hide rows based on other cell value - google-chrome

We have a spreadsheet that automatically attributes status for each row based on information enteredin cells located in column T. The stauts appear on column M showing open, pending and closed. I'm using the following code:
// Sheet the data is on.
var SHEET = "DLT";
// The value that will cause the row to hide.
var VALUE = "Closed"
// The column we will be using
var COLUMN_NUMBER = 14
function onEdit (e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
//Ensure on correct sheet.
if(SHEET == activeSheet.getName()){
var cell = ss.getActiveCell()
var cellValue = cell.getValue();
//Ensure we are looking at the correct column.
if(cell.getColumn() == COLUMN_NUMBER){
//If the cell matched the value we require,hide the row.
if(cellValue == VALUE){
activeSheet.hideRow(cell);
};
};
};
}
I understand that there is a mistake on the code, as the spreadsheet changes automatically the "stauts" value on column M as soon as information is entered on column T, and this code this won't work because technically the Active.cell bit is telling the script to look at the current cell being edited (which in this case will be the cell on column T as this is the last field to be filled before triggering the spreadsheet change status to closed.)
Doubt is, how to make the script still looks into the current row being edited but consider the value on column M and not the active cell.

function onEdit (e) {
var sh = e.range.getSheet();
//column 20 is T
if(sh.getName()== 'DLT' && e.range.columnStart == 20 ){
SpreadsheetApp.flush();//This will provide enough time to allow the spreadsheet to complete all of it's calculations.
//column 13 is M
if(e.range.offset(0,-7).getValue()=="Closed") {
sh.hideRows(e.range.rowStart);
}
};
}

Related

Google Sheets script: Using a term in one cell to delete a row on another page

I’m trying to find a way to delete a row on one sheet based on a row selected by a checkbox on another sheet, using an onEdit function.
The checkbox is in Column A on Sheet1; the row is variable, since Sheet1 is a search page. The unique search result / search string is in Column B. The records that I want to delete from this search page are on a second sheet, Sheet2. In Sheet2, some of the same data is duplicated from Sheet1, but there’s no checkbox. So, the unique identifier in Column B on Sheet1 is Column A on Sheet2, and that’s where I want the deletions to happen. In Sheet2, the Column A values are always unique, so I wouldn't think this calls for an array.
So, to summarize, this script would say: if a row on Sheet1 is checked, look at the value of Column B in that row. Then, search Column A in Sheet2. If matched, deleteRow. So, my question is: How would this script be written?
However, there’s one slight complication, which I hesitate to mention for fear that the question will face closure due to “lack of focus.” (so, if you just want to answer the above and ignore this bit, that's still wonderful!). I'm only asking because I feel like it affects how the script would be coded in the first place. I only want this deletion to happen if Column E on Sheet1 says Indirect. If Column E is blank, or contains other text, then the script runs as follows:
function onEdit(e) {
if (e.range.columnStart != 1) return;
if (e.value != 'TRUE') return;
var sheet = SpreadsheetApp.getActive();
var ignored_sheets = ['Sheet2','Sheet3'];
if (ignored_sheets.includes(sheet.getName())) return;
if(e.range.getSheet().getRange(e.range.getRow(),5).getValue().length > 0){
sheet.toast("Can't overwrite data.");
sheet.getActiveCell().setValue(false);
return;};
var row_index = e.range.rowStart;
var row = sheet.getRange('B' + row_index + ':D' + row_index).getDisplayValues().flat();
if (row[1] == '') return;
var result = SpreadsheetApp.getUi()
.alert("Append record?", SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
if (result != SpreadsheetApp.getUi().Button.OK) {
sheet.toast("Operation canceled.");
sheet.getActiveCell().setValue(false);
return;}
sheet.toast("Operation complete.");
sheet.getActiveCell().setValue(false);
sheet.getRange('B3').clearContent();
sheet.getSheetByName('Sheet2').appendRow(row);
sheet.getSheetByName('Sheet1').setActiveCell('B3');
}
As per problem statement you mentioned in comments:-
The third function I want to add is the ability to delete records, if
their column E value is "Indirect"
Sample script will look like this :-
function onEdit(e)
{
const value = e.value
const range = e.range
const sheet = range.getSheet();
const row = range.getRow();
const column = range.getColumn();
const ss = SpreadsheetApp.getActiveSpreadsheet();
const checkValue = sheet.getRange(row, 5).getValue(); // Column E value
if(column === 1 && value == 'TRUE' && checkValue === 'Indirect')
{
const ref_IDtoSearch = sheet.getRange(row, 2).getValue(); // ref id in sheet 1
const targetSheet = ss.getSheetByName('Sheet2')
const refRange = targetSheet.getRange('A1:A').getValues().flat(); // Range ref column in sheet 2
const posRow = refRange.indexOf(ref_IDtoSearch)
if(posRow > -1)
{
targetSheet.deleteRow(posRow+1)
}
}
}
Incorporate it in your existing onEdit code.
Reference:
deleteRow()

I am trying to set the value of multiple cells when the value of once cell changes in google sheets

I am trying to set the values of several cells in the same row of a cell that I am changing.
IF the value in AJ2 is True then the range AK2:AX2 should also be true.If I change AJ2 to false, then I should be able to uncheck any of the values in the range and they would then be false. I 'sort of' have this logic working. IF I have AJ2 checked and uncheck AK2, when I uncheck AJ2 it rechecks AK2.
I also need this to happen on all rows if I change the value in the column of AJ for their rows. not just row 2. I am fairly new to working with sheets and could use some help.
function onEdit(e) {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var cell = ss.getRange("AJ2");
var range =ss.getRange("AK2:AX2")
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 36&&ss.getActiveSheet().getName()=="MasterData") {
if (Cell = "TRUE")
range.setValue("TRUE")}
}
Try this
function onEdit(e) {
const sheet = e.source.getActiveSheet();
const cell = e.range;
// AJ = column 36 (master column)
if(sheet.getName() == "MasterData" && cell.getColumn()==36 && cell.isChecked()){
sheet.getRange(cell.getRow(),37,1,14).setValue('TRUE')
}
// individual columns : 37 (AK) to 50 (AX)
if(sheet.getName() == "MasterData" && cell.getColumn()>=37 && cell.getColumn()<=50 && !cell.isChecked()){
sheet.getRange(cell.getRow(),36,1,1).setValue('FALSE')
}
}
explanation
when a box is checked in column 36 (AJ = 'master column'), all the boxes of the same row between 37 to 50 (AK to AX) will be checked
when an individual box is unchecked between column 37 to 50 (AK to AX) the master box of the same row will be also unchecked
reference
onEdit trigger
The onEdit(e) simple trigger returns an event object.
The event object contains the information about the spreadsheet that was edited, which you use instead of the "SpreadsheetApp.getActiveSpreadsheet()"
To access the information in the event object, you need to use the 'e':
function onEdit(e) {
//the sheet that was edited
var sheet = e.source.getActiveSheet();
//the cell that was edited
var cell = sheet.getActiveCell();
//the row number of the cell that was edited
var row = cell.getRow();
//the column number of the cell that was edited
var column = cell.getColumn();
From there, proceed as you normally would with sheets and ranges.
To update multiple cells at once, you can set the range with getRange(row, column, numRows, numColumns) and then setValues(values). Note that it's setValues(), not setValue().

How do you show/hide rows based on a particular cell value?

I am attempting to put some show/hide row logic into a google sheet based on a response from a data validation list.
If the user selects the value 'General Account Call' from the data validation list in cell C42 I would like to show rows 43 through to 53 and rows 78 through to 101. Also if a user ticks a check box in cell C40 I would like to show row C41.
I don't know if I can 'monitor' multiple cells with the onEdit function.
I have found a couple of similar(ish) scripts which hide a row based on a value in a cell in the same row and have tried amending them to no avail. I have then tried going back to basics and putting something to monitor a cell and hide a different row, again to no avail
function onEdit(e) {
var ss = SpreadsheetApp.getActive()
var sheet = SpreadsheetApp.getActiveSheet()
var cell = sheet.getRange('D39')
var cellContent = cell.getValue()
if(cellContent === Y) {
Sheet.hideRow(40)
}
}
Your code should be:
function onEdit() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var cell = sheet.getRange('D39');
var cellContent = cell.getValue();
if(cellContent == 'Y') {
sheet.hideRows(11);
}
}
There were a few things wrong:
Even if the ss and sheet declaration work, you were getting the
Sheet from the SpreadsheetApp and not from ss, so ss was not
being used.
cellContent == 'Y' is the correct way to compare the cell to a String, if you remove the quotes, it will interpret it as a variable Y that doesn't exist. Also, === is not necessary as it checks the type and the value, and we only want the value. In fact, it will return false even if the values are the same but are a different type
You wrote Sheet.hideRow instead of sheet.hiderow. Javascript is case-sensitive, so be careful with that!
The method hideRow hides the rows in a given Range, so we have to use hideRows, were you can use the integer (11 in this case) to hide the entire row.
You didn't put any semicolons ;
You didn't get any of these errors as I suppose you were testing the code changing the value of D39. If you execute the code manually, all of these will show up.
So, in order to hide several rows depending of a few cells, you have to get the event information (e), and get the cell that is being edited.
Do an if like this:
var cell = e.range.getA1Notation(); //Gets the Cell you edited
var cell_value = e.range.getValue(); //Gets the value of the cell
if(cell == 'C42' && cell_value == 'General Account Call'){
sheet.showRows(43, 10);
sheet.showRows(78, 23);
}
if (cell == 'C40' && cell_value){ //The checkbox value returns true or false
sheet.showRows(41);
}
The second number in showRows is the number of rows that will be shown.

Google Script to Match A Cell Between Two Sheets and Update A Cell In Second Sheet

In sheet1 I have data that is updated in cell A2 and cell B2. When they are updated I want to run a script that matches the value in A2 with column Q in a different worksheet and when it finds the match, updates the relevant row in column R with the data in cell B2 from sheet1. All variations I have found look to move entire rows or haven't worked. I am a beginner with Script as I have used VBA for years and there only appears to be vague similarities.
Something like this?
function onSheetEdit(e)
{
// get the source range that was edited
var sourceRange = e.range;
// get the associated sheet
var sourceSheet = sourceRange.getSheet();
// get the sheet name
var sourceSheetName = sourceSheet.getName();
if(sourceSheetName == "Sheet1")
{
// if the range edited was one we carea bout
if(sourceRange.getA1Notation() == "A2" || sourceRange.getA1Notation() == "B2")
{
// get the values
var values = sourceSheet.getRange("A2:B2").getDisplayValues()[0];
// open the destination sheet
var destinationSheet = SpreadsheetApp.openById("1ldtZdDiml01_Drlp2WvZ3CaSgABoubauok3BcVq11eI").getSheetByName("Sheet1");
// find the column number of the column we're going to look against
var searchColumnNumber = destinationSheet.getRange("Q1").getColumn();
// get all of the values for the column
var destinationSheetColumnRValues = destinationSheet.getSheetValues(1, searchColumnNumber, -1, 1);
// find the row that has the value we want
var foundRow = destinationSheetColumnRValues.reduce(function(accumulator, currentValue, index) {
if(currentValue[0] == values[0] && accumulator == -1) return index;
return accumulator;
}, -1);
// if we found it
if(foundRow != -1)
{
// set the value in the destination sheet
destinationSheet.getRange("R" + (foundRow + 1 )).setValue(values[1]);
}
}
}
}
You'll need to set this function as the on edit trigger on the sheet. See https://developers.google.com/apps-script/guides/triggers/events for more details.
This code is could be made more efficient depending on the situation. For example, if the destination column is always sorted, or the column being searched against is never changed, etc...

Googlesheet script variable triggered only with manual cell input

I am trying something reasonably simple but can’t get it to work:
I want to hide multiple columns and/or rows based on the value of a cell.
I have it working with a simple script however it seems to only do its job when the trigger cell in question has the value input manually, i.e. I have a drop-down list of “0” & “1” and when I change it manually from “0” to “1” it all works.
However, the cell in question gets its value itself from a simple if condition and even though the value is, in the end, the same it seems the script is not working in such a case.
I would be grateful for any help.
That's the script I found online and is apart from not being triggered correctly in my case very useful:
//TITLE:
//Hide a row if a value is inputted.
//**GLOBALS**
// Sheet the data is on.
var SHEET = "TEST2";
// The value that will cause the row to hide.
var VALUE = "1";
// The column we will be using
var COLUMN_NUMBER = 1
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
//Ensure on correct sheet.
if(SHEET == activeSheet.getName()){
var cell = ss.getActiveCell()
var cellValue = cell.getValue();
//Ensure we are looking at the correct column.
if(cell.getColumn() == COLUMN_NUMBER){
//If the cell matched the value we require,hide the row.
if(cellValue == VALUE){
activeSheet.hideRow(cell);
};
};
};
}
The cell(s) in question use this simple line:
=IF(INDIRECT("A4")=1,"0",IF(E10="NON-FACS",1,0))
Current outcome is: Nothing happens (except when input manually)
The expected outcome is: column number 1 should be hidden