Different trigger in a sheet for multiple IF ELSE Statement - google-apps-script

here's my activesheet is "_input"
range F12:F21 checkboxes when it false then using default formula, when true then input normal number in offset(0,1) which is column G12:G21
range G24 is dropdown which will update offset(0,1) value, H24, when update.
here's my code
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('_input');
var range = sheet.getActiveCell();
var def = 6; // column A = 1, B = 2, etc.
var opt = false;
var row = 11;
if (range.getColumn() == def && range.getValue() == opt && range.getRow()> row && range.getRow()< 22) {
range.offset(0, 1).setValue('=IFERROR(VLOOKUP(inpItem,mstItem,2,0),0)');
}
}
function onEdit(evt) {
var sh = evt.source.getActiveSheet();
var rng = evt.source.getActiveRange("");
var tBat = rng.offset(0,1);
if (sh.getName() == '_input' && rng.getColumn() == 7 && rng.getRow() > 23 && rng.getValue() == "B1") {
tBat.setValue('09:00');
} else if (sh.getName() == '_input' && rng.getColumn() == 7 && rng.getRow() > 23 && rng.getValue() == "B2") {
tBat.setValue('15:00');
} else {
tBat.clearContent();
tBat.setNumberFormat("HH:mm");
}
}
but it doesn't work properly because when i change one of onEdit function to make another onEdit function running.
please advise for my mistake here.
When i change F12:F21 and run script to edit G12:G21 won't effect to G24 and H24.

Related

How do I define an IF statement for a cell contains a specific value in Apps Script?

I have a script that adds a timestamp to a cell when another cell in the row is initially filled in. What I would like to do is only timestamp when a cell contains the word "Completed". It doesn't seem to be working though.
var SHEET_NAME = 'Sheet 1';
var DATETIME_HEADER = 'datetime';
function getDatetimeCol(){
var headers = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME).getDataRange().getValues().shift();
var colindex = headers.indexOf(DATETIME_HEADER);
return colindex+1;
}
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSheet();
var cell = ss.getActiveCell();
var datecell = ss.getRange(cell.getRowIndex(), getDatetimeCol());
//Here's the line where I added an "if the active cell is labelled completed then add a timestamp to the datetime column"
if (ss.getName() == SHEET_NAME && cell.getColumn() == 8 && !cell.isBlank() && datecell.isBlank() && cell.getValues == "Completed") {
datecell.setValue(new Date()).setNumberFormat("yyyy-MM-dd hh:mm");
}
}
;
Try it this way:
function onEdit(e) {
const sh = e.range.getSheet();
const col = sh.getRange(1,1,1,sh.getLastColumn()).getValues().flat().reduce((a,h,i)=> (a[h]=i+1,a),{});
const dateCell = sh.getRange(e.range.rowStart,col['datetime']);
if (sh.getName() == "SHEET_NAME" && e.range.columnStart == 8 && datecell.isBlank() && e.value == "Completed") {
datecell.setValue(new Date()).setNumberFormat("yyyy-MM-dd hh:mm");
}
}

Toggle rows hide/show between top down checkbox

trying to make a semi/manual tree structure. if check box = true. in a topdown manner. it will look for another check box in the downside direction and unhide rows. i.e. show A2 to A9. if box = false then, Hide: A11 till A19. if there is no check box until the last row it will hide/show all the rows. i.e. B23/B2000. it's a top-down approach so the only action only is limited to a particular column and between the boxes cells are blanks.
function onEdit(e){
const sheet = SpreadsheetApp.getActiveSheet();
const range = e.range;
const editedValue = e.value;
if (range.getA1Notation() === "A1" && editedValue === "TRUE") {
sheet.unhideRow(sheet.getRange("A:A9"));
} else if (range.getA1Notation() === "A1" && editedValue === "TRUE") {
const firstRow = 1;
const lastRow = sheet.getLastRow();
if (pValue === true) {
sheet.hideRows(i + firstRow);
}
});
} else if (e.range.columnStart === 9 && editedValue === "TRUE") {
sheet.hideRows(range.rowStart);
}
}
Solution:
You can use this script to check the rows below the edited checkbox and hide/show rows accordingly:
function onEdit(e){
const sheet = SpreadsheetApp.getActiveSheet();
const range = e.range;
const editedValue = e.value;
const row = range.getRow();
const col = range.getColumn();
const lastRow = sheet.getMaxRows();
var data = sheet.getRange(row+1,col,lastRow-row+1,1).getValues();
for (var i = 0; i < data.length; i++) {
if (data[i][0] === true || data[i][0] === false) {
++i;
break;
}
}
if (i > 1) {
if (editedValue === "FALSE")
sheet.hideRows(row+1,i-1);
else if (editedValue === "TRUE")
sheet.showRows(row+1,i-1);
}
}
Sample Output:

Check if Column Contains a Value

What do I add to the if statement to check if Column 5 in the applicable row contains a value and prevent the setValue() from overriding the old value?
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var i = ['Sheet1', 'Sheet2'].indexOf(sheet.getName());
if (e.range.getValue() != '' && i > -1 && e.range.columnStart === 1) {
e.range.offset(0,4).setValue(Utilities.formatDate(new Date(), "GMT-8", "MM/dd/yyyy"));
}
}
Explanation:
Add a condition in the if statement for column 5 to be empty at row in order to fill it:
sheet.getRange(row,5).getValue()==''
Solution:
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var row = e.range.getRow();
var i = ['Sheet1', 'Sheet2'].indexOf(sheet.getName());
if (e.range.getValue() != '' && i > -1 && e.range.columnStart === 1 && sheet.getRange(row,5).getValue()=='') {
e.range.offset(0,4).setValue(Utilities.formatDate(new Date(), "GMT-8", "MM/dd/yyyy"));
}
}
Or:
I formatted your code a little bit to make it more compact:
function onEdit(e) {
const sheet = e.source.getActiveSheet();
const row = e.range.getRow();
const col = e.range.getColumn();
const sheets = ['Sheet1', 'Sheet2'];
if (e.range.getValue() != '' && sheets.includes(sheet.getName())
&& col === 1 && sheet.getRange(row,5).getValue()==''){
e.range.offset(0,4).setValue(Utilities.formatDate(new Date(), "GMT-8", "MM/dd/yyyy"));
}
}

Google Scripts - Compare Color & Change Font Color

I am trying to compare data from two different columns and when they don't match I want the data in column 6 to turn Red and if it is changed back to match it turns back to black.
I don't want to use to conditional formating from the menue because I dont want people to be able to turn it off.
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var activeCell = sheet.getActiveCell();
var col = activeCell.getColumn();
var row = activeCell.getRow();
var col6 = activeCell.getColumn( col == 6 && row >=5 && row <=55 && sheet);
var col14 = activeCell.getColumn( col == 14 && row >=5 && row <=55 && sheet);
var first = get.Value(col6);
var second = get.Value(col14);
//Start Time Function
if (col == 1 && row>=5 && row<=55 && sheet.getRange(row,col).getValue() == ""){
sheet.getRange(row,1,1,sheet.getMaxColumns()).clearContent();
}
else if (col == 1){
sheet.getRange(row,col+11).setValue(new Date()).setNumberFormat('hh:mm:ss');
sheet.getRange(row,col+13).setValue(new Date()).setNumberFormat('hhmm');
sheet.getRange(row,col+5).setValue(new Date()).setNumberFormat('hhmm');
sheet.getRange(row,col+3).setValue(new Date()).setNumberFormat();
}
//End Time Function
if (col == 8 && row>=5 && row<=55 && sheet.getRange(row,col).getValue() == ""){
sheet.getRange(row,7,1).clearContent() && sheet.getRange(row,13,1).clearContent() && sheet.getRange(row,15,1).clearContent();
}
else if (col == 8) {
sheet.getRange(row,col+5).setValue(new Date()).setNumberFormat('hh:mm:ss');
sheet.getRange(row,col+7).setValue(new Date()).setNumberFormat('hhmm');
sheet.getRange(row,col-1).setValue(new Date()).setNumberFormat('hhmm');
}
// Data Valadation Start Time
// Confirm data in column 6 matches column 14, if different set column 6 font to red.
if(first != second){
var cell = sheet.getRange(first);
cell.setFontColor("red");
}
else if(first == second){
var cell = sheet.sheet.getRange(first);
cell.setFontColor("black");
}
}
Working Code.
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var activeCell = sheet.getActiveCell();
var col = activeCell.getColumn();
var row = activeCell.getRow();
//Start Time Function
if (col == 1 && row>=5 && row<=55 && sheet.getRange(row,col).getValue() == ""){
sheet.getRange(row,1,1,sheet.getMaxColumns()).clearContent();
}
else if (col == 1){
sheet.getRange(row,12,1).setValue(new Date()).setNumberFormat('hh:mm:ss'); //real time
sheet.getRange(row,14,1).setValue(new Date()).setNumberFormat('hhmm').setNumberFormat("#");
sheet.getRange(row,6,1).setValue(new Date()).setNumberFormat('hhmm').setNumberFormat("#");
sheet.getRange(row,4,1).setValue(new Date()).setNumberFormat(); //Date Row
} // END - Start Time Function
//End Time Function
if (col == 8 && row>=5 && row<=55 && sheet.getRange(row,col).getValue() == ""){
sheet.getRange(row,7,1).clearContent() && sheet.getRange(row,13,1).clearContent() && sheet.getRange(row,15,1).clearContent();
}
else if (col == 8) {
sheet.getRange(row,13,1).setValue(new Date()).setNumberFormat('hh:mm:ss'); // real time
sheet.getRange(row,15,1).setValue(new Date()).setNumberFormat('hhmm').setNumberFormat("#");
sheet.getRange(row,7,1).setValue(new Date()).setNumberFormat('hhmm').setNumberFormat("#");
} // END - End Time Function
// Data Valadation - Start Time
var firstF = sheet.getRange(row,6,1);
var secondN = sheet.getRange(row,14,1);
if(firstF.getValue() != secondN.getValue()){
var cell = firstF;
cell.setFontColor("red");
}
else {
var cell = firstF;
cell.setFontColor("black");
} // END - Data Valadation - Start Time
// Data Valadation - End Time
var firstG = sheet.getRange(row,7,1);
var secondO = sheet.getRange(row,15,1);
if(firstG.getValue() != secondO.getValue()){
var cell = firstG;
cell.setFontColor("red");
}
else {
var cell = firstG;
cell.setFontColor("black");
} // END - Data Valadation - End Time
} // END - function onEdit
Be careful not to mix up ranges and values
Also, you seem to use methods methods that do not exist in Apps Script / cannot be used with parameters
Please check the documentation for getValues() and getColumn()
A modified working sample based on your code:
function onEdit(e) {
var activeCell = e.range;
var sheet = e.range.getSheet();
var col = activeCell.getColumn();
var row = activeCell.getRow();
var first = sheet.getRange(row, 6);
var second = sheet.getRange(row, 14);
if(first.getValue() != second.getValue()){
var cell = first;
cell.setFontColor("red");
}
else {
var cell = first;
cell.setFontColor("black");
}
}

How to pass a variable from an onEdit(e) function

I have two scripts that run individually, but I can't seem to merge them together correctly. I am attempting to use the onEdit(e) function to capture the row of the cell that is edited, then used that row number to amend a different sheet.
function onEdit(e) {
if (
e.source.getSheetName() == "GPS" &&
e.range.columnStart == 10 &&
e.range.columnEnd == 10 &&
e.range.rowStart >= 4 &&
e.range.rowEnd <= 5000
) {
var range = e.range;
var row = range.getRow();
var change = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var url = change.getRange(row,1,1,1).getValue(); //How to use this variable????????????
function toMaster(change,row){
var dest = SpreadsheetApp.openById('destinationsheetidxxxx')
var s = dest.getSheetByName('GPS')
var data = s.getDataRange().getValues();
var url = change.getRange(row,1,1,1).getValue()
for(var i = 0; i<data.length;i++){
if(data[i][0] == url){
Logger.log((i+1))
var range = s.getRange(i+1,10,1,1);
range.setValue('Yes')
}
Try this:
function onEdit(e) {
var sh=e.range.getSheet();
if(sh.getName()=="GPS" && e.range.columnStart==10 && e.range.columnEnd == 10 && e.range.rowStart >= 4 && e.range.rowEnd<=5000) {
var row = e.range.rowStart;
var url = sh.getRange(row,1).getValue();
var dss=SpreadsheetApp.openById('destId')
var dsh=dss.getSheetByName('GPS')
var drg=dsh.getRange(row,1)
var data=drg.getValues()
for(var i = 0; i<data.length;i++){
if(data[i][0]==url){
Logger.log(i+1);
var range = dsh.getRange(i+1,10).setValue('Yes');
}
}
}
}