Creating a calendar event from cell data - google-apps-script

I've got my bit of code that allows me to enter a date and time and it will create a calendar event. The only problem is the date and time have to be entered in a cell that is formatted Date/Time. If I take the date from one cell and the time from another and try to create a string using these I get an error that the "calendar.createEvent" doesn't work with strings.
How do I turn my string into a date and time?
var calendar = CalendarApp.getCalendarById("xxxxxxx");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var datesheet = ss.getSheetByName("Schedule Job")
var start = datesheet.getRange("C19").getValue() & " " & datesheet.getRange("C20").getValue();
var end = datesheet.getRange("C30").getValue();
calendar.createEvent("Test",start,end);

instead of creating a string with them, try just adding them.
With a Date in A1 and a time in B1 put this formula in a cell:
=A1+B1
and then select the cell and choose Format>Number>DateTime
run your script off that value.

Related

Add $ between two characters

I need to add a $ between a "A1notation result" , it returns the possition of today´s date in an array of dates (row)
So I have a row (A1:AA1) with dates and I want to find today´s date to insert a formula
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("DB");
var date = Utilities.formatDate(now, 'GMT-5', 'dd/MM/yyyy');
var ranges = sheet.createTextFinder(date).findAll().map(r => r.getA1Notation());
sheet.getRangeList(ranges).activate();
Logger.log(ranges)
This will show where today´s date is found and log [T1](for example). I am using it to insert a formula and copyTo the destination in the same column to getLastRow(), but when used it changes the value to T2, T3 and so on instead of keeping the value in T1, so im trying to change it to $T$1 to keep it in the exact same cell and not moving downwards. Does this meake sense? Thanks in advanced
I don't think there's an option to anchor the cell automatically, surely with some string manipulation. I suggest you put in your formula INDIRECT("T1") and it won't move

How To Display Weekday in Google Sheet Script?

Please Forgive me if this has been covered couldn't find it. But Does anyone have an idea on how to get a weekday (monday, Tues, Ect...) in this Script i have running.
function newColumn() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Song of the Day');
sheet.insertColumnAfter(1);
sheet.getRange("B1").setValue(new Date()).setNumberFormat('mmm/d/yyyy');
}
Currently ^ It makes a new column B and adds the date in cell B1 Every day I would just like that date to remain the same but also display the day of the week beside it also Thanks in advance!
Display Day of Week:
function DisplayDayOfWeek() {
Logger.log(["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][new Date().getDay()])
}
If I understand right you want Column B to contain the date, and you want that to format like 'mmm/d/yyyy' and then you want column C to also have the date but to be formatted to show the Name of the Day.
I would modify your script to place the date unformatted into both columns B and C, and then use the formatting controls in your spreadsheet to display them how you want to.
Your code would change to:
function newColumn() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Song of the Day');
sheet.insertColumnAfter(1);
sheet.getRange("B1").setValue(new Date());
sheet.insertColumnAfter(2);
sheet.getRange("C1").setValue(new Date());
}
On Your spreadsheet choose the Column C, then from Format>Custom Date and Time choose one with the Name of the Day listed, and remove the parts you don't want until it looks like this:
custom date image "Day Name Only"
If you wanted to format it with code then as shown here Javascript in Google Sheets script: help using setNumberFormat
you should grab the cell and format the cell:
var cell = sheet.getRange("B1");
cell.setNumberFormat('mmm/d/yyyy');
var cell = sheet.getRange("C1");
cell.setNumberFormat('dddd+');
Date number Formattings found here: https://developers.google.com/sheets/api/guides/formats

Google App Script - copy and increment Date to next row

I have a column with date
var range = sheet.getRange(1,1);
range.copyTo(sheet.getRange(2,1));
give me the same date as previous row.
The above code works well for values and formulas, but not date.
How do I copy it such that it replicate the dragging behaviour, i.e. 11/6/2021 become 12/6/2021.
I have already formatted it as date, I can increment it by manually dragging the cell in UI, but I can't use copyTo in app script to achieve the same result.
In Apps Script, you need to convert to cell values to Date format in order to increment the date as google sheet is using Java Script by adding customize function, below is the way you can add Day + 1 in the next row using Javascript new Date() method:
function increRow(){
var ss = SpreadsheetApp.getActiveSheet();
var date = new Date( ss.getRange(1,1).getValue());
ss.getRange(2,1).setValue(new Date(date.setDate(date.getDate() + 1)));
}
You may try another method autofill which perform as human action to fill Range("A2:A4"), if you preferred:
function autoFill() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
spreadsheet.getRange(2,1).autoFill(spreadsheet.getRange(2,1,3,1), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
};

Google Spreadsheet Makro - Add one time value to another

var valueDate = Utilities.formatDate(sheet.getRange("D2").getValue(), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "dd/MM/YYYY hh:mm:ss");
var valueResetCD = Utilities.formatDate(sheet.getRange("C2").getValue(), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "hh:mm:ss");
This are my 2 lines I currently have - As the Spreadsheet timezone may be different from the makro timezone I got told to always get the timezone from the Sheet.
In those 2 values I have the right values safed (tried to print them into a field)
first is 19/09/2020 22:34:52 (a specific date) and the second is 03:00:00.000 (3 Hours)
Now what I want to do is just add those 2 times together so I get as output: 20/09/2020 01:34:52
I tried it with: sheet.getRange("Data!$A$21").setValue(valueDate + valueResetCD) but I guess it is not that easy - it just copies the 2 string values of the times into one line.
How can I add those 2 Time / Date values to eachother so I get the output above
I believe your situation and goal as follows.
In your situation, as a sample value,
valueDate is 19/09/2020 22:34:52 retrieved from sheet.getRange("D2").getValue().
valueResetCD is 03:00:00.000 retrieved from sheet.getRange("C2").getValue().
Both values are the date object.
You want to add valueResetCD to valueDate.
When the sample values are used, you want to get 20/09/2020 01:34:52 as the result value.
Modification points:
In this case, I think that valueDate is the correct date time like 19/09/2020 22:34:52 as the date object.
But, I think that valueResetCD is 1899/12/30 03:00:00. Because the Spreadsheet uses the serial number.
From this situation, it is required to convert the serial number to unix time.
And also, in this case, the time difference is required to be considered.
Both values are added by converting from the date object to the unix time. And, the result value is converted to the date object.
When above points are reflected to the Google Apps Script, it becomes as follows.
Modified script:
function myFunction() {
var sheetName = "Sheet1"; // Please set the sheet name.
// 1. Retrieve values from the cells as the date object.
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var valueDate = sheet.getRange("D2").getValue(); // As a sample value, it's `19/09/2020 22:34:52`.
var valueResetCD = sheet.getRange("C2").getValue(); // As a sample value, it's `03:00:00.000`.
// 2. Convert the date object to the unix time.
var valueDateUnix = valueDate.getTime();
var differenceBetweenSerialAndUnix = new Date("1970/01/01 00:00:00").getTime() - new Date("1899/12/30 00:00:00").getTime();
var timeDifference = (new Date().getTimezoneOffset()) * 60 * 1000;
var valueResetCDUnix = valueResetCD.getTime() + differenceBetweenSerialAndUnix - timeDifference;
// 3. Add both time and convert it to the date object.
var resultDateObject = new Date(valueDateUnix + valueResetCDUnix);
var resultString = Utilities.formatDate(resultDateObject, SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "dd/MM/YYYY hh:mm:ss");
console.log(resultDateObject)
console.log(resultString) // You can see "20/09/2020 01:34:52" at the log.
// 4. Put the value to the cell.
sheet.getRange("A1").setValue(resultDateObject);
}
Note:
In this answer, it supposes that the values from the cells "C2" and "D2" are the date object. If those values are the string which is not the date object, above script cannot be used. So please be careful this.
References:
Date
getTime()
getTimezoneOffset()

Writing a string of multiple date / time to a single cell

I have an array of a couple (the array is up to 10) date/time that I want to write to a spreadsheet using getRange().setValues(). I'm converting the array to a string and it looks correct in Logger.
[Mon Feb 02 14:01:00 GMT-06:00 2015, Tue Feb 02 01:00:00 GMT-06:00 2016, , , , , , , , ]
When I try to write the string to a single cell in a sheet:
target6.setValues(source_range6_values);
I get this error:
Incorrect range width, was 10 but should be 1 (line 84, file "Code")
Edited 4/28/2014 adding entire script:
/**
* Copies source range and pastes at first empty row on target sheet
*/
function CopyIt(){
//Establishing source and target sheets
var source_spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var target_spreadsheet = SpreadsheetApp.openById("0AhCv9Xu_eRnSdHpLTkc0d1ZURUtyTU9oRjdFbmpMUFE");
// Get source and target sheets - can be the same or different
var sourcesheet = source_spreadsheet.getSheetByName("Form Responses");
var targetsheet = target_spreadsheet.getSheetByName("Work_Orders");
//Get row of last form submission
var source_last_row = sourcesheet.getLastRow();
// Check for answer to Do you need a Flyer Created? If No, end now. If Yes, continue.
var check = sourcesheet.getRange("T"+(source_last_row)).getValue();
if (check == 'Yes') {
//Pulling date(s) from the users form entry (source sheet) into an array
var daterange = sourcesheet.getRange("H"+source_last_row+":Q"+source_last_row);
//Getting the values of the array
var classDate = daterange.getValues();
//changing the array values to a string
classDate.toString();
//Building a new variable with the string to be inserted below in the target sheet
var source_range6_values = classDate;
//source_range6_values.toString();
Logger.log(classDate[0]);
// Get the last row on the target sheet
var last_row = targetsheet.getLastRow();
//Setting the target cell in the Marketing Work Order sheet
var target6 = targetsheet.getRange("U"+(last_row+1));
// Aadding a new row in the target sheet
targetsheet.insertRowAfter(last_row);
//Inserting the values of source_range6_values into the target sheet. Unfortunately it does not enter the data into the same field and it's in military time.
target6.setValue(source_range6_values);
Logger.log(source_range6_values);
}
}
To give a correct answer for your question, i guess i need to know how you get the value of source_range6_values.
One quick guess is you might want to use target6.setValue instead of target6.setValues since you want to write the data into one cell only...
A quick & dirty way would be to replace the commas(with spaces):
source = String(source_range6_values).replace("," , " ");
I've had fun with GAS and variables. Casting it as a String should let you use the string functions on it. If that doesn't work can you share a mock-up of your sheets so I can take a look?
edit:
I had to play around with it a bit, seems google's version of .replace() only replaces the first instance (and doesn't allow .replaceAll() ).
I edited your code starting on line 23:
//Getting the values of the array
var classDate = daterange.getValues().toString();
//Building a new variable with the string to be inserted below in the target sheet
//Google has bugs, .replace() seems to only replace the first instance
//-while {} loop replaces all of them
while (!classDate.equals(classDate.replace("," , " "))) { classDate = classDate.replace("," , " "); };
var source_range6_values = classDate;
All the dates are in one cell if you change only those lines (and no errors).
I appreciate the help you two have given me trying to answer this question. #swimmingwood fixed the actual capture of the data into a string, but it left commas and when I inserted it into the target sheet, it wrote it to multiple cells with an error. It did write to the sheet but the error had you use a CTRL-E (inside the taget sheet) to complete the insert and wrote them into separate cells.
#MickATX suggested the code to replace the commas in the string with a space, which would be fine, but apparently he discovered a Google scripting problem that would only allow for the first comma to be replaced and ignore the rest. Great knowledge never-the-less.
I ended up using a formula in an addition cell in the source sheet that looked like this:
=ArrayFormula(CONCATENATE(REPT(TEXT(H2:Q2,"mm/dd/yyyy hh:mm a")&CHAR(10),H2:Q2>0)))
This formula wrote all the date/time entries provided by the form entry into one cell of the source sheet and ONLY the number of entries (1-10). I then wrote that single cell to the target sheet via the script.
Thanks to #swimmingwood and #MickATX for trying to help me, both provided worthy knowledge.
I've read a couple of strange answers here...
If you write an 2D array to a sheet it will obviously be written accross multiple cells... commas are definitely not the issue but the nature of the object is.
Simply convert your array into a string using .toString() or .join() (the latter providing the advantage you can choose the separator to use) and setValue() (without S) at the place you want.
the commas you see in the logger are only typographic representation of array elements separators...
And, last point : the .join() or .toString() methods return new variables, they don't modify the original value so when you write classDate.toString(); you are not doing anything ...
you should write it like this :
classDateAsAString = classDate.toString();
finally your code :
function CopyIt(){
//Establishing source and target sheets
var source_spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var target_spreadsheet = SpreadsheetApp.openById("0AhCv9Xu_eRnSdHpLTkc0d1ZURUtyTU9oRjdFbmpMUFE");
// Get source and target sheets - can be the same or different
var sourcesheet = source_spreadsheet.getSheetByName("Form Responses");
var targetsheet = target_spreadsheet.getSheetByName("Work_Orders");
//Get row of last form submission
var source_last_row = sourcesheet.getLastRow();
// Check for answer to Do you need a Flyer Created? If No, end now. If Yes, continue.
var check = sourcesheet.getRange("T"+(source_last_row)).getValue();
if (check == 'Yes') {
//Pulling date(s) from the users form entry (source sheet) into an array
var daterange = sourcesheet.getRange("H"+source_last_row+":Q"+source_last_row);
//Getting the values of the array
var classDate = daterange.getValues();
var source_range6_values = classDate.join(' & ');// using & as separator for example
// Get the last row on the target sheet
var last_row = targetsheet.getLastRow();
//Setting the target cell in the Marketing Work Order sheet
var target6 = targetsheet.getRange("U"+(last_row+1));
// Adding a new row in the target sheet
targetsheet.insertRowAfter(last_row);
//Inserting the values of source_range6_values into the target sheet. Unfortunately it does not enter the data into the same field and it's in military time.
target6.setValue(source_range6_values);
Logger.log(source_range6_values);
}
}
Now if you want to format the dates in a more civilized way, that should be handled a bit differently... let me know if you still need it / want it.