I am using the below code to hide and unhide rows which I got from the below question posted in Stakeoverflow community.
Hide Blank Rows In Google Sheets Based On Selection
The code runs when I change the selection in "NamedRange1" i.e. Cell No. A1 of Sheet3. If I select A in this section then blank rows in Sheet2 will get hide and if I select B then the rows will get unhide.
The code runs fine and hides unhides the rows but I am getting issue in below case:
I selected A in NamedRange1 so blank rows in Sheet2 will get hide, then I manually hide one row (Say row No.7) in Sheet2 which is having data and now if I select B in NamedRange1 then the script will unhide hidden rows except Row No. 7. I want to update the script so it can unhide all the hidden rows.
For reference am sharing the link of the sheet which is having the sample data as well as the code.
https://docs.google.com/spreadsheets/d/1s0El5dqirom3UMX2tGihYbdZM8ldWku9F_xqQXi31Ws/edit#gid=1228899550
function onEdit(e) {
const sh = e.range.getSheet();
const rg = e.source.getRangeByName("NamedRange1");
const sr = rg.getRow();
const sc = rg.getColumn();
const er = sr + rg.getHeight() - 1;
const ec = sc + rg.getWidth() - 1;
if (sh.getName() == "Sheet3" && e.range.columnStart >= sc &&
e.range.columnStart <= ec && e.range.rowStart >= sr &&
e.range.rowStart <= er && e.value) {
//e.source.toast("Flag1")
const sh2 = e.source.getSheetByName("Sheet2");
const vs = sh2.getDataRange().getValues();
vs.forEach((r, i) => {
if (r.every(e => e == '')) {
if (e.value == "A") {
sh2.hideRows(i + 1);
} else {
sh2.showRows(i + 1)
}
}
});
}
}
Any help on above will be appreciated.
Related
I am on basics of appscript and learning it progressively with the help of this community. Any help on below will be appreciated.
I am trying to design a script which hides and unhides rows on change of selection and for that I got a solution from question posted at below link.
Google Sheet Hide/Unhide Rows Using Appscrit Unhide
Below is the code given in above link
function onEdit(e) {
const sh = e.range.getSheet();
const rg = e.source.getRangeByName("NamedRange1");
const sr = rg.getRow();
const sc = rg.getColumn();
const er = sr + rg.getHeight() - 1;
const ec = sc + rg.getWidth() - 1;
if (sh.getName() == "Sheet3" && e.range.columnStart >= sc && e.range.columnStart <= ec
&& e.range.rowStart >= sr && e.range.rowStart <= er && e.value) {
//e.source.toast("Flag1")
const sh2 = e.source.getSheetByName("Sheet2");
const vs = sh2.getDataRange().getValues();
vs.forEach((r, i) => {
if (r.every(e => e == '')) {
if (e.value == "A") {
sh2.hideRows(i + 1);
} else {
sh2.showRows(i + 1)
}
}
});
}
}
The code is given proper result but I want a bit modification in the same. The unhide command of the code unhides all the rows of the sheet, however I want the code to unhide all the rows except first row of the sheet.
Any help on above will really be appreciated.
From The unhide command of the code unhides all the rows of the sheet, however I want the code to unhide all the rows except first row of the sheet., how about the following modification?
From:
vs.forEach((r, i) => {
if (r.every(e => e == '')) {
if (e.value == "A") {
sh2.hideRows(i + 1);
} else {
sh2.showRows(i + 1)
}
}
});
To:
vs.forEach((r, i) => {
if (r.every(f => f == '')) {
if (e.value == "A") {
sh2.hideRows(i + 1);
} else if (i > 1) {
sh2.showRows(i + 1);
}
}
});
When this is reflected in your script, sh2.showRows(i + 1) is run when e.value != "A" and i > 1. By this, the 1st row is skipped.
And also, in the case of r.every(e => e == ''), e has already been used with the event object. So, I changed it to f.
I am trying to hide blank rows in Google Sheet based on edit i.e. change of selection in 'Sheet3!NamedRange1'. I had taken support of these two questions posted in Stakeoverflow community for the same (Hide and Unhide Specific Blank Rows With the Same Button) and (Hide Blank Rows In Google Sheets Based On Selection).
I am using below code to get the desired result. The code hides blank rows but only upto the last row having data i.e. if last row with data is Row No. 80 then after row no. 80 the script will not hide the rows even if the rows are blank. I want to hide all the blank rows.
In addition to above I want to keep specific blank rows unhide based on the row no.
E.g. Donot hide Row No. 12, 15 and 18 even if they are blank.
function onEdit(e) {
const sh = e.range.getSheet();
const rg = e.source.getRangeByName("NamedRange1");
const sr = rg.getRow();
const sc = rg.getColumn();
const er = sr + rg.getHeight() - 1;
const ec = sc + rg.getWidth() - 1;
if (sh.getName() == "Sheet3" && e.range.columnStart >= sc && e.range.columnStart <=
ec && e.range.rowStart >= sr && e.range.rowStart <= er && e.value) {
const sh2 = e.source.getSheetByName("Sheet2");
const vs = sh2.getDataRange().getValues();
vs.forEach((r, i) => {
if (r.every(e => e == '')) {
if (e.value == "A") {
sh2.hideRows(i + 1);
} else {
sh2.showRows(i + 1)
}
}
});
}
}
Any help on above will be appreciated.
I believe your goal is as follows.
You want to hide all empty rows in "Sheet2" when the value of cell "A1" of "Sheet3" is A.
In this case, you want to exclude the specific rows from the hidden rows.
In this case, how about the following modification?
Modified script:
Before you use this script, please show all rows, and test the script. Please set the excluded rows to excludeRows. In this sample, rows 12, 15, and 18 are excluded from the hidden rows.
function onEdit(e) {
const excludeRows = [12, 15, 18]; // Please set excluded row numbers.
// Ref: https://gist.github.com/tanaikech/5a43281964b739ead2b7ae2401400630
const compilingNumbers = ar => {
const { values } = [...new Set(ar.sort((a, b) => a - b))].reduce((o, e, i, a) => {
if (o.temp.length == 0 || (o.temp.length > 0 && e == o.temp[o.temp.length - 1] + 1)) {
o.temp.push(e);
} else {
if (o.temp.length > 0) {
o.values.push({ start: o.temp[0], end: o.temp[o.temp.length - 1] });
}
o.temp = [e];
}
if (i == a.length - 1) {
o.values.push(o.temp.length > 1 ? { start: o.temp[0], end: o.temp[o.temp.length - 1] } : { start: e, end: e });
}
return o;
}, { temp: [], values: [] });
return values;
};
const sh = e.range.getSheet();
const rg = e.source.getRangeByName("NamedRange1");
const sr = rg.getRow();
const sc = rg.getColumn();
const er = sr + rg.getHeight() - 1;
const ec = sc + rg.getWidth() - 1;
if (sh.getName() == "Sheet3" && e.range.columnStart >= sc && e.range.columnStart <=
ec && e.range.rowStart >= sr && e.range.rowStart <= er && e.value) {
const sh2 = e.source.getSheetByName("Sheet2");
const vs = sh2.getRange(1, 1, sh2.getMaxRows(), sh2.getMaxColumns()).getDisplayValues();
const rows = vs.reduce((ar, r, i) => {
if (!excludeRows.includes(i + 1) && r.join("") == "") ar.push(i + 1);
return ar;
}, []);
const method = e.value == "A" ? "hideRows" : "showRows";
compilingNumbers(rows).forEach(({ start, end }) => sh2[method](start, end - start + 1));
}
}
In this script, when the value of cell "A1" of "Sheet3" is A, the empty rows in "Sheet2" are hidden by excluding the specific rows.
I have designed below script from solution given in one of the question posted from the Stakeoverflow community (Show and hide rows and columns based on different dropdowns).
In the solution given in the above link, specific rows/columns are being hide by using the script, I want to hide all the blank rows in place of specific rows.
Script which I am using
function onEdit(e) {
const n1=e.source.getRangeByName('Sheet3!NamedRange1').getValue();
const sh2=e.source.getSheetByName("Sheet2");
if (n1=="A"){sh2.showRows(15,10);}else{sh2.hideRows(15,10);}
}
Any help on above will be greatly appreciated.
Hide and Show Row based on value in NamedRang1
function onEdit(e) {
//e.source.toast("Entry")
const sh = e.range.getSheet();
const rg = e.source.getRangeByName("NamedRange1");
const sr = rg.getRow();
const sc = rg.getColumn();
const er = sr + rg.getHeight() - 1;
const ec = sc + rg.getWidth() - 1;
if (sh.getName() == "Sheet3" && e.range.columnStart >= sc && e.range.columnStart <= ec && e.range.rowStart >= sr && e.range.rowStart <= er && e.value) {
//e.source.toast("Flag1")
const sh2 = e.source.getSheetByName("Sheet2");
const vs = sh2.getDataRange().getValues();
vs.forEach((r, i) => {
if (r.every(e => e == '')) {
if (e.value == "A") {
sh2.hideRows(i + 1);
} else {
sh2.showRows(i + 1)
}
}
});
}
}
Good afternoon;
I am working on a google sheet with 2 columns "New Data" and "Completed". I have the New Data set with a check box that moves the row to the completed sheet once it is checked. Once on the completed sheet I would like to fill in a date and time stamp under comlumn E to show when it was moved to completed. What I have so far is listed below. Currently when it moves over from new data nothing happens. I also have a trigger set on addCompleteDate to work onEdit. Any help is appreciated.
function onEdit(e) {
const src = e.source.getActiveSheet();
const r = e.range;
if(src.getName() != "New Data" || r.columnStart != 6 || r.rowStart == 1) return;
const dest = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Completed");
src.getRange(r.rowStart, 1, 1 ,4).moveTo(dest.getRange(dest.getLastRow()+1,1,1,4));
src.deleteRow(r.rowStart);
}
function addCompleteDate(e){
const row = e.source.range.getRow();
const col = e.source.getSheetByName("Completed").columns[2];
if(col && col != "" && row > 1 ){
const currentDate = new Date();
e.source.getActiveSheet().getRange(row, 5).setValue(currentDate);
}
}
Just combine them together
function onEdit(e) {
const sh = e.range.getSheet();
if (sh.getName() == "New Data" && e.range.columnStart == 6 || e.range.rowStart > 1) {
const dsh = e.source.getSheetByName("Completed");
const dnr = dsh.getLastRow() + 1;
sh.getRange(e.range.rowStart, 1, 1, 4).moveTo(dsh.getRange(dnr, 1, 1, 4));
sh.deleteRow(e.range.rowStart);
dsh.getRange(dnr,5).setValue(new Date());
}
}
I have a Google spreadsheet which has checkboxes in column P, as and when a checkbox is ticked the corresponding row automatically hides.
I am looking to add an additional check box in G1 that will show all hidden rows if checked and if possible a checkbox in E1 to then hide again all the rows that have the checkbox ticked in column P.
Basically I want to automatically hide rows when I tick the checkbox in column P
Then later I may need to review the hidden rows by clicking the checkbox in G1.
When I am finished reviewing the hidden rows above click a checkbox in E1 and all rows which are checked in column P will hide again.
function onEdit(e){
if (e.range.columnStart != 16 || e.value != "TRUE") return;
SpreadsheetApp.getActiveSheet().hideRows(e.range.rowStart);
}
Solution:
Check if edited cell is G1 via getA1Notation(). In that case, check if value is TRUE, and if that's the case, show all rows. An easy option to show all rows is using unhideRow(row), setting A:A as your range (since this includes all rows in the sheet).
Check if edited cell is E1. If the value is TRUE, retrieve all values from P column via getValues(), iterate through them, and hide the corresponding rows if the value is true, using hideRows(rowIndex).
Check if the edited cell is in column P, and use hideRows on the edited row if that's the case, as you're already doing.
Code snippet:
function onEdit(e){
const sheet = SpreadsheetApp.getActiveSheet();
const range = e.range;
const editedValue = e.value;
if (range.getA1Notation() === "G1" && editedValue === "TRUE") {
sheet.unhideRow(sheet.getRange("A:A"));
} else if (range.getA1Notation() === "E1" && editedValue === "TRUE") {
const firstRow = 2;
const lastRow = sheet.getLastRow();
const pValues = sheet.getRange("P" + firstRow + ":P" + lastRow).getValues().flat();
pValues.forEach((pValue,i) => {
if (pValue === true) {
sheet.hideRows(i + firstRow);
}
});
} else if (e.range.columnStart === 16 && editedValue === "TRUE") {
sheet.hideRows(range.rowStart);
}
}
I know it is a bit of an old thread, but still very helpfull to al lot of people i guess. Both the code from the TS and the answer were very helpfull.
I used this for a similar project and found it a bit strange to have two checkboxes to show/hide rows though, so i made this work with one checkbox in cell "G1" to toggle the view hide/unhide.
Code Snippet
function onEdit(e){
const sheet = SpreadsheetApp.getActiveSheet();
const range = e.range;
const editedValue = e.value;
if (range.getA1Notation() === "G1" && editedValue === "TRUE") {
sheet.unhideRow(sheet.getRange("A:A"));
} else if (range.getA1Notation() === "G1" && editedValue === "FALSE") {
const firstRow = 2;
const lastRow = sheet.getLastRow();
const pValues = sheet.getRange("P" + firstRow + ":P" + lastRow).getValues().flat();
pValues.forEach((pValue,i) => {
if (pValue === true) {
sheet.hideRows(i + firstRow);
}
});
} else if (e.range.columnStart === 16 && editedValue === "TRUE") {
sheet.hideRows(range.rowStart);
}
}