In Google Sheets I have a list of activities with a start date, and a number that specifies the duration in days of that activity. I need to use Google Apps Script to sum those numbers to the date, to obtain the deadline for the activity.
I've tried the solution posted in this question: Adding Days to a Date - Google Script.
The problem with that solution is that the script editor of the spreadsheet doesn't recognize the "Date" Class, so I can't instantiate a Date element.
Summing directly only takes the date and the number as a string.
Trying the method above results in a #NUM! error in the cell I want to convert.
EDIT:
I've tried this, where V3 holds the date I want to sum:
var fecha= new Date (ss.getSheetByName(camada).getRange("V3").getValue());
var fecha2= new Date();
fecha2.setDate(fecha.getDate() + 1);
ss.getSheetByName(camada).getRange("W3").setValue(fecha2);
It apparently works, but the problem is that V3 holds 5/13/2019 and the date returned is 4/14/2019, so it is a day more (13->14) but it is a month less (5->4).
The answer was in Adding Days to a Date - Google Script.
Three things:
don't define fecha2 as new Date(); this gives it no context and instead returns today's date.
let fecha2 be a variable name
the correct statement is var fecha2 = new Date(fecha.setDate(fecha.getDate() + 1));
function so55593876() {
var ss = SpreadsheetApp.getActiveSheet();
var range = ss.getRange("C3");
var value = range.getValue();
Logger.log("DEBUG: Date Range: "+range.getA1Notation()+", Date value: "+value);//DEBUG
var date = new Date(value); // make the sheet value a date object
Logger.log("DEBUG: new date(value) = "+date);//DEBUG
var dateTime = new Date(date.getTime()+1*3600000*24);
Logger.log("DEBUG: Method 1 (add one day = getTime()+1*3600000*24) = "+dateTime);//DEBUG
var dateDate = new Date(date.setDate(date.getDate()+1));
Logger.log('DEBUG: Method 2 (add one day = getdate()+1) = '+dateDate);//DEBUG
ss.getRange("C4").setValue(dateDate);
Logger.log("<<<<<<<<<<<FETCHA>>>>>>>>>>>>>");
var fecha = new Date(value); // make the sheet value a date object
Logger.log("DEBUG: fecha: new date(value) = "+fecha);//DEBUG
var fecha2= new Date(); // note there are no parameters; this will return TODAY's date
Logger.log("DEBUG: fecha2 = "+fecha2);//DEBUG
var fecha3 = fecha2.setDate(fecha.getDate() + 1);
Logger.log("DEBUG: fecha3 = "+fecha3); //DEBUG
var fecha2 = new Date(fecha.setDate(fecha.getDate() + 1));
Logger.log("DEBUG: fecha2 = "+fecha2); //DEBUG
ss.getRange("C5").setValue(fecha2);
}
I have left all the Logger statements in the code so that you can identify the various values at different states of the script.
Related
I have a column 'C' containing dates and in that some cell values are having values like " Due on Date". I have written app script code that if a cell value contains "Due on" it will be copied to another column,else copied to different column.But on running I found that cells having "due on " on running the date and month are interchanged. for eg: if a cell contains "Due on 08/02/2022(dd/MM/yyyy)" is changed to "02/08/2022(MM/dd/yyyy)". Is there any method to retain the same date format.I have already done the date format methods in the spreadsheet and maintained the same time zone .
Here is the sample code:
for(var i=value.length-1;i>=0;i--){
var chn = value[i];
if(chn[2]!="NA"){
// var rdate= new Date(chn[2]);
var dat=Utilities.formatDate(new Date(chn[2]), "GMT+5:30", "dd-MMMM-yyyy");
var mat= chn[2].toString();
if(mat.match(/Due on/)){
var d1= mat.replace("Due on", "");
var ds = new Date(dat);
var year = ds.getFullYear();
var month = ds.getDate();
var day = ds.getMonth();
Logger.log(chn[2]);
Logger.log(dat);
Logger.log(ds);
Logger.log(month);
// var pubdate = new Date(year, day,month);
// Logger.log(pubdate);
ss.getRange("C"+(i+2)).setValue("Valid till "+Utilities.formatDate(ds, "GMT+5:30", "dd-MMMM-yyyy"));
}
else{
.................
}
}
A copy of the spreadsheet and the executions log is attached here:
Execution log:
You code works for me correctly, however here are some thoughts for troubleshooting
You do not specify into which sheet you want to write (I assume ss is SpreadsheetApp.getActiveSpreadsheet()). This is dangerous when your spreadsheet has several sheets. It's best to sue the method getSheetByName()
Reduce your code snippet to something simpler to reduce potential error sources
Change you spreadsheet locale for changing the date formatting
Since your date is concatenated to a string (and the method formatDate() returns a date anyway), the output should not be affected by any locales and date formatting, however to be sure, try to set it explicitly to a string.
Make sure you pass to new Date() a valid date object or date string.
This code snippet works for me regardless of the spreadsheet locale and the number formatting of the cells:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
for(var i = 10; i >= 0; i--){
var dat=Utilities.formatDate(new Date("2022-05-15"), "GMT+5:30", "dd-MMMM-yyyy");
ss.getRange("C"+(i+2)).setValue(("Due on " + dat).toString());
}
}
UPDATE:
If the problem is the format of the original date string, you need to convert it to the necessary format for new Date(). To do so, you need to know the formatting of the original date string.
For a date string with the format ddmmyyyy , you can do it as following:
var chn = [];
chn[2] = "15052022";
var day = Number(chn[2].substring(0,2));
var month = Number(chn[2].substring(2,4));
var year = Number(chn[2].substring(4,8));
console.log("day: " + day)
console.log("month: " + month)
console.log("year: " + year)
var dat= Utilities.formatDate(new Date(year, month - 1, day), "GMT+5:30", "dd-MMMM-yyyy");
ss.getRange("C2").setValue(("Due on " + dat).toString());
I have a google sheets document that has the date as the sheet name for every day of the month.
For example, this month I have 10/1, 10/2, 10/3, 10/4, 10/5... etc and everyday I duplicate the old sheet, update the tab name for the new sheet and hide the oldest sheet.
For example, if I have tabs 10/1, 10/2, 10/3, 10/4, 10/5 -> Is there a way to add a new tab, name it 10/6 (with the same contents as 10/5) and hide 10/1?
I also have a formula. For example, in tab 10/6 I would have "=(B34+B30-'10/5'!B30)/B35" <-- all the contents are within 10/6 except for '10/5'!B30 which I need to change manually after duplicating the sheet.
So when I create 10/7 I need to go in and change the formula from '10/5' to '10/6'?
To recap:
I need to duplicate the most recent tab and change the tab name to today's date.
I need to hide the oldest tab, so in the example I would create 10/6 and hide 10/1
I need to change the formula to match the previous day, so for tab 10/6 I need the formula to link to 10/5
Tried this formula but it keeps labeling as total days so 10/14 -> 10/287
function duplicatesheet() {
var as = SpreadsheetApp.getActiveSpreadsheet(); // active spreadsheet
var s = as.getActiveSheet(); // first sheet object
var dateCell = "A1"; // cell containing first date
var N = 1; // number of copies to make
var startDate = new Date(s.getRange(dateCell).getValue()); // get the date stored in dateCell
var day = startDate.getDate(); // extract the day
var month = startDate.getMonth(); // extract the month
var year = startDate.getFullYear(); // extract the year
// loop over N times
for (var i = 0; i < N; i++) {
var asn = s.copyTo(as); // make a duplicate of the first sheet
var thisSheetDate = new Date(year, month, day+(i+1)); // store the new date as a variable temporarily
asn.getRange(dateCell).setValue(thisSheetDate); // writes the date in cell "B3"
asn.setName(Utilities.formatDate(thisSheetDate, "GMT", "MM/DD")); // sets the name of the new sheet
}
}
This will insert a new sheet with the correct name assuming that you are still making your sheet as 10/10,10/11,10/12,10/13 then this function will determine the proper month and day for the next sheet.
function insertnewsheet() {
//find the sheets
const ss = SpreadsheetApp.getActive();
const shts = ss.getSheets().filter(sh => sh.getName().match(/\d{1,2}\/\d{1,2}/g));
let oA = shts.map(sh => [sh.getName()]);
//Sort them based upon date value in milliseconds
oA.sort((a, b) => {
let tA = a[0].split('/');
let vA = new Date(new Date().getFullYear(), parseInt(tA[0]) -1 , parseInt(tA[1])).valueOf()
let tB = b[0].split('/');
let vB = new Date(new Date().getFullYear(),parseInt(tB[0]) - 1, parseInt(tB[1])).valueOf();
return vA - vB;
});
Logger.log(oA.join('\n'));
//take the last one and figure out the next month and day using the Date() object
let md = oA[oA.length - 1][0].split('/');
let dt = new Date(new Date().getFullYear(), parseInt(md[0]) - 1, parseInt(md[1]) + 1);
let name = `${dt.getMonth() + 1}/${dt.getDate()}`;
ss.insertSheet(name);
Logger.log(name);
}
I want to compare the dates in Referral Date column with the present day and if Referral Date is lesser than present day then proceed with script if not throw an error "future date referral".
function dateFun() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Worksheet");
var headers = ss.getRange('A:Z').getValues()[0];
var column =headers.indexOf("Referral Date")+1;
var presentDay = new Date();
if (column.valueOf()>presentDay){
}else{
SpreadsheetApp.getUi().alert("Future Date Referral")
}
}
Image for reference
Hope its clear!
Date objects can be compared with logical operators.
Ok you are on the right track here, but you are missing some important methods to get the data from the spreadsheet.
function dateFun() {
// Open the worksheet
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Worksheet");
// Get data display values
var range = ss.getRange('A:Z');
// Get index of "Referral Date" in headers
var headers = range.getValues()[0];
var columnIndex = headers.indexOf("Referral Date")+1;
// Get today's date
var presentDay = new Date();
// Loop through the dates column
for(var i=1;i<=range.getNumRows();i++){
// Get the value to compare to today
var rowDate = new Date(range.getValues()[i+1][columnIndex]);
if(rowDate.valueOf()>presentDay.valueOf()){
SpreadsheetApp.getUi().alert("Future Date Referral");
}
}
}
Further reading:
Date()
getDisplayValue()
I am trying to get a sheet to populate data in a new tab, I need three columns type, service and date/month. However, the getMonth statement keeps throwing an error and I'm unsure why?
var service = inputSheet.getRange('O' + lastRow).getValue();
var date = inputSheet.getRange('L' + lastRow).getValue();
var month = date.getMonth();
I expected this to return the date held in variable date as the month it was entered.
You have to explicitly create a JavaScript / Google Apps Script Date object using the value returned by getValue():
var date = new Date(inputSheet.getRange('L' + lastRow).getValue());
var month = date.getMonth();
Note: getMonth() returns a value 0 - 11 not 1 - 12.
I have a column in which dates are saved in string format like this: "Tuesday, 18th November(11:00)"
I want to take this string date and save its equivalent date in Date format corresponding to its row in new column (first empty column in sheet), so that I can later compare that date with current date.
I have written this function and I am in test phase. However I have two questions :
1) This function is not inserting value in corresponding row in new column.
2) Since setValue is Object type it will not save value in Date type, for me setDay, set Month methods are not working (may be because of wrong object).
Here is my code:
function replaceStringDate(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
var lastColumn = SpreadsheetApp.getActiveSheet().getLastColumn();
var dataRange = sheet.getRange(startRow,2,lastRow,12);
var values = dataRange.getValues();
var index = dataRange.getRowIndex();
for(i=0;i<values.length;++i){
var lastCell = sheet.getRange(index,14);
var appointmentDateFirst = values[i][8] ;
if (appointmentDateFirst == "Thursday, 18th November (11:00 to 12:00)") {lastCell.setValue('18/11/2011');}
index=index+1;
} //end for loop
} //end function
here is a piece of code to start with, I played with string manipulation and regex... It's kind of fragile and needs to be improved to handle different cases but the idea is working...
I'm sure it can be done more efficiently with only regex but this string approach was easier...
function convertToDateTest(){
Logger.log(convertToDate("Tuesday, 18th November(11:00)"))
}
function convertToDate(str){
Logger.log(str.substring(str.indexOf(', ')+1,str.indexOf('(')).replace('th','')+' '+new Date().getFullYear());
var date = new Date(str.substring(str.indexOf(', '),str.indexOf('(')).replace('th','')+' '+new Date().getFullYear());
var time = str.match(/((([0-1]?[0-9])|([2][0-3])):)([0-5][0-9])/g);
Logger.log(time);
new Date(date).setHours(time[0]);
return date;
}