Pulling array, based on the onEdit range - google-apps-script

I have the following script. Its full purpose is to remove cells of columns B,C,D,E,F if the content in column A was deleted, only on the matching row. It functions as it should. However, it is a bit slow.
I couldn't figure out a way to do it myself. Which is why I am here. How could I go about adjusting it, so instead of removing the cells individually, I could instead grab a full range of them, in the matching row? Perhaps based on the offset of the initially adjusted cell.
function onEdit(e) {
if(e.range.columnStart === 1
&& e.range.rowStart > 1
&& e.range.getSheet().getName() == 'Sheet1'
&& e.range.getValue() == '') {
e.range.offset(0,1).deleteCells(SpreadsheetApp.Dimension.ROWS);
e.range.offset(0,2).deleteCells(SpreadsheetApp.Dimension.ROWS);
e.range.offset(0,3).deleteCells(SpreadsheetApp.Dimension.ROWS);
e.range.offset(0,4).deleteCells(SpreadsheetApp.Dimension.ROWS);
e.range.offset(0,5).deleteCells(SpreadsheetApp.Dimension.ROWS)
}
}

To implement a couple of additional checks for copy-paste and the like, and to observe onEdit(e) best practices, try this:
/**
* Simple trigger that runs each time the user hand edits the spreadsheet.
*
* #param {Object} e The onEdit() event object.
*/
function onEdit(e) {
if (e.range.columnStart !== 1
|| e.range.rowStart <= 1
|| e.range.getSheet().getName() !== 'Sheet1'
|| (e.value || e.range.getValue())
|| e.range.getHeight() + e.range.getWidth() > 2) {
return;
}
e.range.offset(0, 1, 1, 5).clearContent();
}

Try:
function onEdit(e) {
if(e.range.columnStart === 1
&& e.range.rowStart > 1
&& e.range.getSheet().getName() == 'Sheet1'
&& e.range.getValue() == '') {
deletecols()
}
}
function deletecols(){
var sh = SpreadsheetApp.getActive().getActiveSheet()
var range = sh.getActiveRange()
var numrows = range.getNumRows()
var row = range.getRow()
sh.getRange(row,2,numrows,5).clearContent()
}

My not be that much faster:
function onEdit(e) {
const sh = e.range.getSheet();
if(e.range.columnStart == 1 && e.range.rowStart > 1 && sh.getName() == 'Sheet1' && e.value == '') {
sh.getRange(e.range.rowStart,2,1,5).setValues([['','','','','']]);
}
}

Related

Deleting cell conditionally with apps script

I'm having trouble with what seems like a very simple problem. Yet, I don't know how to fix it.
I am trying to clear cell A2 if and only if A1 is empty. I'm sure there is an easy solution but I don't seem to notice it. I'll share a sample spreadsheet for all of you to visualize my objective.
https://docs.google.com/spreadsheets/d/1qiq0w4xcUDO8pkFyeMO2ma_KR48evSsVAP6o50O0RtI/edit#gid=0
This is what I tried.
function onEdit(e) {
var sheet = SpreadsheetApp.getActive().getSheetByName("TEST");
var range = e.source.getActiveRange();
if(e.range.getRow() == 1 && e.range.getColumn() == 1) {
if(sheet.getRange("A1").getValue() == "") {
sheet.getRange('A2').clearContent();
}
}
}
Is there any problem with what I'm doing?
Help would be awesome.
The below works for me. I think you might be getting the selected range which may be different? Also you might not want to run this on other sheets? If performance becomes an issue, it might make sense to reduce the && statements and use more if statements.
function onEdit(e) {
const range = e.range;
const zzSheetName = "TEST";
const ss = range.getSheet();
if(ss.getName() == zzSheetName
&& ss.getRange("A1").isBlank()
&& range.getRow()==1
&& range.getColumn()==1
&& (!ss.getRange("A2").isBlank())
){
ss.getRange('A2').clearContent();
}
}
Clear A2 if A1 is empty
function onEdit(e) {
var sh = e.range.getSheet();
if (sh.getName() == "TEST" && e.range.columnStart == 1 && e.range.rowStart == 1 && e.value === '') {
e.range.offset(0, 1).clearContent();
}
}

Can I force onEvent to interact with data provided by filter function?

Please refer to the below code, written by the user #doubleunary
The purpose of the code is to remove the content of the rows in which the matching column had its contents removed manually by the user. However, I realized that in this instance. I want to remove the content from Sheet 2, which uses a filter to populate data from sheet 1. The script does not recognize changes done in sheet 1, as modifications to data in sheet 2, and does not function. Is there any way to adjust that?
function onEdit(e) {
if (e.range.columnStart !== 1
|| e.range.rowStart <= 1
|| e.range.getSheet().getName() !== 'Sheet2'
|| (e.value || e.range.getValue())
|| e.range.getHeight() + e.range.getWidth() > 2) {
return;
}
e.range.offset(0, 1, 1, 5).clearContent();
}
Respond to changes in multiple sheets
function onEdit(e) {
const sh = e.range.getSheet();
const shts = ["Sheet1", "Sheet2"];
const idx = shts.indexOf(sh.getName());
if (~idx && e.range.columnStart == 1 && e.range.rowEnd - e.range.rowStart + 1 + e.range.columnEnd - e.range.columnStart + 1 < 2 && e.value === '' && e.oldValue) {
e.range.offset(0, 1, 1, 5).clearContent();
}
}

Google Sheets - OnEdit - Separate Range

I am using the following code to automatically turn inputs in columns 1 and 4 of a sheet into a hyperlink. Whenever any range beyond 1 cell is pasted into the sheet only the first value will be hyperlinked into all cells in the range. Is there a way to get the cells within the range so I can have it check each cell for their individual value and column?
Thanks for any help!
function onEdit(e) {
// Set a comment on the edited cell to indicate when it was changed.
let range = e.range;
let order = range.getValue()
if (!( order === ''))
{
if (range.getColumn() == 1 || range.getColumn() == 4) {range.setValue("=hyperlink(\""+order+"\", \""+order+"\")");}
}
}
If you wish to tie it down to a single sheet
function onEdit(e) {
//e.source.toast('Entry')
//Logger.log(JSON.stringify(e));
const sh = e.range.getSheet();
if (sh.getName() == "Sheet1" && e.range.rowStart > 1 && (e.range.columnStart == 1 || e.range.columnStart == 4) && e.value) {
//e.source.toast("flag1");
e.range.setValue(`=hyperlink("${e.value}","${e.value}")`);
}
}

AutoTimeStamp based on multiple cells

I have a document that when any cell from column B through G has data entered into it (starting from row 4) I want Row A to have a TimeStamp of when that data was started and to not change. But if the row is cleared I want the timestamp to be deleted and be able to be reentered with new data. And I'm using this across multiple sheets. I did the IFS function and it worked, but people were overwriting and deleting it so I am trying to script it. I've tried modifying a few scripts I've found online and using some of the stuff I remember from college days, but it hasn't been great and I could use some help. Thanks!
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSheet();
var range = ss.getRangeList(['B4:B', 'C4:C','D4:D','E4:E', 'F4:F', 'G4:G']);
if ( e.range) return;
e.targetColumn = 1
.setValue (new Date("HH:mm"));
}
function onEdit(e) {
if ( e.range.columnStart !== 2 && e.range.columnStart !== 3
&& e.range.columnStart !== 4 && e.range.columnStart !== 5
&& e.range.columnStart !== 6 && e.range.columnStart !== 7) return;
e.range.targetColumn = 1
.setValue(new Date());
}
(Updated) Try this:
function onEdit(e) {
e.source.toast('Entry');
const sh = e.range.getSheet();
if (sh.getName() == "Your sheet name" && e.range.columnStart > 1 && e.range.columnStart < 8 && e.range.rowStart > 3) {
e.source.toast('Flag1');
if(sh.getRange(e.range.rowStart,2,1,sh.getLastColumn() -1).isBlank() ) {
sh.getRange(e.range.rowStart(),1).clearContent();
} else {
if(sh.getRange(e.range.rowStart,1).isBlank()) {
sh.getRange(e.range.rowStart,1).setValue(new Date());
}
}
}
}

OnEdit Google Scripts in same sheet - Separately they work, together not so well

I have these scripts working separately but when I combine them or create two different scripts only one will function.
What am I missing?
function onEdit(e) {
var sheet = e.source.getActiveSheet(),
editCols = [20, 21, 22, 23, 24, 25, 26, 27]
if (sheet.getName() !== 'THANG11' || editCols.indexOf(e.range.columnStart) ==
-1 || e.range.rowStart < 3 || e.range.rowStart > 6)
if (sheet.getName() !== 'THANG12' || editCols.indexOf(e.range.columnStart) ==
-1 || e.range.rowStart < 3 || e.range.rowStart > 6)
return;
sheet.getRange("I1").setValue(new Date());
}
There are two possibilities to merge your if statements.
First possibility
function onEdit(e) {
...
if (sheet.getName() != 'THANG11' || ...){
return;
}
if (sheet.getName() != 'THANG12' || ...){
return;
}
sheet.getRange("I1").setValue(new Date());
...
}
In this case you implement two separate if statements and specify within curly brackets the block of code to execute if the respective condition is fulfilled.
In your case, the code to execute is identical for both coditions (return), thus you can implement both conditions within one if statement:
Second possibility
function onEdit(e) {
...
if (sheet.getName() != 'THANG11' || sheet.getName() != 'THANG12' ||...){
return;
}
sheet.getRange("I1").setValue(new Date());
...
}