Date Stamp for Cell update - google-apps-script

Using a Google App Script to show when a Stock Take cell has been entered or updated.
using the following simple script:
function onEdit(ss) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("StockTake"); // StockTake is the sheet where data is entered
var activeCell = sheet.getActiveCell();
var col = activeCell.getColumn(); // numeric value of column, ColA = 1
var row = activeCell.getRow(); // numeric value of row
if (col == 2 || col == 3 || col == 4 || col == 5 || col == 6 || col == 7) {
sheet.getRange(row, col+6).setValue(new Date()).setNumberFormat('DDD, MMM dd');
}
}
Problem is that sometimes the Column Header will also Date Stamp. I would like to know how to go about keeping the first row from getting a date stamp.
Thank you!

To avoid stamping the header row, you want to make sure that row > 1. So, add that to the if-statement.
While doing that, also simplify the condition for column: it's 2 <= col <= 7, which is expressed as
if (row > 1 && col >= 2 && col <= 7) {
sheet.getRange(row, col+6).setValue(new Date()).setNumberFormat('DDD, MMM dd');
}

Related

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

scrips to subtract value in one cell from another cell

My current script adds a timestamp, i now want to add the function to subtract the value in cell 13 from that in cell 14 and put in into cell 12 at the same time it adds the date stamp
function onEdit(e) {
var row = e.range.getRow();
var col = e.range.getColumn();
var value = e.range.getValue();
var sheet = e.source.getActiveSheet().getName();
var destination = e.source.getActiveSheet().getRange(row,11);
var destination2 = e.source.getActiveSheet().getRange(row,10);
var num1 = e.source.getActiveSheet().getRange(row,13).getValue;
var num2 = e.source.getActiveSheet().getRange(row,14).getValue;
if(col === 4 && row > 4 && sheet ==="Bayswater" && value === "Completed" && destination2.getValue() ==="" && destination.getValue() ===""){
e.source.getActiveSheet().getRange(row,11).setValue(new Date(new Date().setHours(0,0,0,0))).setNumberFormat('dd-MMM-yy');
e.source.getActiveSheet().getRange(row,10).setValue(new Date(new Date().setHours(0,0,0,0))).setNumberFormat('dd-MMM-yy');
e.source.getActiveSheet().getRange(row,12).setValue('=num1-num2')
}
Probably the last line should be like this:
e.source.getActiveSheet().getRange(row,12).setFormula('=(N' + row + '-M' + row + ')');
Or it was just a typo. You forgot to add () after getValue in the two lines:
var num1 = e.source.getActiveSheet().getRange(row,13).getValue(); // <-- here
var num2 = e.source.getActiveSheet().getRange(row,14).getValue(); // <-- here
If you add () you can use the last line this way:
e.source.getActiveSheet().getRange(row,12).setValue(num1-num2);

Automatic timestamp when a cell is modified, but that clears when the cell is empty

I have this code and i am trying to add some code at the bottom saying that if the column is empty, the date column will clear.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSheet();
var r = ss.getActiveCell();
//1.Change 'Ark 1' to be matching your sheet name
if (r.getColumn() == 4 && ss.getName()=='Ark 1') { // 2. If Edit is done in column 4 (D) And sheet name is Ark 1 then:
var celladdress ='L'+ r.getRowIndex()
ss.getRange(celladdress).setValue(new Date()).setNumberFormat("dd/MM/yyyy hh:mm");}
};
L is the column i have my date timestamp in, while column 4 (D) is the column the modification is done.
You don't explain in your question either you mean the whole column being empty, or the active cell.
In any case:
To verify that the cell is not empty or contains only a space you have to query for if(r.getValue() !="" && r.getValue() !=" ")
Depending on the outcome - either you set a timestmap in the active row of column L or you clear the content of the respective cell in column L with ss.getRange(celladdress).clear();
Below is a sample:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSheet();
var r = ss.getActiveCell();
//1.Change 'Ark 1' to be matching your sheet name
if (r.getColumn() == 4 && ss.getName()=='Ark 1') { // 2. If Edit is done in column 4 (D) And sheet name is Ark 1 then:
var celladdress ='L'+ r.getRowIndex();
if(r.getValue() !="" && r.getValue() !=" "){
ss.getRange(celladdress).setValue(new Date()).setNumberFormat("dd/MM/yyyy hh:mm");
} else{
ss.getRange(celladdress).clear();
}
}
}

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.

How to Automatically Change a Cell in Google Sheets Based on Multiple Variables

I am working on creating a schedule in Google Sheets and I have just one last task that I cannot figure out. Here is an example of what I would like to accomplish.
For lines 8-12 (which is for Employees 1-5) I need to have a script that looks for every cell that contains either A or A-10. If these A or A-10 shifts fall on the 1-15 (days of the month are in row 5...pictured below) they should be changed to Aa or Aa-10. If they fall on the 16th-end of the month they should be Ap or Ap-10. The same will be the case with the R and I shifts.
Here is a screen shot of the Google Sheet from the example I gave above:
Any help would be greatly appreciated! Thanks!
Here is a script that will do those changes. It only changes rows 8 - 12 and assumes the dates are in row 5.
function changeValues() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("8:12");
var dates = sheet.getRange("5:5").getValues();
var values = range.getValues();
for(var row = 0; row < values.length; row++) {
for(var column = 1; column < values[row].length; column++) {
var day = Number(dates[0][column].replace(/[^0-9]/g, ""));
var value = values[row][column];
if(day >= 1 && day <= 15) {
if(value === "A") value = "Aa";
else if(value === "A-10") value = "Aa-10";
} else if(day > 15) {
if(value === "A") value = "Ap";
else if(value === "A-10") value = "Ap-10";
}
values[row][column] = value;
}
}
range.setValues(values);
}