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());
}
}
}
}
Related
I'm sorry if the title is confusing.
Basically, I'm trying to make a log register
screenshot of the sheet
I want it so each time I write something on the empty "Log" column in row 3, the ID, Date and Hour are automatically filled and the entire row is moved downwards, leaving an empty one in row 3 again for me to fill when i want.
I don't know how it would be possible to make this as I don't really know to program or even use Google Sheets that well, so I'd appreciate any help!
This requires an onEdit trigger and cannot be run from script editor or a menu. Copy it into the Script editor and then editor the appropriate column to trigger the script.
function onEdit(e) {
e.source.toast("Entry");
const sh = e.range.getSheet();
if(sh.getName() == "Log" && e.range.columnStart == 4 && e.range.rowStart > 2) {
e.source.toast("Gate2");
e.range.offset(0,-3).setValue(e.range.offset(-1,-3).getValue() + 1);
e.range.offset(0, -2).setValue(new Date()).setNumberFormat("MM/dd/yyyy");
e.range.offset(0, -1).setValue(new Date()).setNumberFormat("HH:mm");
}
if(sh.getName() == "Log" && e.range.columnStart == 4 && e.range.rowStart == 2) {
e.source.toast('Gate1')
e.range.offset(0, -3).setValue(1);
e.range.offset(0, -2).setValue(new Date()).setNumberFormat("MM/dd/yyyy");
e.range.offset(0, -1).setValue(new Date()).setNumberFormat("HH:mm");
}
}
Demo:
Drop Down one row:
function onEdit(e) {
e.source.toast("Entry");
const sh = e.range.getSheet();
if(sh.getName() == "Log" && e.range.columnStart == 4 && e.range.rowStart == 2) {
e.source.toast('Gate1')
e.range.offset(0, -3).setValue(e.range.offset(1,-3).getValue() + 1);
e.range.offset(0, -2).setValue(new Date()).setNumberFormat("MM/dd/yyyy");
e.range.offset(0, -1).setValue(new Date()).setNumberFormat("HH:mm");
sh.insertRowBefore(2);
}
}
Demo:
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([['','','','','']]);
}
}
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();
}
}
I was trying to figure out how to make so there would be one check per column in one row. So far, I was still looking for an way to do this via Apps Script extension which I have been met with disappointment.
So, for example, if you have two rows but needs to have one checks per columns in the respective row? How would you do this?
One Checkbox per column in one row
function oneCheckPerColumn() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");//change sheet name to fit your needs
const rg = sh.getRange(1,1,1,10).insertCheckboxes();
}
Only one checked at a time
function onEdit(e) {
const sh = e.range.getSheet();
if(sh.getName() == 'Sheet0' && e.range.columnStart == 1 && e.range.rowStart > 1 && e.range.rowStart < 17 && e.value == "TRUE") {
sh.getRange("A2:A16").uncheck();
e.range.check();
}
}
Demo:
Rows and Columns
function onEdit(e) {
e.source.toast("Entry");
const sh = e.range.getSheet();
if(sh.getName() == 'Sheet0' && e.range.columnStart == 1 && e.range.rowStart > 1 && e.range.rowStart < 17 && e.value == "TRUE") {
sh.getRange("A2:A16").uncheck();
e.range.check();
}
if(sh.getName() == 'Sheet0' && e.range.rowStart == 2 && e.range.columnStart > 1 && e.range.columnStart < 12 && e.value == "TRUE") {
e.source.toast('Flag2');
sh.getRange("B2:K2").uncheck();
e.range.check();
}
}
Demo:
In Google Sheets, range N16:N29 has content referenced as a query from another sheet. If I select any one of those cells N16:N29, I'd like to have its content displayed at cell N10. When the active cell is no longer one of N16:N29, N10 is blank.
I haven't seen any mention of this and am curious if it's possible.
function onSelectionChange(e) {
//e.source.toast('entry');
//Logger.log(JSON.stringify(e));
const sh = e.range.getSheet();
if(sh.getName() == 'Sheet1' && e.range.columnStart < 10 && e.range.rowStart < 17) {
sh.getRange("M1").setValue(e.range.getValue());
}
}
I imported data into Sheet1 A2:J16 and used the onSelectionChange() triggers to display data in M1 when you select a cell inside of the imported range.
You just have to edit the if statement to set e.range.columnStart > 15 && e.range.columnStart < 30 & e.range.rowStart == 14 and correct the sheet name and change M1 to N10
function onSelectionChange(e) {
//e.source.toast('entry');
//Logger.log(JSON.stringify(e));
const sh = e.range.getSheet();
if(sh.getName() == 'New Sheet Name' && e.range.columnStart > 15 && e.range.columnStart < 30 & e.range.rowStart == 14) {
sh.getRange("N10").setValue(e.range.getValue());
}
}
function onSelectionChange(e) {
//e.source.toast('entry');
//Logger.log(JSON.stringify(e));
const sh = e.range.getSheet();
if(sh.getName() == 'Form' && e.range.columnStart < 15 && e.range.columnStart > 13 && e.range.rowStart > 15 && e.range.rowStart < 30) {
sh.getRange("N10").setValue(e.range.getValue());
}
}
Cooper, thanks for your help! I'm new to Apps Script. I've been having trouble getting your code to work on my sheet. None of the selections I made would show at the target cell. After some experimenting, I changed columnStart from >15 <30 to <15 >13 and rowStart from ==14 to >15 <30. That worked.
The only thing I can't figure out is when I select a cell outside the script range (N16:N29), the target cell (N10) still holds the previous selection. I'd like for the target cell to go blank when that happens. Is that possible?