TImestamp Apps First DateEntered freeze - google-apps-script

Hi I want to show Onlt The first date entered, so whenever someone change it
the timestamp WONT change
what can i use for it? like filter?
my code is like this
if C&E&F is filled
then timestamp
the timestamp should be freezed once someone input it, when someone change it the timestamp WONT CHANGET
function onEdit(e) {
const editedRange = e.range
const sheet = editedRange.getSheet()
var row = editedRange.getRow();
if (
sheet.getName() === 'Data' && ///cari sheet yang dipakai
(editedRange.getColumn() == 4 || editedRange.getColumn() == 5 || editedRange.getColumn() == 6) && ///jika keisi
(sheet.getRange(row, 4).getValue() !== "" && sheet.getRange(row, 5).getValue() !== "" && sheet.getRange(row, 6).getValue() !=="") ///jika tidak diisi
)
{
const timestampRange = sheet.getRange(editedRange.getRow(), 1, editedRange.getNumRows(), 1)
timestampRange.setValue(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "d/MM/yyyy HH:mm:ss")); /// memunculkan timestamp pada colum ke1/A yg dituju
}
}

This version requires that all three of d,e and f must be filled in order to get a time stamp and once you get a timestamp then it does not change unless the user changes it manually
function onEdit(e) {
//e.source.toast("Entry1");
const sh = e.range.getSheet()
if (sh.getName() == 'Sheet0' && e.range.columnStart > 3 && e.range.columnStart < 7 && e.value) {
let x = sh.getRange(e.range.rowStart,4,1,3).getValues()[0].every(e => e );//This requires d,e and f to be filled or truthy
//e.source.toast("outer gate " + x);
if (sh.getRange(e.range.rowStart, 1).getValue() == '' && x) {
//e.source.toast("inner gate")
sh.getRange(e.range.rowStart, 1).setValue(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "d/MM/yyy HH:mm:ss"))
}
}//if column is null the set the timestamp otherwise do nothing
}
Demo:

Related

Date Stamp in multiple Columns Google Sheets

I have started using this script to auto populate the date when data is entered into the column next to it for Google Sheets. It needs to do this on multiple columns as new data is entered. This script works on all of the columns but the last paired: 13-14 and 15-16. It was working before but now it has stopped. Any help with what I need to do? I'm not versed in code and I learned this much from YouTube! Thanks!
function onEdit(e) {
var row = e.range.getRow();
var col = e.range.getColumn();
if(col == 5 && row > 1 && e.source.getActiveSheet().getName() === "IRLA Level" ) {
e.source.getActiveSheet().getRange(row,6).setValue(new Date())
if(col == 7 && row > 1 && e.source.getActiveSheet().getName() === "IRLA Level" )
e.source.getActiveSheet().getRange(row,8).setValue(new Date())
if(col == 9 && row > 1 && e.source.getActiveSheet().getName() === "IRLA Level" )
e.source.getActiveSheet().getRange(row,10).setValue(new Date())
if(col == 11 && row > 1 && e.source.getActiveSheet().getName() === "IRLA Level" )
e.source.getActiveSheet().getRange(row,12).setValue(new Date())
if(col == 13 && row > 1 && e.source.getActiveSheet().getName() === "IRLA Level" )
e.source.getActiveSheet().getRange(row,14).setValue(new Date())
if(col == 15 && row > 1 && e.source.getActiveSheet().getName() === "IRLA Level" )
e.source.getActiveSheet().getRange(row,16).setValue(new Date())
}
}
Try it this way
function onEdit(e) {
const sh = e.range.getSheet();
const idx = [5,7,9,11,13,15].indexOf(e.range.columnStart);
if(sh.getName() == "IRLA Level" && e.range.rowStart > 1 && ~idx) {
e.range.offset(0,1).setValue(new Date());
}
}
Bitwise Not

Apps Script IF columns are filled THEN timestamp, IF columns are Empty then CLEAR

I have column A which is supposed to hold time. If any data is entered in columns B through G then a timestamp should be entered into Column A and then remain static. If ALL of the data in those columns (Column B through G is empty) then the timestamp in A (if it was there) should clear.
Currently the script I have is working except for clearing the row in column A. I know I'm probably missing something silly, but I can't get it right!
function checkinTimeStamp(e){
var s = SpreadsheetApp.getActive();
var range = e.range;
var column = range.getColumn();
if (column == 2 || column == 3 || column == 4 || column == 5 || column == 6 || column == 7){
var timestamp = Utilities.formatDate(new Date, s.getSpreadsheetTimeZone(), "hh:mm");
var row = range.getRow();
var value = e.value || '';
var sheet = e.source.getActiveSheet();
if(sheet.getRange(row,1).getValue() ==""){
if(value !== ""){
sheet.getRange(row, 1).setValue(timestamp);
}
//if(sheet.getRange(row,1).getValue() !==""){
// sheet.getRange(row, 1).setValue(currentvalue);
}
// else{
if(sheet.getRange(column == 2 && column == 3 && column == 4 && column == 5 && column == 6 && column == 7).getValue() ==""){
sheet.getRange(row, 1).setValue('');
}
}
}
In your script, for example, as a simple modification, how about following modification?
From:
if(sheet.getRange(column == 2 && column == 3 && column == 4 && column == 5 && column == 6 && column == 7).getValue() ==""){
sheet.getRange(row, 1).setValue('');
}
To:
if (sheet.getRange(row, 2, 1, 6).getValues()[0].join("") == "") {
sheet.getRange(row, 1).setValue('');
}
In this modification, the row value is retrieved and compare it with "". By this, when the columns "B:G" of the row are empty, sheet.getRange(row, 1).setValue('') is run.
Hey I tried a different approach using the forEach loop to go through each row to first look at if ColB is empty (clear timestamp if empty) then print a timestamp if there is items filled in ColB. I have shared the image of the before and after running code.
function checkinTimeStamp(){
var s = SpreadsheetApp.getActiveSpreadsheet();
var sheet=s.getSheetByName('Sheet1');
var data=sheet.getDataRange().getValues();
var timezone = s.getSpreadsheetTimeZone();
var timestamp = Utilities.formatDate(new Date(), timezone, "hh:mm");
// Go through each row and if ColB is empty but ColA isn't, clear the timestamp in ColA
data.forEach(function(row,col){
if (col == '') return; //skip row 1 as title
if (row[0] == '') return; //skip if ColA is empty
if (row[1] != '') return //skip if ColB is NOT empty
sheet.getRange(col + 1,1).clearContent();
});
// Go through each row and if ColB is not empty put a timestamp in ColA
data.forEach(function(row,col){
if (col == '') return; //skip row 1 as title
if (row[1]== '') return; //skip if ColB is empty
sheet.getRange(col + 1,1).setValue(timestamp);
});
}
Before Running Code
After Running Code
My sample sheet here: https://docs.google.com/spreadsheets/d/1IrEG_YNoUnesg78CDjlEwsVqssElZZ8znciqJC63D1Y/edit#gid=0

Generate automatic value and data when there are some value in a column in Google Sheets with GAS

In my spreadsheet I would generate automatically, when in col B there are these values:
yellow
green
black
brown
In col F the value "SI" and in col J the timestamp of the operation in col B.
https://docs.google.com/spreadsheets/d/1_oPC01vUjLYlCikyuk35bERa2Bughm_xDJSaim-wD58/edit#gid=0
Using onEdit to set value of column10 based on edit and value of B and value of F
function onEdit(e) {
//Logger.log(JSON.stringify(e));
//e.source.toast('Entry')
const sh = e.range.getSheet();
if(sh.getName() == "Sheet1" && e.range.columnStart == 2 ) {
//e.source.toast('Flag1')
const cA = ['yellow','green','black','brown'];
if(~cA.indexOf(e.value) && e.range.offset(0,4).getValue() == "SI") {
//e.source.toast('Flag2')
let ts = Utilities.formatDate(new Date(), Session.getScriptTimeZone(),"dd/MM/yyyy")
sh.getRange(e.range.rowStart,10).setValue(ts);
}
}
}

add timestamp when specific cell = "complete"

I have the following script that will add a timestamp to column 11 when column 4 in the same row and sheet is changed.
I now want to charge it so that it only charges when the text "Complete" is what is added to column 4
function onEdit(e) {
var row = e.range.getRow();
var col = e.range.getColumn();
if(col === 4 && row > 4 && e.source.getActiveSheet().getName() ==="Sheet1" ) {
e.source.getActiveSheet().getRange(row,11).setValue(new Date());
}
}
var value = e.range.getValue();
if(col === 4 && row > 4 && e.source.getActiveSheet().getName() ==="Sheet1" && value === "Complete") {.....

What i'm doing worng in this conditional?

Yesterday I asked a question about a script I was doing, since I could not detect the cell I was modifying, I leave in link to the question:
Stuck with Google spreadsheet script
Now I am trying to make the script conditional, but I can not distinguish between watchRange1 and watchRange2, these are two different cell ranges, which have a specific cell in which I want to write the time in which each range was modified.
Right now the conditional always writes me the modification time in the cell of the watchRange1 even if I modify the other range.
Can you tell me what i'm doing wrog?
This is the script that i'm mentioning:
function onEdit(e){
var curDate = Utilities.formatDate(new Date(), "GMT+01:00", "hh:mm");
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Test2');
var range = e.range;
//var colIndex = range.getColumn();
var colIndex = range.getColumnIndex(); //Same as getColumn()
var rowIndex = range.getRowIndex(); //Same as getRow()
var DateCol1 = "K9"; //Cell you want to have the date
var DateCol2 = "U9"; //Cell you want to have the date
var watchRange1 = {
top : 11, // start row
bottom : 109, // end row
left : 3, // start col
right : 11, // end col
};
var watchRange2 = {
top : 11, // start row
bottom : 109, // end row
left : 13, // start col
right : 21, // end col
};
if(colIndex >= watchRange1.left || colIndex <= watchRange1.right &&
rowIndex >= watchRange1.top || rowIndex <= watchRange1.bottom &&
e.getValue() != 0){
SpreadsheetApp.getActiveSheet().getRange(DateCol1).setValue(curDate);
//Write the date in the cell
}else if (colIndex >= watchRange2.left || colIndex <= watchRange2.right &&
rowIndex >= watchRange2.top || rowIndex <= watchRange2.bottom &&
e.getValue() != 0){
SpreadsheetApp.getActiveSheet().getRange(DateCol2).setValue(curDate);
//Write the date in the cell
}else{
SpreadsheetApp.getActiveSheet().getRange(DateCol1).setValue("Error");
};
}
You are using 'or' || instead of 'and' &&.
Col is greater than or equal to left OR less than or equal to right. Col will always be greater than left in the first range. This means the first if statement is always true (if you're editing in either of the ranges).
if(colIndex >= watchRange1.left || //should be &&
colIndex <= watchRange1.rigth && //right is misspelled
rowIndex >= watchRange1.top || //should be &&
rowIndex <= watchRange1.bottom &&
e.value != 0) //access key value instead of call function
Also, event objects e do not have associated functions. They have key:value pairs. e.value is how you access the value.