The goal:
Get the edited checkbox
Get all checkboxes in range (column 2–7, same row as edited checkbox)
If all checkboxes return "TRUE", set backgrounds on range (column 1–7, same row as edited checkbox)
Seems like the code do nothing.
function onEdit(event) {
var sheet = event.source.getActiveSheet(), //get edited sheet
row = event.range.getRow(), // get row needed
column = 2, // set the starting column
test,
userValues = [];
while (column<=7) {
if (sheet.getValue(row,column) == "TRUE") {
test = true
} else {
test = false;
break;
}
column++;
}
if (test) {
sheet.getRange(row,1,1,7).setBackgrounds("#b6d7a8");
}
}
I believe your goal is as follows.
You have the checkboxes to the columns "B" to "G".
When all checkboxes from the columns "B" to "G" are checked, you want to set the background color of the columns "A" to "G" of the same row to #b6d7a8.
In your situation, I guessed that when all checkboxes are not checked, you might want to set the background color to the default color.
When I saw your script, getValue is used in the loop. In this case, the process cost will be high. And, when you use sheet.getRange(row,1,1,7).setBackgrounds("#b6d7a8"), you can use sheet.getRange(row,1,1,7).setBackground("#b6d7a8").
In this case, how about the following modification?
Modified script:
function onEdit(event) {
var sheetName = "Sheet1"; // Please set the sheet name.
var range = event.range;
var sheet = event.source.getActiveSheet();
if (sheet.getSheetName() != sheetName || range.columnStart < 2 || range.columnStart > 7) return;
var r = sheet.getRange(range.rowStart, 1, 1, 7)
var checks = r.offset(0, 1, 1, 6).getValues()[0].every(e => e === true);
r.setBackground(checks ? "#b6d7a8" : null);
}
When you use this script, please check the checkboxes the columns "B" to "G". When all checkboxes from the columns "B" to "G" are checked, the background color of columns "A" to "G" is changed to #b6d7a8.
Note:
This script is run by the OnEdit trigger. So please edit the cells of checkboxes from the columns "B" to "G". By this, the script is run. When you directly run this script with the script editor, an error occurs. Please be careful about this.
When you are not required to check the sheet name, you can also use the following script.
function onEdit(event) {
var range = event.range;
var sheet = event.source.getActiveSheet();
if (range.columnStart < 2 || range.columnStart > 7) return;
var r = sheet.getRange(range.rowStart, 1, 1, 7)
var checks = r.offset(0, 1, 1, 6).getValues()[0].every(e => e === true);
r.setBackground(checks ? "#b6d7a8" : null);
}
References:
every()
setBackground(color)
Related
If data in a cell in Column B has a A or B as the 2nd last letter ONLY - (example of Location G08B1) - Copy that row to another sheet.
I use a modified version of copy row if certain cell has certain word, so not sure how to modify this to what I need.
function CopyAorBLocation() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "FORKLIFT" && r.getColumn() == 7 && r.getValue() == copy AorB if 2nd last letter - if not ignore)
{
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSS =
SpreadsheetApp.openById("");
s = SpreadsheetApp.getActiveSheet();
var tempSheet = s.copyTo(targetSS);
var targetSheet = targetSS.getSheetByName("ONLINERELOCATION");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
tempSheet.getRange(row, 4, 1, 3).copyTo(target);
Hoping this is not too complicated to achieve.
Thanks in Advance
The input and output sample values are the column "B" and the columns "C:D", respectively.
You want to put the values of column "B" to the column "C" and "D" by the 2nd last character of each value of the column "B".
Put the values ###A# and ###B# to the column "C".
Put the values ###C# and ###D# to the column "D".
You want to achieve this using Google Apps Script.
I could understand like above. If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
In this answer, the 2nd last character of each value is retrieved by substring().
Sample script:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var srcValues = sheet.getRange(2, 2, sheet.getLastRow() - 1, 1).getValues();
var dstValues = srcValues.map(function([b]) {
var len = b.length;
var s = b.substring(len - 2, len - 1).toUpperCase();
return (s == "A" || s == "B") ? [b, ""] : (s == "C" || s == "D") ? ["", b] : ["", ""];
});
sheet.getRange(2, 3, dstValues.length, 2).setValues(dstValues);
}
In this sample script, Sheet1 is used.
Note:
This sample script is for your shared Spreadsheet. If the format is different from your shared Spreadsheet, the script might not work. Please be careful this.
Reference:
substring()
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.
New to writing Google scripts. Have found similar questions but none with answers that I could make work. I want the value of the cell in column "H" of a given row on sheet "main" to be set to "Y" when the cell in column "G" of the same row is edited to be "y". I can not use a formula for this, as I need the values in "H" to remain after those in "G" are deleted. Current code I am working with is below. Returns no errors but also does not change anything in the sheet. It is not written as onEdit because I am using a separate onEdit function to call multiple functions (including this one when it is correct).
function myFunction3() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("main");
var range = sheet.getActiveCell();
var columnNumberToWatch = 7; // column A = 1, B = 2, etc.
var valueToWatch = "y";
var right = range.offset(0,1);
if (range.getColumn() == columnNumberToWatch && range.getValue() ==
valueToWatch) {
sheet.getRange(right).setValue('Y');
}
}
Try this -
function myFunction3() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('main');
var range = sheet.getActiveCell();
var columnNumberToWatch = 7; // column A = 1, B = 2, etc.
var valueToWatch = 'y';
if (range.getColumn() == columnNumberToWatch && range.getValue() == valueToWatch) {
range.offset(0, 1).setValue('Y');
}
}
In your description you seem to be saying that if the value in column G is "y" then you want to make the value in column "H" equal to "Y". The range = activeCell(), column number is 7, and valueToWatch = "y".
So what you need to do is get the value in range (e.g. the active cell) and change the value in the cell next to it to "Y".
So your conditional statement needs to start with the thing you are testing (e.g. range.getValue() and if that value is in the columnToWatch then set the value in the column next to it to "Y".
First thing you need to so is to get the column number of the active cell.
try range.getColumn() and assign it to a new variable (i.e. activeColumnNumber)
then start your if statement with range.getValue().
if (range.getValue == 'y' && activeColumnNumber == 7) etc., etc. it should work.
I've made a well-working script to copy cells *OnEdit (col16 on sheet 2) if any row in Col16 = "Yes") to last row of custom column on sheet 1(now Col4). But I have a Query based data on sheet 2, so my script copies data only when I type "Yes" by hands. That's why now I need to run this script by button, or maybe as a time-driven trigger. Can't get it to work by button. How to change the following script to make it possible to work by clicking on button?
function onEdit(e) {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
if (sheet.getName() !== '2' || e.range.getColumn() !== 16 || e.value !== 'Yes') return;
var value = e.range.offset(0,-12,1,1).getValue();
sheet = e.source.getSheetByName('1');
var grd = sheet.getRange("D:D").getValues();
var maxIndex = grd.reduce(function(maxIndex, row, index) {
return row[0] === "" ? maxIndex : index;
}, 0);
sheet.getRange(maxIndex+2,e.range.getColumn()-12,1,1).setValue(value);
}
UPDATE: I've tried to change my script like this, assigned it to button, and after clicking on button- it say "Running..... then Finished..." but it don't copy anything (but it works when it's OnEdit(e), and I m not getting any error.
But it seems it's not enough just change "OnEdit(e)" to "copymissings()", I need to change something in code, but I don't know what exactly. Please help:
function copymissings() {
var s = SpreadsheetApp.getActive();
if (s.getName() !== '2' || range.getColumn() !== 16 || value !== 'Yes') return;
var value = range.offset(0,-12,1,1).getValues();
sht = s.getSheetByName('1');
var grd = sheet.getRange("D:D").getValues();
var maxIndex = grd.reduce(function(maxIndex, row, index) {
return row[0] === "" ? maxIndex : index;
}, 0);
sht.getRange(maxIndex+2,range.getColumn()-12,1,1).setValues(value);
}
Visualisation:
CLICK TO SEE GIF
I think you're mixing two concepts here. onEdit() is a trigger that runs AUTOMATICALLY when a user changes the value of a cell. However what you're trying to do is MANUAL, as the user is in charge when the event will trigger.
Refer to HTML Service: Create and Serve HTML on how create UI buttons. You can check actual samples here.
Okay big thanks to Edward Ulle from "Plus" google apps script forum.
We've made working version of same script as I offered in post which is automatically working OnEdit.
The following script copies cells from Sheet-2 Col4 if that row contains "Yes" in col16 to Sheet-1 col4. Everything optional.
function copymissings() {
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Source sheet
var shs = ss.getSheetByName("2");
// Values from Sheet2
var vs = shs.getRange(1,1,shs.getLastRow(),shs.getLastColumn()).getValues();
// Destination sheet
var shd = ss.getSheetByName("1");
// Get the destination range
var rd = shd.getRange("D:D");
// Gets a 2D array
var vd = rd.getValues();
var j = 1;
// Get offset j to first empty row
for( j=0; j<vd.length; j++ ) {
if( vd[j][0] == 0 ) break;
}
// Assuming you want to do for every row in Sheet2
for( var i=0; i<vs.length; i++ ) {
if( vs[i][15] == "Yes" ) { // Column 16 is index 15
// Use offset from last row of destination sheet
rd.offset(j,0,1,1).setValue(vs[i][3]); // Copy to column 4 (0)
j++; // Increment to next row
}
}
}
catch(err) {
Logger.log(err);
}
}
Situation:
I find this script, that delete the rows when the text in the column B change to "Closed". I want to copy the row before to delete into other sheet called historic.
Action:
The script should be copy the row when the the status is "Closed" in other sheet called "Historic" in the same spreadsheeet.
Then when the first point is completed should be delete the rows in the activesheet.
SCRIPT DELETE ROWS:
function DeleteRow(e) {
try {
var ss = e.source; // Just pull the spreadsheet object from the one already being passed to onEdit
var s = ss.getActiveSheet();
// Conditions are by sheet and a single cell in a certain column
if (s.getName() == 'ISP1' && // change to your own
e.range.columnStart == 2 && e.range.columnEnd == 2 && // only look at edits happening in col 2 which is 2
e.range.rowStart == e.range.rowEnd ) { // only look at single row edits which will equal a single cell
checkCellValue(e);
}
} catch (error) { Logger.log(error); }
};
function checkCellValue(e) {
if ( e.value == 'Closed') { // Delete if value is zero or empty
e.source.getActiveSheet().deleteRow(e.range.rowStart);
}
}
SCRIPT HISTORIC:
This script when somone update the column 5 will copy the row to other sheet called "historic".
When somone change the column 9 and select the status "Closed" the script copy the row to the historic and insert the closed date.
Now, does exist any why to do the same and improve the perfomance? I think this script is very complex and use many line.. I don't know if possible do the same better.
function Historic(e) { //CopyRows
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var r = SpreadsheetApp.getActiveRange();
var date = Utilities.formatDate(new Date(), "GMT-3", "dd/MM/yyyy HH:mm"); // Function Date + Format
// 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.
var colNumber = s.getLastColumn();
// Move row based on criteria in column 5, and if row is not the header.
if (colIndex == 5 && rowIndex != 1) {
// Get value from column 5, in the active row.
var status = s.getRange(rowIndex, colIndex).getValue();
// Do nothing if criteria value is not actually changed to something else.
if (s.getName() != 'Historic') {
// The target sheet is the one with the same name as the criteria value.
var targetSheet = ss.getSheetByName('Historic');
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(rowIndex, 1, 1, colNumber).copyTo(target);
//s.deleteRow(rowIndex); // This line delete the source row
targetSheet.getRange(targetSheet.getLastRow(), 11).setValue(s.getSheetName()); //Insert in the Column 11 the SheetName where was modify that line
}
}
else if (colIndex == 9 && rowIndex != 1 && e.value == 'Closed' ) {
// Get value from column 5, in the active row.
var status = s.getRange(rowIndex, colIndex).getValue();
// Do nothing if criteria value is not actually changed to something else.
if (s.getName() != 'Historic') {
// The target sheet is the one with the same name as the criteria value.
var targetSheet = ss.getSheetByName('Historic');
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(rowIndex, 1, 1, colNumber).copyTo(target);
targetSheet.getRange(targetSheet.getLastRow(),10).setValue(date); //This Line Insert Close Date when the user select option Close
targetSheet.getRange(targetSheet.getLastRow(),11).setValue(s.getSheetName()); //Insert in the Column 11 the SheetName where was modify that line
e.source.getActiveSheet().deleteRow(e.range.rowStart); // This line delete the source row
}
}
}
I see somone vote this question -1. I'm using the Historic the second part, this part copy and then delete the row.
If anyone have a better idea, I will appreciate your help.
Thanks So much