hide columns based on user input cell - google-apps-script

hi all (I am new to scripting),
here is a sample of my sheet I need help with.
https://docs.google.com/spreadsheets/d/1iypkWdUsSkow9m8nTSFS25HgY1d5vsVMZvjEynwQJcM/edit?usp=sharing
what i need is a script that will run onedit.
the user has 5 selectable fields, highlighted in yellow. the script should run only if cell F3 is edited.
and what it should do is hide all column where row 1 does not match F3.
please please help!

I wrote this small function that hides or unhides columns depending on the value of the dropdown in F3, and that only runs when this cell is modified.
Copy this to the script bound to your spreadsheet:
function onEdit(e) {
var ss = e.source; // Spreadsheet that triggered the function
var sheet = ss.getActiveSheet();
var sheetName = "Sheet1"; // Change accordingly
var range = e.range; // Range that was edited
var editedColumn = range.getColumn();
var editedRow = range.getRow();
var column = 6;
var row = 3;
// Check that the edited cell is F3 and the edited sheet is the one you want:
if(column == editedColumn && row == editedRow && sheet.getName() == sheetName) {
var dropdownValue = range.getValue(); // Value of F3
// Index of last column with content. If you want to hide the blank columns after that, use sheet.getMaxColumns() instead:
var cols = sheet.getLastColumn();
// First row values:
var headers = sheet.getRange(1, 1, 1, cols).getValues()[0];
// Looping through each column (hiding or unhiding depending on whether value matches):
for(var i = 1; i < cols; i++) {
if(headers[i] != dropdownValue) {
sheet.hideColumns(i + 1);
} else {
sheet.showColumns(i + 1);
}
}
}
}
Please tell me if that works for you.

Related

How to create a Google apps script array list of sheet names and use it in if statement?

I am trying to get my Google sheet to fill in the date in column A when I fill in column B and have that function work on multiple sheets within the spreadsheet.
So far I have a working script that works on my first sheet. I have tried several things like making an array out of the variable (but that makes only the last array name work), trying an OR statement with 2 variables (but that fucked up the column it should watch), ...
Can you guys help me with this?
this is the one that works for 1 sheet name:
function onEdit() {
// writes the current date to the cell to the right on the row when a cell in a specific column is edited
// adjust the following variables to fit your needs
var sheetNameToWatch = "2021";
var columnNumberToWatch = /* column A */ 2; // column A = 1, B = 2, etc.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
var val=sheet.getActiveCell().getValue()
if (sheet.getName() == sheetNameToWatch && range.getColumn() == columnNumberToWatch && val!= "" /* I changed this var value so if I input anything, it will update the date */) {
var targetCell = sheet.getRange(range.getRow(), range.getColumn()-1 /* changed this to "-1" so it will input to the left column */
);
targetCell.setValue("" + Utilities.formatDate(new Date(), "CET", "dd/MM/yyyy"));
}
}
Demo can be found here: https://docs.google.com/spreadsheets/d/1mLBJrx3VCCwtcfUk-q_1DhwZFdA1cdrqFcySfC0cAi0/edit?usp=sharing
Just a minor edit on the code you provided:
function onEdit() {
// writes the current date to the cell to the right on the row when a
cell in a specific column is edited
// adjust the following variables to fit your needs
var columnNumberToWatch = /* column A */ 2; // column A = 1, B = 2, etc.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
var val=sheet.getActiveCell().getValue()
if (range.getColumn() ==
columnNumberToWatch && val!= "") {
var targetCell = sheet.getRange(range.getRow(), range.getColumn()-1
);
targetCell.setValue("" + Utilities.formatDate(new Date(), "CET", "dd/M
M/yyyy"));
}
}
The following code snippet has been removed:
var sheetNameToWatch = "2021";
sheet.getName() == sheetNameToWatch &&
Technically your code is already good, we just need to remove the condition based on your IF Statement since SpreadsheetApp.getActiveSheet(); will detect the current sheet you are working on.

Google Script - Unable to copy from one sheet to another

This is my first Google Script and I am coming from a VBA background so I have likely missed something obvious. I am attempting to copy from one sheet to another, some that is quite simple in VBA, but I am struggling with it and I dont understand what I am missing
The below code I would have though would copy a range in one sheet to another sheet. Not the whole range, just a section of it and only 1 row per an OnEdit()
I checked the ranges I am wanting to copy from and copy to using targetSheet.getRange(targetSheet.get1stNonEmptyRowFromBottom(1) + 1, 1,1,numColumns-1).activate(); & sheet.getRange(row, 1, 1, numColumns-1).activate(); and it selects the range I would expect
Currently the execution doesn't show any fails either
function onEdit(e) {
//This is sheet we will be copied to
const VALUE = ["LEAD","LANDSCAPE"];
//This is the column for the check box
const COLUMN_NUMBER = 25
//The main sheet that is being copied from
const MAIN_SHEET = 'Form Responses 1'
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var lead_or_landscape = sheet.getRange(row,20).getValue();
//This is so we dont run this by mistake on another cell edit or sheet
if((COLUMN_NUMBER == cell.getColumn() && MAIN_SHEET == sheet.getName && cell.isChecked() == true)
&& (lead_or_landscape == VALUE[0] || lead_or_landscape == VALUE[1])){
//copies row from current sheet to the specificed sheet (Lead or landscape)
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName(lead_or_landscape);
var target = targetSheet.getRange(targetSheet.get1stNonEmptyRowFromBottom(1) + 1, 1,1,numColumns-1);
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target());
}
}
Object.prototype.get1stNonEmptyRowFromBottom = function (columnNumber, offsetRow = 1) {
const search = this.getRange(offsetRow, columnNumber, this.getMaxRows()).createTextFinder(".").useRegularExpression(true).findPrevious();
return search ? search.getRow() : offsetRow;
};
You've to use parentheses in sheet.getName() and not use them in copyTo(target())
And you can use sheet.appendRow() method instead of copyTo(), that is easier.
function onEdit(e) {
//This is sheet we will be copied to
const sheets = ["LEAD","LANDSCAPE"];
//This is the column for the check box
const colNumber = 25;
//The main sheet that is being copied from
const mainSheet = 'Form Responses 1';
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var leadOrLandscape = sheet.getRange(row,20).getValue();
//This is so we dont run this by mistake on another cell edit or sheet
if(colNumber == cell.getColumn()
&& mainSheet == sheet.getName()
&& cell.isChecked() == true
&& sheets.includes(leadOrLandscape)){
//copies row from current sheet to the specificed sheet (Lead or landscape)
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName(leadOrLandscape);
targetSheet.appendRow(sheet.getRange(row, 1, 1, numColumns-1).getValues()[0])
}
}
I just took a quick look at your code, are you sure about this line?
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target());
it shouldn't rather be
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target);

Combine two functions that must work one after another (with trigger)

I have two working functions. One of them is myFunction with a trigger. Is protects the row of the cell when any information is entered in this cell in Column4.
function myFunction(e) {
const sheetNames = ['Sheet1', 'Sheet2', 'Sheet3']; // Please set the sheet names you want to run the script.
const range = e.range;
const sheet = range.getSheet();
const value = range.getValue();
const row = range.getRow();
if (!sheetNames.includes(sheet.getSheetName()) || range.getColumn() != 4 || row == 2 || value == "") return;
const p = sheet.getRange(`B${row}:D${row}`).protect();
const owner = Session.getActiveUser().getEmail();
p.getEditors().forEach(f => {
const email = f.getEmail();
if (email != owner) p.removeEditor(email);
});
}
Another function is an onEdit function. It adds date in Column1 when I enter information in Column4. The date appears in the same row with the cell in Column4.
function onEdit() {
var colToCheck = 4;
// Offset from the input [row, column]
var dateOffset = [0, -3];
// Sheets to proceed on
var sheetNames = ['Sheet1', 'Sheet2', 'Sheet3'];
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var name = sheet.getName();
if (sheetNames.indexOf(name) > -1) {
var cell = sheet.getActiveCell();
var col = cell.getColumn();
if (col == colToCheck) {
var dateTimeCell = cell.offset(dateOffset[0], dateOffset[1]);
dateTimeCell.setValue(new Date());
}
}
}
How these two functions can be combined in one sheet?
I just added two separate functions to one sheet: the one with trigger and the one onEdit as two different codes. And they work as I need. So, we do not need to combine them somehow. They just work one after another. First, the one onEdit function works, and as it adds info to the necessary cell, the function with trigger starts working.

Google App Script update cell value in another sheet

I'm a little stuck on this one. I'm trying to find the corresponding row and update the last column in another google spreadsheet after updating the first column of another spreadsheet.
When the user selects "Restocked" in ColA of spreadsheet X , I need to lookup the ID value in ColB on another sheet (Y). Then I need to access spreadsheet Y, find the row that contains that same ID. Access the last column or columnAZ (52) and change the cell value to "Restocked".
Here is what I have so far...
function restockComplete(){
var s = SpreadsheetApp.getActiveSpreadsheet();
if( s.getName() == "Restock Queue"){
var r = s.getActiveCell();
if ( r.getColumn() == 1 && r.getValue() == "Restocked"){
var nextCell = r.offset(0, 1);
var buybackId = nextCell.getValue();
// Opens SS by its ID
var ss = SpreadsheetApp.openById("xxxxxxxxxxxxxxxSheetIDHerexxxxxxxxxxx");
var sheet = ss.getSheetByName('NameOfSheetHere'); // Name of sheet
// var range = sheet.getRange(1,1); // Gets Column 1 Cell 1 value
//var data = range.getValue();
var data = sheet.getDataRange().getValues();
//var buyback = sheet.getRange(buybackId).getValue();
for(var i = 0; i<data.length;i++){
if(data[i][1] == buybackId){ //[1] because column B
Logger.log((i+1))
i.offset(0, 52).setValue('Restocked');
return i+1;
}
}
}
}
};
You're close, save for one error. Right now, to test for the sheet name, you have to actually get the sheet. I would do the following to fix the immediate problem:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet() // call this for the active sheet
...
You also had an error in your loop setting the value:
for(var i = 0; i<data.length;i++){
if(data[i][1] == buybackId){ //[1] because column B
// Get the range of the cell, not the index.
sheet.getRange((i+1), 1).setValue('Restocked');
}
}
...
Rename your secondary sheet from ss to something else to avoid a conflict.
Beyond this fix, there are some changes I'd recommend making to make the script more efficient for your users. Rather than look for the active cell, you can use the onEdit simple trigger with an e event object. This will allow your script to modify cells regardless of where the active cell is.
function onEdit(e){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var s = ss.getActiveSheet();
if( s.getName() == "Restock Queue"){
if ( (e.range.getColumn() == 1.0) && (e.range.getValue() == "Restocked") ){
var nextCell = e.range.offset(0, 1);
var buybackId = nextCell.getValue();
var ss2 = SpreadsheetApp.openById('xxx');
var sheet = ss2.getSheetByName('NameOfSheetHere'); // Name of sheet
var data = sheet.getDataRange().getValues();
for(var i = 0; i<data.length;i++){
if(data[i][1] == buybackId){ //[1] because column B
// Get the range of the cell, not the index.
sheet.getRange((i+1), 52).setValue('Restocked');
}
}
}
}
}

Need to return the displayed value not formula when copying a row between sheets

Im currently using google sheets and a script to move a portion of row when i select "ok" in a data validation column , the problem is that it copies the formulas of each cell and not the displayed value, and ideas, Im not the best at this so any help is HUGE.
/**
* Moves row of data to another spreadsheet based on criteria in column 6 to sheet with same name as the value in column 4.
*/
function onEdit(e) {
// see Sheet event objects docs
// https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events
var ss = e.source;
var s = ss.getActiveSheet();
var r = e.range;
// to let you modify where the action and move columns are in the form responses sheet
var actionCol = 6;
var nameCol = 4;
// Get the row and column of the active cell.
var rowIndex = r.getRowIndex();
var colIndex = r.getColumnIndex();
// Get the number of columns in the active sheet.
// -1 to drop our action/status column
var colNumber = s.getLastColumn()-1;
// if our action/status col is changed to ok do stuff
if (e.value == "ok" && colIndex == actionCol) {
// get our target sheet name - in this example we are using the priority column
var targetSheet = s.getRange(rowIndex, nameCol).getValue();
// if the sheet exists do more stuff
if (ss.getSheetByName(targetSheet)) {
// set our target sheet and target range
var targetSheet = ss.getSheetByName(targetSheet);
var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, 6); //6 represents Numer of Columns to Copy
// get our source range/row
var sourceRange = s.getRange(rowIndex, 1, 1, 6); //6 represents Numer of Columns to Copy
// new sheets says: 'Cannot cut from form data. Use copy instead.'
sourceRange.copyTo(targetRange);
// ..but we can still delete the row after
// or you might want to keep but note move e.g. r.setValue("moved");
}
}
}
Add the option to sourceRange.copyTo(targetRange); as described here:
https://developers.google.com/apps-script/reference/spreadsheet/range#copyTo(Range,Object)
Please look at the docs before posting, thanks. Good luck.