Script for Date Stamping on Multiple Sheets - date

I am very very very new to all this. I need help, I am trying to use script editor to get the date statically stamped in one column when something is entered in a different column. I figured how to do this for one tab but I need this to happen on multiple tabs in the same sheet and I'm struggling to get it to work. Is there one code that will work for this? This is the script I was using for one tab:
/**
* Creates a Date Stamp if a column is edited.
*/
//CORE VARIABLES
// The column you want to check if something is entered.
var COLUMNTOCHECK = 9;
// Where you want the date time stamp offset from the input location. [row, column]
var DATETIMELOCATION = [0,-8];
// Sheet you are working on
var SHEETNAME = 'Sheet 2'
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//checks that we're on the correct sheet.
if( sheet.getSheetName() == SHEETNAME ) {
var selectedCell = ss.getActiveCell();
//checks the column to ensure it is on the one we want to cause the date to appear.
if( selectedCell.getColumn() == COLUMNTOCHECK) {
var dateTimeCell = selectedCell.offset(DATETIMELOCATION[0],DATETIMELOCATION[1]);
dateTimeCell.setValue(new Date());
}
}
}
Thank you for your time in advance.

To proceed with the function on multiple sheets, you can check for the sheet name in an array of acceptable names.
function onEdit() {
var colToCheck = 9;
// Offset from the input [row, column]
var dateOffset = [0, -8];
// Sheets to proceed on
var sheetNames = ['Sheet 2', 'Sheet 3'];
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var name = sheet.getName();
if (sheetNames.indexOf(name) > -1) {
var cell = sheet.getActiveCell();
var col = cell.getColumn();
if (col == colToCheck) {
var dateTimeCell = cell.offset(dateOffset[0], dateOffset[1]);
dateTimeCell.setValue(new Date());
}
}
}
References
Arrays
indexOf()
EDIT ONE
If you want multiple options, you could set them up in arrays. The order of the elements in the arrays must match.
This code assumes that the timestamp is always on the same row.
function onEdit() {
var sheetNames = ['Sheet 2', 'Sheet 3'];
var colsToCheck = [9, 15];
var colOffsets = [-8, -4];
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var name = sheet.getSheetName();
var index = sheetNames.indexOf(name);
if (index > -1) {
var cell = sheet.getActiveCell();
var col = cell.getColumn();
if (col == colsToCheck[index]) {
var dateTimeCell = cell.offset(0, colOffsets[index]);
dateTimeCell.setValue(new Date());
}
}
}
EDIT TWO
For those of you who would prefer objects
function onEdit() {
var sheets = {
'Sheet 2': {
checkCol: 9,
offset: -8
},
'Sheet 3': {
checkCol: 15,
offset: -4
}
};
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var name = sheet.getSheetName();
var settings = sheets[name];
if (settings) {
var cell = sheet.getActiveCell();
var col = cell.getColumn();
if (col == settings.checkCol) {
var dateTimeCell = cell.offset(0, settings.offset);
dateTimeCell.setValue(new Date());
}
}
}

Related

Creating calendar syncronised to spreadsheet but all events are created onn 1 Jan 1970 at 03:00. What did I miss?

I am following the conversation and tutorial in post Create Google Calendar Events from Spreadsheet but prevent duplicates
But I cannot get the final solution to work. It fills my calendar but all dates are 1/1/1970 at 3 am.
The code is as follows:
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name: "Export Events",
functionName: "exportEvents"
}];
sheet.addMenu("Calendar Actions", entries);
};
function parseDate(s) {
var months = {
jan: 0, feb: 1, mar: 2, apr: 3, may: 4, jun: 5, jul: 6, aug: 7, sep: 8, oct: 9, nov: 10, dec: 11
};
var p = s.replace(".", "").split('-');
return new Date(p[2], p[1], p[0]);
}
/**
* Export events from spreadsheet to calendar
*/
function exportEvents() {
var sheet = SpreadsheetApp.getActiveSheet();
var headerRows = 1; // Number of rows of header info (to skip)
var range = sheet.getDataRange();
var data = range.getDisplayValues();
var calId = "the calendar"; // PRODUCTION
//var calId = "the calendar; // TEST
var cal = CalendarApp.getCalendarById(calId);
//Logger.log(cal);
//Logger.log(data.length);
for (i = 0; i<data.length; i++) {
if (i<headerRows) continue; // Skip header row(s)
if (data[i][0].length<1) continue; // Skip if no content.
var row = data[i];
Logger.log(row);
var date = parseDate(row[0]); // First column
//Logger.log(date);
var title = row[1]; // Second column
var tstart = new Date();
var s = row[2].split(":");
tstart.setHours(s[0]);
tstart.setMinutes(s[1]);
tstart.setSeconds(s[2]);
tstart.setDate(date.getDate());
tstart.setMonth(date.getMonth());
tstart.setYear(date.getYear());
var tstop = new Date();
var e = row[3].split(":");
tstop.setHours(e[0]);
tstop.setMinutes(e[1]);
tstop.setSeconds(e[2]);
tstop.setDate(date.getDate());
tstop.setMonth(date.getMonth());
tstop.setYear(date.getYear());
var loc = row[4];
var desc = row[5];
var id = row[6]; // Sixth column == eventId
// Check if event already exists, update it if it does
var event = null;
if (id.length > 0) {
try {
event = cal.getEventSeriesById(id);
} catch (e) {
// do nothing - we just want to avoid the exception when event doesn't exist
}
}
if (!event) {
//cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
var newEvent = cal.createEvent(title, tstart, tstop, {
description: desc, location: loc
}).getId();
var r = i + 1;
var cell = sheet.getRange("G" + r);
cell.setValue(newEvent);
} else {
Logger.log(event);
event.setTitle(title);
event.setDescription(desc);
event.setLocation(loc);
// event.setTime(tstart, tstop); // cannot setTime on eventSeries.
// ... but we CAN set recurrence!
var recurrence = CalendarApp.newRecurrence().addDailyRule().times(1);
event.setRecurrence(recurrence, tstart, tstop);
}
debugger;
}
}
I think I must be making an obvious rookie mistake but cannot figure it out. Any chance of some help?
BTW: my dates are formatted: 12/01/2019 and times formatted: 18:00:00.

Google Script copy and paste as values debug

Looking to
Find cell in first row that matches yesterday's date (this part works)
Select column that cell belongs to
Copy entire column and paste as values
Not sure where the code is breaking
function CopyandPasteasValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[1];
// sheet is the first worksheet in the spreadsheet
var today = new Date();
var yesterday = new Date();
yesterday.setDate(today.getDate()-1);
yesterday.setHours(3,0,0,0); //comparison doesn't seem to work without this
for(var i=0; i< 26; i++) {
var cell = sheet.getRange(1,i+2); //start getting sheet date at cell C1
var sheetdate = cell.getValue();
if(sheetdate.valueOf() == yesterday.valueOf()) {
// if there's a match, set the col
var col = (i);
// copy column and paste as values -- BELOW DOESN"T WORK --
function copyandpastescol() {
sheet.getRange(1, col+2, sheet.getMaxRows(), 1).activate();
sheet.getActiveRange().copyTo(sheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
}
}
}
Duh... didn't need the extra function! Thanks...
/** #OnlyCurrentDoc */
function CopyandPasteasValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// ss is now the spreadsheet the script is associated with
var sheet = ss.getSheets()[1]; // sheets are counted starting from 0
// sheet is the first worksheet in the spreadsheet
// set and store a date object for today
var today = new Date();
var yesterday = new Date();
yesterday.setDate(today.getDate()-1);
yesterday.setHours(3,0,0,0);
// iterate the values in the range object
for(var i=0; i< 26; i++) {
var cell = sheet.getRange(1,i+2); //start getting sheet date at cell C1
var sheetdate = cell.getValue();
// Compare only values of the objects
if(sheetdate.valueOf() == yesterday.valueOf()) {
// if there's a match, set the col
var col = (i+2);
// copy column and paste as values
sheet.getRange(1, col, sheet.getMaxRows(), 1).activate();
sheet.getActiveRange().copyTo(sheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
}
}

Clear Data rather then deleting row

I have the script below that works for what i need except the ending where it deletes the row out. What I am in need of is it to copy and paste from Sheet1 to Sheet2, and clear the row out of sheet1 except for column A.
function copyrange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1'); //source sheet
var testrange = sheet.getRange('D:D');
var testvalue = (testrange.getValues());
var csh = ss.getSheetByName('Sheet2'); //destination sheet
var data = [];
var j =[];
//Condition check in D:D; If true copy the same row to data array
for (i=0; i<testvalue.length;i++) {
if ( testvalue[i] == 'x') {
data.push.apply(data,sheet.getRange(i+1,1,1,11).getValues());
//Copy matched ROW numbers to j
j.push(i);
}
}
//Copy data array to destination sheet
csh.getRange(csh.getLastRow()+1,1,data.length,data[0].length).
setValues(data);
//Delete matched rows in source sheet ** I Need these to clear data
from B:E for row that it copied and pasted rather then deleted it out.***
for (i=0;i<j.length;i++){
var k = j[i]+1;
sheet.deleteRow(k); // I have tried sheet.Clearcontents, with no sucess
//Alter j to account for deleted rows
if (!(i == j.length-1)) {
j[i+1] = j[i+1]-i-1;
}
}
}
I was able to find an alternate way of clearing what i need which was thru another script that clear any orange cell. I used conditional formatting to get this to work. See below. Thanks....
function copyandclearorange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Research'); //source sheet
var testrange = sheet.getRange('L:L');
var testvalue = (testrange.getValues());
var csh = ss.getSheetByName('Log'); //destination sheet
var data = [];
var j =[];
//Condition check in L:L; If true copy the same row to data array
for (i=0; i<testvalue.length;i++) {
if ( testvalue[i] == 'x') {
data.push.apply(data,sheet.getRange(i+1,1,1,11).getValues());
//Copy matched ROW numbers to j
j.push(i);
}
}
//Copy data array to destination sheet
csh.getRange(csh.getLastRow()+1,1,data.length,data[0].length).setValues(data);
var sheet = SpreadsheetApp.getActive().getSheetByName('Research');
var range = sheet.getDataRange();
var bgColors = range.getBackgrounds();
for (var i=0; i<bgColors.length; i++) {
for (var j=0; j<bgColors[i].length; j++) {
if (bgColors[i][j] === '#ff9900') {
range.getCell(i+1,j+1).clearContent();
}
}
}
}

Calling a function from onEdit() trigger doesn't work

I want to run a function that updates some values when I edit one cell of a column. This line of the trigger works well: dataCell0.setValue(today_date(new Date())[2]);. But this other line updatePercent(); doesn't. But if I call this updatePercent() function from a time based trigger (in Resources), it works well. What is going wrong with this updatePercent() call?
function onEdit(){
var s = SpreadsheetApp.getActiveSheet();
if( ( s.getName() == "mySheet1" ) || (s.getName() == "mySheet2") ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( s.getRange(1, r.getColumn()).getValue() == "PORCENT_TIME") { // If you type a porcent, it adds its date.
var dataCell0 = r.offset(0, 1);
dataCell0.setValue(today_date(new Date())[2]);
updatePercent();
}
}
}
Here the updatePercent function code:
/**
* A function to update percent values accoding to input date.
**/
function updatePercent() {
var sheet = SpreadsheetApp.getActiveSheet();
var column = getColumnNrByName(sheet, "PORCENT_TIME");
var input = sheet.getRange(2, column+1, sheet.getLastRow(), 4).getValues();
var output = [];
for (var i = 0; i < input.length; i++) {
var fulfilledPercent = input[i][0];
Logger.log("fulfilledPercent = " + fulfilledPercent);
var finalDate = input[i][3];
Logger.log("finalDate = " + input[i][3]);
if ( (typeof fulfilledPercent == "number") && (finalDate instanceof Date) ) {
var inputDate = input[i][1]; // Date when input was added.
var restPorcentPen = 100 - fulfilledPercent;
var restantDays = dataDiff(inputDate, finalDate);
var percentDay = restPorcentPen/restantDays;
Logger.log("percentDay = " + percentDay);
var passedTime = dataDiff(inputDate, new Date());
Logger.log("passedTime = " + passedTime);
var passedPorcent = passedTime * percentDay; // How much percent this passed time is?
Logger.log("passedPorcent = " + passedPorcent);
var newPorcent = (fulfilledPercent + passedPorcent);
newPorcent = Math.round(newPorcent * 100) / 100;
Logger.log("newPorcent = " + newPorcent);
var newInputDate = hoje_data(new Date())[2]; // Now update the new input date
// newPorcent = newPorcent.toFixed(2);
output.push([newPorcent, newInputDate]);
sheet.getRange(2, column+1, output.length, 2).setValues(output);
Logger.log(" ");
var column25Dec = getColumnNrByName(sheet, "PORCENT_25DEZ");
var passedTimeSince25Dec = dataDiff(new Date(2013,11,25), new Date()); // Months: January is 0;
var decPercent = (newPorcent - (passedTimeSince25Dec * percentDay)); // .toFixed(2).replace(".", ",");
decPercent = Math.round(decPercent * 100) / 100;
// if (sheet.getRange(output.length+1, column25Dec+1).getValues() == ''){
sheet.getRange(output.length+1, column25Dec+1).setValue(decPercent );
// }
var remainingYears = dataDiffYears(new Date(), finalDate);
sheet.getRange(output.length+1, column).setValue(remainingYears);
}
else {
newPorcent = "Put a final date"
output.push([newPorcent, inputDate]);
sheet.getRange(2, column+1, output.length, 2).setValues(output);
}
if (finalDate instanceof Date){
var remainingYears = dataDiffYears(new Date(), finalDate);
// Logger.log("remainingYears = " + remainingYears);
}
else {
remainingYears = "insert a valid date";
}
sheet.getRange(output.length+1, column).setValue(remainingYears);
}
}
I will guess you're using the new gSheets. Check if it will work in the old-style sheets. The new sheets' onEdit trigger has problems, particularly with getActive.
My problem was in the updatePercent() funciton. Thank you, guys!

How to automatically delete rows that contain a date with more than 3 days offset to the past from now?

I am trying to get a script going that will automatically delete rows with a date over 3 days old (4 days on)
I found this script that I was hoping to be able to adapt:
function DeleteOldEntries() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
//give your sheet name below instead of Sheet1
var sheet = ss.getSheetByName("Foglio1");
var datarange = sheet.getDataRange();
var lastrow = datarange.getLastRow();
var currentDate = new Date();
var oneweekago = new Date();
oneweekago.setDate(currentDate.getDate() - 7);
for (i = lastrow; i >= 2; i--) {
var tempdate = sheet.getRange(i, 1).getValue();
if (tempdate < oneweekago) {
sheet.deleteRow(i);
}
}
}
But there seems to be an error in the script itself that I need to figure out before adapting it to 4 days instead of 7 (that part is easy)
My sheet has 3 columns with the date in column C if that info is helpful
"date in column C, if that info is helpful"
It is indeed ! instead of trying to get a date in column A as it it done in this line :
var tempdate = sheet.getRange(i, 1).getValue();
you should look at the value in column C like this :
var tempdate = sheet.getRange(i, 3).getValue();
but to be more efficient you should do these comparisons at array level, try it like below and it will run much faster ...
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Foglio1");
var datarange = sheet.getDataRange();
var lastrow = datarange.getLastRow();
var values = datarange.getValues();// get all data in a 2D array
var currentDate = new Date();
var oneweekago = new Date();
oneweekago.setDate(currentDate.getDate() - 7);
for (i=lastrow;i>=2;i--) {
var tempdate = values[i-1][2];// arrays are 0 indexed so row1 = values[0] and col3 = [2]
if(tempdate < oneweekago)
{
sheet.deleteRow(i);
}
}
}
It will be much much faster if your rows are in order of date, newest at the top and you delete all the rows at once and not one at a time.
function deleteOldData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("CallHub1");
var datarange = sheet.getDataRange();
var lastrow = datarange.getLastRow();
var values = datarange.getValues();// get all data in a 2D array
var currentDate = new Date();
var daysago = new Date().setDate(currentDate.getDate() - 3);
var yearago = new Date().setDate(currentDate.getDate() - 365);
for (i=lastrow;i>=2;i--) {
var tempdate = values[i-1][0];// arrays are 0 indexed so row1 = values[0] and col3 = [2]
if(tempdate < daysago) {
if(tempdate < yearago) {continue;}
sheet.deleteRows(1, i);
break;
}
}
}