Google Sheets - post DATE and USERNAME who edited it - google-apps-script

This code works on Google Sheets as to:
Help users update today's date in a column, and effectively add a signature.
In a specific column, users type in any random jibberish (easy to do), and the sheet will then change this to today's date, and add their logged-in email address as a signature.
Ps the sheet does know who's currently logged in - I've set the sheet so users do have to be logged in and given access to the sheet
This is my code (https://imgur.com/8KSBbsB):
function onEdit(event)
{
var timezone = "UTC";
var timestamp_format = "d/MM/yy"; // Timestamp Format.
var updateColName = "[code]";
var timeStampColName = "[code]";
var nameColname = "[codename]";
var userName = Session.getEffectiveUser().getEmail();
var sheet = event.source.getSheetByName('Rank Sheet'); //Name of the sheet where you want to run this script.
var actRng = event.source.getActiveRange();
var editColumn = actRng.getColumn();
var index = actRng.getRowIndex();
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();
var dateCol = headers[0].indexOf(timeStampColName);
var nameCol = headers [0].indexOf(nameColname); nameColname = nameColname+1;
var updateCol = headers[0].indexOf(updateColName); updateCol = updateCol+1;
if (dateCol > -1 && index > 1 && editColumn == updateCol) { // only timestamp if 'Last Updated' header exists, but not in the header row itself!
var cell = sheet.getRange(index, dateCol + 1);
var date = Utilities.formatDate(new Date(), timezone, timestamp_format);
cell.setValue(date + " " +userName)
var cell = sheet.getRange(index, nameColname + 1);
var nameCol = cell.setValue = (userName)
}
}
To do this you need to 'title' the columns [code], and [codename] (changeable).
Thank you very much to Cooper for advice given!!

Try this:
cell.setValue(date + '\n' + userName)

Related

Send emails 14 days from date in cell

I've wrote the following code- on the homepage there is a cell (merged at the moment) where we'd put in the date. The end goal is to have the script send emails out when the current date meets 14 days later from the date in the cell.
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Email addresses")
var hpsheet = ss.getSheetByName("Main Page-Control Plan")
var startRow = 2; // Start at second row because the first row contains the data labels
var numRows = 2; // Put in here the number of rows you want to process
// Fetch the range of cells A2:B4
// Column A = Email Address, Column B = First Name
var dataRange = sheet.getRange(startRow, 1, numRows, 2)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[0]; // First column of selected data
var personName = row[1]
var currentDate = new Date(hpsheet.getRange("F6:F9").getValue());
var fourteenDaysLater = new Date(currentDate.getTime() + 14 * 24 * 60 * 60 * 1000);
console.log(fourteenDaysLater)
var subject = 'Recovery schedule is due';
var message ='Hi, ' + personName + '\n\n' + 'Recovery schedule is due. Please notify other members in this email chain if this has been done. '
if (fourteenDaysLater < new Date()) {
MailApp.sendEmail(emailAddress, subject, message);
}
}
}
I've put a daily trigger on it to run the script between 6-7am and put the date in the cell as 09/02/23, I've changed the number of days to 1 in the fourteenDaysLater variable so I could see if it worked today but I didn't get emails for some reason.
Is there something wrong with the code?
I think the problem is when you parse the string to Date(), where the parsed date shows Sat Sep 16 00:00:00 GMT+12:00 2023 in my timezone.
To make sure it parses the correct format and timezone, try the code below:
var timezone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var dateString = "09/02/23"; //replace with your cell value
var format = "dd/MM/yy"; //date format to parse
var currentDate = Utilities.parseDate(dateString,timezone,format);
var fourteenDaysLater = new Date(currentDate.getTime() + 14 * 24 * 60 * 60 * 1000);

AppScript Select active range

so i am trying to when i select any column form the row, returns me the column E value, some one know how?
i don't know if i made me clear, but the idea is save the value and display after in a sidebar as default value
i have onde function who does something similar, but i don't know how works
function notifyReporterForm() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_BUGS);
var row = ss.getLastRow(), column = 1, numRows = 1, numColumns = ss.getLastColumn();
var values = ss.getRange(row, column, numRows, numColumns).getValues();
var to = values[0][2];
var user_email = values[0][3];
var ticketNo = values[0][0];
var openedDate = values[0][1]
var details = ''
var summary = values[0][6]
var text = values[0][6].split('\n')
var image_url = values[0][8]
text.map(row => {
if(row){
details += '<p>' + row + '</p>'
}
})
function onSelectionChange(e) {
const sh = e.range.getSheet();
e.source.toast(sh.getRange(e.range.rowStart,5).getValue());
e.range.setValue(sh.getRange(e.range.rowStart,5).getValue());
}

LastRow in certain column in google sheet

Any idea how to get lastRow at certain column, in this case i want the lastRow for range AJ until AX only.
var emailUser = Session.getActiveUser().getEmail();
var ss2 = SpreadsheetApp.openById('1h2jmWV7mytPF_ltxYb2uPm4Pq7iHLg-hc3k_0X4Txvw');
var ws2 = ss2.getSheetByName(emailUser);
var lastRow = ws2.getLastRow();
var rdPic = ws2.getRange(3,36,lastRow,50).getValues();
var lrPic = rdPic.filter(String).length + 1;
ws2.getRange("AJ"+lrPic).setValue(stock.tglMasuk1);
ws2.getRange("AK"+lrPic).setValue(stock.namaPic1);
ws2.getRange("AL"+lrPic).setValue(stock.locPIC1);
ws2.getRange("AM"+lrPic).setValue(stock.teritori1);
ws2.getRange("AN"+lrPic).setValue(stock.penyimpanan1);
ws2.getRange("AO"+lrPic).setValue(stock.jenisTransaksi1);
ws2.getRange("AP"+lrPic).setValue(stock.nmrDO1);
ws2.getRange("AQ"+lrPic).setValue(stock.tglDO1);
ws2.getRange("AR"+lrPic).setValue(stock.sn1);
ws2.getRange("AS"+lrPic).setValue(stock.venname1);
ws2.getRange("AT"+lrPic).setValue(stock.itm1);
ws2.getRange("AU"+lrPic).setValue(stock.ponum1);
ws2.getRange("AV"+lrPic).setValue(stock.bcd1);
ws2.getRange("AW"+lrPic).setValue(emailUser);
ws2.getRange("AX"+lrPic).setValue(dateNow);

Send email notification using multiple sheet tabs when a cell value change

Below function works well but I want to add 2nd sheet which have same number of columns and rows. The logic is the same when user select 'Yes' in column 7. How do I get to send email if user select 'yes' in Sheet2. I did create duplicate function and name sheet as 'Sheet2'. When I click 'Yes' in Sheet2, I get a email notification for Sheet1 and Sheet2 even though Sheet1 is not selected 'Yes'. If user select 'Yes' in Sheet1, it should only get email from Sheet1 and likewise in Sheet2. How do I go about it?
function sendNotification(e){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
var editedRange = e.range;
if(sheet.getName()=='Sheet1' && editedRange.getColumn()==7 && e.value=='Yes'){
var row = editedRange.getRow();
var numRows = sheet.getLastRow()-1;
var row_values = sheet.getRange(row, 1, numRows, 7).getValues()[0];
var first_name = row_values[0];
var last_name = row_values[1];
var company = row_values[3];
var email= row_values[5];
var message = "The person has completed Sheet1"+first_name+" "+last_name+ " -
"+company;
var subject = "Completed - "+first_name+" "+last_name;
MailApp.sendEmail(email, subject, message);
}
}
Replace
var sheet = ss.getSheetByName('Sheet1');
by
var sheet = e.range.getSheet();
and replace
if(sheet.getName()=='Sheet1' && editedRange.getColumn()==7 && e.value=='Yes'){
by
if(['Sheet1', 'Sheet2'].indexOf(sheet.getName()) > -1 && editedRange.getColumn()==7 && e.value=='Yes'){
['Sheet1', 'Sheet2'].indexOf(sheet.getName()) will return 0 or 1 if sheet.getName() returns 'Sheet1' or 'Sheet2', respectively and -1 in any other case.
NOTE: You can remove var ss = SpreadsheetApp.getActiveSpreadsheet();

Google Script Not Iterating Through Rows

I have a google script that changes the event dates to the day of the year, so 8/26/15 is 237, and also changes today's date to it's day of the year. It then compares the event date day of the year against today's date day of the year. If the event date integer is smaller than today's date integer than it changes the event description in the google calendar to Event Closed. The problem is it only does this for the first event in the spreadsheet. It does not iterate through all of the events and change all of the event descriptions that are before today's date.
function compareDates(){
var sheet = SpreadsheetApp.getActive().getSheetByName("Events");
var data = sheet.getDataRange().getValues();
var headerRow = 1;
var i = 1;
for (i = 1; i < data.length; i += 1) {
var row = data[i];
var room = row[5];
var description = row[6];
var agegroup = row[7];
var registration = row[8];
var calname = row[14];
var registrants = row[17];
var id = sheet.getRange(headerRow + 1, 16).getValues();
var event = CalendarApp.getEventSeriesById(id);
var description1 = (description + '\n' + '\n<b>Room:</b> ' + room + '\n' + '\n<b>Event Type:</b> ' + calname + '\n' + '\n<b>Age Group:</b> ' + agegroup);
var today = parseInt(Utilities.formatDate(new Date(sheet.getRange("U2").getValues()), "EST", "D"));
var eventDate = parseInt(Utilities.formatDate(new Date(row[0]), "EST", "D"));
var testED = sheet.getRange(headerRow + i, 22).setValue(eventDate);//To see if var Today works.
var testT = sheet.getRange(headerRow + i, 23).setValue(today);//To see if var eventDate works.
if (today > eventDate && registration === 'Y') {
var descriptionHTMLEC = '\n <div id="registration_button" ><a style="text-align:right;color:white!important;text-decoration:bold;background-color:rgb(121,183,138);background-image:-webkit-linear-gradient(top,rgb(221,75,57),rgb(121,183,138nnn ));color:#ffffff;border:1px solid rgba(0,0,0,0);border-radius:2px;display:inline-block;font-size:12px;font-weight:bold;height:27px;line-height:27px;padding:0px 20px 0px 20px;text-align:center;text-transform:uppercase;white-space:nowrap;text-decoration:none;color:white" target="_blank">Event Closed</a>';
var descriptionRegistrationEC = (description1 + '\n' + '\n' + descriptionHTMLEC);
event.setDescription(descriptionRegistrationEC);
}
}
}
It seems you are modifying the same event on each iteration. The statement:
var id = sheet.getRange(headerRow + 1, 16).getValues();
Will assign the same value to id each time. Shouldn't it be:
var id = sheet.getRange(headerRow + i, 16).getValues();
For more readable code you can just the getTime() function on the date object.
var today = new Date(sheet.getRange("C2").getValues()).getTime();
var eventDate = new Date(row[0]).getTime();