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:
Related
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.
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");
}
}
My script is able to cross out the first column juste after the the check box, while I'm looking to cross out the whole row.
Also, I'd like to apply a different colour when the box is ticked.
function onEdit(e){
var mySheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var myRange = e.range;
var mySheetName = mySheet.getSheetName();
var myStatus = myRange.getValue();
var currRow = myRange.getRow();
var currCol = myRange.getColumn();
var myItem = mySheet.getRange(currRow, currCol + 1);
if (
mySheetName === 'Feuille1'
&& currCol === 1
) {
if (
myStatus
) {
myItem.setFontLine("line-through");
} else {
myItem.setFontLine(null);
};
};
};
Set Line Through
function onEdit(e) {
//e.source.toast("Entry")
const sh = e.range.getSheet();
if (sh.getName() == 'Feuille1' && e.range.columnStart == 1) {
let rg = sh.getRange(e.range.rowStart, 2, 1, sh.getLastColumn() - 1);
if(e.value == "TRUE") {
rg.setFontLine('line-through')
} else {
rg.setFontLine('none')
}
}
}
Demo:
I have a google sheet with a column full of checkboxes. My goal is to have a row of the selected adjacent columns of data (namedInsured, lineCoverage, etc.) append to a separate sheet when a checkbox is selected and True. This is what I currently have, and it does absolutely nothing.
function onEdit(e) {
const ss = e.range.getSheet();
var active_range = ss.getActiveRange();
var namedInsured = ss.getRange(active_range.getRowIndex(), 4).getValue();
var lineCoverage = ss.getRange(active_range.getRowIndex(), 5).getValue();
var effDate = ss.getRange(active_range.getRowIndex(), 6).getValue();
var assignedTo = ss.getRange(active_range.getRowIndex(), 15).getValue();
var data = [namedInsured, lineCoverage, effDate, assignedTo];
const destinationSheet = ss.getSheetByName("Sheet4");
if (ss.getName() != "Sheet4" && e.range.columnStart == 10 && e.value == "TRUE")
{
e.source.toast("Quote In Process Entered")
destinationSheet.appendRow(data);
}
}
[This is an example of the desired output]
<< If the first and fourth checkboxes were selected one after the other, this is how they should appear on the separate sheet
This works for me
function onEdit(e) {
e.source.toast('Entry')
const sh = e.range.getSheet();
if (sh.getName() == "Sheet0" && e.range.columnStart == 10 && e.value == "TRUE") {
e.source.toast('Flag1');
const [a,b,c] = sh.getRange(e.range.rowStart, 4,1,3).getValues()[0];
var d = sh.getRange(e.range.rowStart, 15).getValue();
var data = [a, b, c, d];
const dsh = e.source.getSheetByName("Sheet1");//modified from original
dsh.appendRow(data);
}
}
Demo:
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"));
}
}