I'm trying to auto-populate a cells time ( cell B2 in sheet "leads")
But doesn't seem to run the script successfully. Gives me the error "TypeError: Cannot read property "source" from undefined. (line 6, file "Code"
function onEdit(event) {
var timezone = "GMT-2";
var timestamp_format = "MM-dd-yyyy"; // Timestamp Format.
var updateColName = "Time";
var sheet = event.source.getSheetByName('Leads'); //Name of the sheet where you want to run this script.
var responseArray = ["Time"];
var questionArray = ["Time"];
var actRng = event.source.getActiveRange();
var editColumn = actRng.getColumn();
var index = actRng.getRow();
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues(); //get values and place them inside array
var dateCol = headers[0].indexOf(timeStampColName); //get index position inside the array
for (var i = 0; i < questionArray.length; i++) {
if (headers[0].indexOf(responseArray[1]) > -1 && index > 1 && editColumn == (headers[0].indexOf(questionArray[i]) + 1)) { // only timestamp if 'Last Updated' header exists, but not in the header row itself!
var cell = sheet.getRange(index, (headers[0].indexOf(responseArray[i]) + 1));
var date = Utilities.formatDate(new Date(), timezone, timestamp_format);
cell.setValue(date);
}
}
}
I've tried all solutions but nothing seems to give me a successful run.
I want cell B2 to automatically add the time when someone starts to enter data into cell A1
That code is very over complicated for what you're trying to achieve to be honest.
Try using this:
function onEdit(e) {
var TIME_ZONE = "GMT-2"; //enter desired timezone
var date = Utilities.formatDate(new Date(), TIME_ZONE, 'MM-dd-yyyy'); //enter desired date format
//if column A has been edited, set date in same row in column B
if (e.range.getColumn() == 1) {
var row = e.range.getRow();
e.source.getSheetByName('Leads').getRange(row, 2).setValue(date);
}
}
Put simply, this code will check that the user has edited column A, if so then it'll put a date value into the same row in column B.
Related
I want to have a sheet which automatically sorts the most recently edited row to the top, in order to surface freshly edited results and not let them be buried by outdated entries.
Here's the solution I came up with for a Google Apps Script:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var dateColumn = 2; // What column should date be written to
var headerRows = 2;
var tableRange = "A3:M101"; // What data to sort.
var sheetName = 'Sheet name' // Name of the sheet to sort
if( sheet.getName() == sheetName ) { // Checks that we're on the correct sheet
var editedCell = sheet.getActiveCell();
var offset = dateColumn - editedCell.getColumn() // Finds the offset needed to move from edited cell to date column
if( editedCell.getColumn() != dateColumn && editedCell.getRow() > headerRows) { // Don't overwrite manually set dates or the header row(s)
var dateCell = editedCell.offset(0, offset); // Go to relevant date cell
var now = new Date();
now = Utilities.formatDate(now, "GMT", "yyyy/MM/dd HH:mm:ss"); // Format datetime
dateCell.setValue(now);
}
var range = sheet.getRange(tableRange);
range.sort( { column : dateColumn, ascending: false } ); // Sort range by date column, newest on top
// range.setWrapStrategy(SpreadsheetApp.WrapStrategy.WRAP); // Sets text wrapping to wrap if uncommented
}
}
Plus adding an event trigger on form submission.
This could work with an on form submit but not like you think
function onFormSubmit(e) {
const sh = e.range.getSheet();
if (sh.getName() == 'Sheet name' && e.range.columnStart != 2 && e.range.rowStart > 3) {
e.range.offset(0, 2 - e.range.columnStart).setValue(Utilities.formatDate(new Date(), "GMT", "yyyy/MM/dd HH:mm:ss"));
sh.getRange(3, 1, sh.getLastRow() - 2, 13).sort({ column: 2, ascending: false });
}
}
columStart will always be one so that will work
row start will work after you get past row 3
and the sheet will always have to be the linked sheet name and resorting the linked sheet seems kind of weird to me it's already sorted by time stamp
I'm trying to make an Entry/Exit logbook, where staff would tag their ID cards to the card-reader at the entrance, which will populate a cell in column A, and this will trigger the script to create a day/time stamp.
{
function activeSheetName()
{
return
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
}
{
var timezone = "GMT+7";
var timestamp_format = "MM/dd/yyyy HH:mm:ss"; // Timestamp Format.
var updateColName = "CardID";
var timeStampColName = "Date/Time";
var sheet = event.source.getSheetByName('Current'); //Name of the sheet where you want to run this script.
var actRng = event.source.getActiveRange();
var actSheet = event.source.getActiveSheet();
var actSheetName = actSheet.getSheetName();
var updateSheetName = sheet.getSheetName();
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 updateCol = headers[0].indexOf(updateColName); updateCol = updateCol+1;
if (dateCol > -1 && index > 1 && editColumn == updateCol && actSheetName == updateSheetName) { // 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);
}
}
}
The problem is when the card is tagged, the cursor stays in the cell, so I need to hit enter for it to move down. Can I edit the script above for cursor to move one cell down automatically, as soon as the ID card is read by the reader? Please help, I've tried a separate jump down script and edit this one, but nothing worked so far. Thanks!
Example Logbook
If you mean mouse cursor, then I don't think you can do it via GAS. But if I understand you correctly, you want to activate the next cell in Column A after value was set. To do that, add method sheet.getRange(index+1,1).activate(); after you set value.
I am working with a Google Script (see below) to timestamp when actions occur on the spreadsheet. The script works great EXCEPT for 1 problem. The timestamp returns data in 12-hour format, but will not indicate whether it is AM/PM. If the script triggers at 16:00:00, the time stamp reads 4:00 AM instead of PM. Can someone help me please? I have already tried adding the AM/PM to the timestamp_format, but then the script fails to run.
function onEdit(event)
{
var timezone = "America/Chicago";
var timestamp_format = "MM/dd hh:mm"; // Timestamp Format.
var updateColName = "Customer Update Confirmation 4";
var timeStampColName = "TimeStamp 4";
var sheet = event.source.getSheetByName('COVERED'); //Name of the sheet where you want to run this script.
var responseArray = ["TimeStamp 1", "TimeStamp 2","TimeStamp 3","TimeStamp 4","TimeStamp 5","TimeStamp 6"];
var questionArray = ["Freight Broker 1 Day Follow Up", "Freight Broker Pickup Day Follow Up", "Load Pickup Update 1","Load Pickup Update 2","Load Pickup Update 3"];
var actRng = event.source.getActiveRange();
var editColumn = actRng.getColumn();
var index = actRng.getRow();
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();//get values and place them inside array
var dateCol = headers[0].indexOf(timeStampColName); //get index position inside the array
for(var i = 0; i < questionArray.length ; i ++){
if (headers[0].indexOf(responseArray[1]) > -1 && index > 1 && editColumn == (headers[0].indexOf(questionArray[i])+1) ) { // only timestamp if 'Last Updated' header exists, but not in the header row itself!
var cell = sheet.getRange(index, (headers[0].indexOf(responseArray[i])+1) );
var date = Utilities.formatDate(new Date(), timezone, timestamp_format);
cell.setValue(date);
}
}
}
I have a Google Sheets which have protected data range for example A2:F99, A100:F199 and so on. Now if new rows of data entered to A200 and onward, it is working fine. But if No new data is entered to A200 and onward for example, the highlighted block (** ) of codes should not be executed. And when there is no new rows of data, that code block of codes between ( **) works surprisingly on A1:F2. Please note that A1:F1 is not protected.
So how to code it when there will be no new data, the highlighted block of codes MUST not be executed.
function onePeriod(){
// For a single Period Class
var spreadsheet = SpreadsheetApp.getActive();
var dashboard = spreadsheet.getSheetByName("Dashboard");
var sheetName = dashboard.getRange("A4").getValue();
//retrieve the start date to use as desired
var startDate = dashboard.getRange("C4").getDisplayValue();
var endDate = dashboard.getRange("D4").getDisplayValue();
var sheet = spreadsheet.getSheetByName(sheetName);
//chose the range within the specified dates, for this first locate the date column
var startRow = 2;
var dateColumn = sheet.getRange(startRow,1,sheet.getLastRow(), 1);
var dates = dateColumn.getDisplayValues().flat();
var firstRow = dates.indexOf(startDate)+startRow;
var lastRow = dates.lastIndexOf(endDate)+startRow;
//now get the range between (and including) those rows
var range = sheet.getRange(firstRow, 1, lastRow-firstRow+1, sheet.getLastColumn());
var newRows = lastRow-firstRow;
**if(newRows > 0){
//Sorting and removing duplicates
// You need to specify by which column you want to sort your data, in this sample it it column 3 - that it column C
var column = 3;
range.sort({column: column, ascending:true});
range.removeDuplicates([column]);
//now delete empty rows if any
var deleteRows = 0; // <--- Added
for (var i = range.getHeight(); i >= 1; i--){
if(range.getCell(i, 1).isBlank()){
sheet.deleteRow(range.getCell(i, 1).getRow());
deleteRows++;
}
}
//Protecting data
var timeZone = Session.getScriptTimeZone();
var stringDate = Utilities.formatDate(new Date(), timeZone, 'dd/MM/yy HH:mm');
var me = Session.getEffectiveUser();
var description = 'Protected on ' + stringDate + ' by ' + me;
var height = range.getHeight();
var newHeight = height+1;
var newRange = sheet.getRange(firstRow, 1, newHeight-deleteRows, sheet.getLastColumn());
var protection = newRange.protect().setDescription(description);
newRange.getCell(newHeight-deleteRows, 2).setValue(height-deleteRows + ' Students, Signed by ' + me).offset(0, -1, 1, 6).setBackground('#e6b8af');
//protection.setDomainEdit(false);
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
}**
}
You are retrieving the first and the last index of the occurence of a date in the sheet
If there is only one occurence - the first and the last index will be the same and thus lastRow = firstRow and newRows = 0
This is why newRows > 0 is not a good criterion
If you want to query either a date does not occur at all - check either dates.indexOf(startDate) == -1
As mentioned in the documentation for indexOf():
The indexOf() method returns the first index at which a given element
can be found in the array, or -1 if it is not present.
Adapting it to your case:
//if startdate is present in column A
if(dates.indexOf(startDate) != -1){
//Sorting and removing duplicates
...
}
function onEdit(event)
{
var timezone = "GMT-6";
var timestamp_format = "HH:mm:ss"; // Timestamp Format.
var sheet = event.source.getActiveSheet();//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 updateCol = headers[0].indexOf(updateColName); updateCol = updateCol+1;
var updateColName = sheet.getRange( 1, editColumn).getValue ();
var timeStampColName = "null";
if (updateColName == "PACK STARTED BY") {timeStampColName = "Pack Start";}
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);
}
}
Above is the code I am running in my sheet. Now This on edit event is supposed to grab the column title from the currently active cell. then using if statements should be putting a static value into the timestamp column name so I can put timestamps in my sheet. I am having a really hard time debugging this since I don't know how to debug on edit in the google scripting screen. So I can't tell what is not right about the code. Right now it does nothing.