I created a bit of code, that has the On edit function.
So when others types "x" it gives me a timestamp in another cell.
Some are working on the google sheets app, and it gives you an "X" to start with
Is there anyway to get the On edit function to also work woth the large "X"?
I tried == "x","X", but then it also inserted a timestamp everytime i changed anything in the cell..
function onEdit(e) {
var sheet = e.source.getActiveSheet();
if (sheet.getName() ==
"Mandagstræning","Tirsdagstræning","Torsdagstræning","Holdkamp") {
var actRng = sheet.getActiveRange();
var editColumn = actRng.getColumn();
var rowIndex = actRng.getRowIndex();
var headers = sheet.getRange(1, editColumn, 1,
sheet.getLastColumn()).getValues();
var dateCol = headers[0].indexOf("Tid") + editColumn;
if (sheet.getRange(rowIndex, orderCol).getValue() === "x") {
sheet.getRange(rowIndex, dateCol).setValue(Utilities.formatDate(new
Date(), "UTC+8", "dd-MM-yyyy HH.mm.ss"));
}
No error message, just no time stamp when hitting "X"
Sounds like you just want this check to be case insensitive. To accomplish this you can simply lowercase the input before checking it against "x", like so:
if (sheet.getRange(rowIndex, orderCol).getValue().toLowerCase() === "x") {
sheet.getRange(rowIndex, dateCol).setValue(Utilities.formatDate(new
Date(), "UTC+8", "dd-MM-yyyy HH.mm.ss"));
}
//++
const keyss = ['x','X'];
function onEdit(e) {
var sheet = e.source.getActiveSheet();
if (sheet.getName() ==
"Mandagstræning","Tirsdagstræning","Torsdagstræning","Holdkamp") {
var actRng = sheet.getActiveRange();
var editColumn = actRng.getColumn();
var rowIndex = actRng.getRowIndex();
var headers = sheet.getRange(1, editColumn, 1,
sheet.getLastColumn()).getValues();
var dateCol = headers[0].indexOf("Tid") + editColumn;
// edited -->
if ( keyss.includes(sheet.getRange(rowIndex, orderCol).getValue())) {
sheet.getRange(rowIndex, dateCol).setValue(Utilities.formatDate(new
Date(), "UTC+8", "dd-MM-yyyy HH.mm.ss"));
}
Related
I am very new to coding so I appreciate the community keeping this in mind. This script is limited to worksheet 1 and worksheet 2. When a line is edited the user email is recorded in the edited row column 41. I would also like to put a timestamp in column 42.
Bottom Line: I need for this to include a timestamp in column 42 AND exclude edits on the first (header) row.
function onEdit (e)
{
var ss = SpreadsheetApp.getActive()
var sheets = ["Worksheet","Worksheet2"]
var ws = e.range.getSheet()
if (sheets.indexOf(ws.getName()) != -1)
{
var row = e.range.getRow()
var rng = ws.getRange(row,41)
rng.setValue(e.user.getEmail())
function onEdit (e)
{
var ss = SpreadsheetApp.getActive()
var sheets = ["Worksheet","Worksheet2"]
var ws = e.range.getSheet()
if (sheets.indexOf(ws.getName()) != -1)
{
var row = e.range.getRow()
var rng = ws.getRange(row,41)
rng.setValue(e.user.getEmail())
var timezone = "GMT-4";
var timestamp_format = "yyyy-MM-dd HH:mm:ss";
var dateCol = headers[0].indexOf('Date');// create a column if its not exits
// note: actRng = the cell being updated
var actRng = event.source.getActiveRange();
var index = actRng.getRowIndex();
if (dateCol > -1 && index > 1) { // only timestamp if 'Date' 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);
}
var sheetFrom = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Worksheet");
var sheetTo = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Worksheet2");
var valuesToCopy = sheetFrom.getRange(0, 41, sheetFrom.getLastRow(), 1).getValues();
//Paste to another sheet from first cell onwards
sheetTo.getRange(1,sheetTo.getLastColumn()-1,valuesToCopy.length,1).setValues(valuesToCopy);
}
}
This will add current time to column 42 and copy column 41 from worksheet one to worksheet2
I was able to figure it out, thank you for the help it pointed me in the right direction. The following works:
function onEdit (e)//get the range of the edited cell
{
var ss = SpreadsheetApp.getActive()
var sheets = ["Worksheet","Copy of Worksheet"]
var ws = e.range.getSheet()
if (sheets.indexOf(ws.getName()) != -1)
// Check if the edit was made in an applicable sheet
{
var row = e.range.getRow()
if(row != 1){
//Get the row of the edited cell
var rng = ws.getRange(row,41)
//Range = Row of edited cells and Column 41
rng.setValue(e.user.getEmail())
var rng = ws.getRange(row,42)
//Range = Row of edited cells and Column 42
rng.setValue(Utilities.formatDate(new Date(),"America/New_York","yyyy-MM-dd HH:mm"))
}}}
im using this script to auto date Col 1, when I edit Col 6
function onEdit(e) {
var colToWatch = 6, colToStamp = 1;
var timezone = "GMT-6";
var timestamp_format = "MM-dd-yyyy"; // Timestamp Format.
if (e.range.columnStart !== colToWatch) return;
if (e.source
.getActiveSheet()
.getRange(e.range.rowStart, colToStamp)
.getValue()) {
return;
}
var date = Utilities.formatDate(new Date(), timezone, timestamp_format);
e.source.getActiveSheet()
.getRange(e.range.rowStart, colToStamp)
.setValue(date);
}
is working perfect
What I have to do to prevent this onEdit to don't run on some tabs ?
Thanks !
You can define an array of tabs to exclude then check if current sheet is one among the excludes. Add this code after line 4.
var name = e.source.getActiveSheet().getName();
// enter names of the sheets to exclude, ['Sheet1', 'Sheet2'] etc
var excludes = [];
if (excludes.indexOf(name) != -1) return;
I have 2 sheets that both have dates saved to columns. My current date is saved on both Sheet1 and Sheet2 with the same code:
curDate = Utilities.formatDate(new Date(), "EST", "MM/dd/yyyy");
I want to have one of my scripts compare the dates from Sheet1 to Sheet2
On Sheet1 I used a small script to set the current date and then used the drag function to set the previous and next dates in the column using the same formatting here:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Update Dates')
.addItem('Set Dates', 'setDatesUp')
.addToUi();
}
function setDatesUp(){
var app = SpreadsheetApp;
var ss = app.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Sheet1");
var curDate = Utilities.formatDate(new Date(), "EST", "MM/dd/yyyy");
sheet1.getRange("A4").setValue(curDate);
}
Once the dates on Sheet1 are set up I use the following script to compare the dates from Sheet1 and Sheet2, this script also sets the date for Sheet2 because when this script is activated it's supposed to mark the current date in the corresponding box.
function onEdit() {
//Loops through all of Column C to determine which values are True and False
//Saves all True Values Row # in SavedValues
//Initialize Variables
var app = SpreadsheetApp;
var ss = app.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
var sheet2 = ss.getSheetByName("Sheet2");
//Sheet 2 S2
var cValuesS2 = sheet2.getRange("C:C").getValues();
var dValuesS2 = sheet2.getRange("D:D").getValues();
var lastRowS2 = sheet2.getLastRow();
//Variables
var curDate;
var curVar;
//Loops through all S2 rows, stops at last row
for (var i = 0; i <= lastRowS2; i++){
//Checks checkboxes in S2C:C for True OR "Complete" and adds dates in corresponding D:D cells
if (cValuesS2[i] == "true" || cValuesS2[i] == "Complete") {
//If D:i is empty
if (dValuesS2[i] == "") {
//Sets current date
curDate = Utilities.formatDate(new Date(), "EST", "MM/dd/yyyy");
//Set current D:i cell (*+1 offset)
curVar = ("D" + (i + 1));
//Sets curVar value to curDate
sheet2.getRange(curVar).setValue(curDate);
}
//Checks checkboxes in S2C:C for False OR "Incomplete" and deletes dates in corresponding D:D cells
} else if (cValuesS2[i] == "false" || cValuesS2[i] == "Incomplete") {
//If D:i is NOT empty
if (dValuesS2[i] != "") {
//Set current D:i cell (*+1 offset)
curVar = ("D" + (i + 1));
//Sets curVar to ""
sheet2.getRange(curVar).setValue("");
}
}
}
updateS1();
}
Then finally I have my script to compare the dates from the 2 Sheets together.
function updateS1() {
//Initialize Variables
var app = SpreadsheetApp;
var ss = app.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
var sheet1 = ss.getSheetByName("Sheet1");
var sheet2 = ss.getSheetByName("Sheet2");
//Sheet 1 S1
var aValuesS1 = sheet1.getRange("A:A").getValues();
var lastRowS1 = sheet1.getLastRow();
//Sheet 2 S2
var dValuesS2 = sheet2.getRange("D:D").getValues();
var lastRowS2 = sheet2.getLastRow();
//Variables
var curVar;
var curVar2;
//Loop through Sheet 1 until the bottom
//For each value in S1 A I use i
for (var i = 0; i <= lastRowS1; i++) {
//Loop through Sheet 2 until the bottom
//For each value in S2 D I use j
for (var j = 0; j <= lastRowS2; j++) {
//TODO: Compare dates from S1 A:i to S2 D:j
//If they are the same date the if statement will execute
}
}
}
I've already tried using the following
if (aValuesS1[i].toString() == dValuesS2[j].toString()) {
}
and
if (aValuesS1[i] == dValuesS2[j]) {
}
but neither option has worked. I've noticed that when I grab the "value" for the date in the Logger I get a lot of information that I don't want or need:
Thu Oct 30 2018 00:00:00 GMT-0400 (EDT)
instead of 8/30/18.
I think that this is the reason that I do not get "matching" values even if both of my boxes show the date formatted the same. I'm honestly stumped at how to solve this, so any help would be greatly appreciated.
So as it turns out, I actually can compare in my if statement with .toString() it just takes quite a while for my loop to execute in the Google Apps Script.
How can I change the background color for only the rows that were (true) as per function checkDate(row) on the originating sheet "Pasco"? Is this possible?
A little bit about the script:
A date range is inputted through function getDateRange(), all rows in sheet "Pasco" is checked for if they meet that date range through function checkDate(row). If it does meet the date range (true), function filterRows() essentially filters the rows from "Pasco" sheet, and moves them over to another sheet "Copy of Pasco".
Another way of asking my question, how can I get a range of all the rows that were "true" in sheet "Pasco". If "Pasco" wasn't sorted by date, this could mean multiple ranges, right? Once I have a range I'd be able to change background easy.
If you are to test the script, please create two sheets, 'Pasco' and 'Copy of Pasco'. In 'Pasco' Starting from row 2, place some dates down column I (column 8). To see the filtering in action. 'Copy of Pasco' will be deleted/created on each run.
Thank you for your time =)
var globalStartDate;
var globalEndDate;
function getDateRange(){
var startui = SpreadsheetApp.getUi();
var startprompt = startui.prompt('Start Date', 'Enter a date in m/d/y format', startui.ButtonSet.OK_CANCEL);
var startdate = new Date(startprompt.getResponseText());
var startdatemilliseconds = startdate.getTime();
Logger.log(startdate);
Logger.log(startdatemilliseconds);
globalStartDate = startdatemilliseconds;
var endui = SpreadsheetApp.getUi();
var endprompt = endui.prompt('End Date', 'Enter a date in m/d/y format', endui.ButtonSet.OK_CANCEL);
var enddate = new Date(endprompt.getResponseText());
var enddatemilliseconds = enddate.getTime();
Logger.log(enddate);
Logger.log(enddatemilliseconds);
globalEndDate = enddatemilliseconds;
}
function checkDate(row) {
Logger.log(row[8].getTime() <= globalEndDate && row[8].getTime() >= globalStartDate);
return (row[8].getTime() <= globalEndDate && row[8].getTime() >= globalStartDate); // Check column H
}
function filterRows() {
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = Spreadsheet.getSheetByName('Pasco');
var sheetdelete = Spreadsheet.getSheetByName('Copy of Pasco');
Spreadsheet.deleteSheet(sheetdelete);
Spreadsheet.setActiveSheet(sheet1);
Spreadsheet.duplicateActiveSheet();
var headers = 1; // # rows to skip
var sheet2 = Spreadsheet.getSheetByName('Copy of Pasco');
var range = sheet1.getDataRange();
var data = range.getValues();
var headerData = data.splice(0,headers); // Skip header rows
getDateRange();
var filteredData = data.filter( checkDate );
var outputData = headerData.concat(filteredData); // Put headers back
Logger.log(filteredData)
sheet2.clearContents(); // Clear content, keep format
// Save filtered values
sheet2.getRange(1, 1, outputData.length, outputData[0].length).setValues(outputData);
}
Sorry I don't have time to read through your code and give you a complete answer but you could just add a loop to go through the sheet and set the background colour of each row with 'true'.
In my script below I assume 'true' is in column A.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var data = sheet.getRange(1, 1, sheet.getLastRow()).getValues();
var lastCol = sheet.getMaxColumns();
for (var i = 0; i < data.length; i ++){
if(data[i][0] == true){
sheet.getRange(i + 1, 1, 1, lastCol).setBackground('Yellow');
}
}
}
EDIT
Insert this code after you call getDateRange() in the filter rows function.
var lastCol = sheet1.getMaxColumns();
for(var i = headers; i < data.length ; i++){
if(data[i][8].getTime() <= globalEndDate && data[i][8].getTime() >= globalStartDate){
sheet1.getRange(i, 1, 1, lastCol).setBackground('Yellow');
}
}
Your filter rows function should now look like this:
function filterRows() {
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = Spreadsheet.getSheetByName('Pasco');
var sheetdelete = Spreadsheet.getSheetByName('Copy of Pasco');
Spreadsheet.deleteSheet(sheetdelete);
Spreadsheet.setActiveSheet(sheet1);
Spreadsheet.duplicateActiveSheet();
var headers = 1; // # rows to skip
var sheet2 = Spreadsheet.getSheetByName('Copy of Pasco');
var range = sheet1.getDataRange();
var data = range.getValues();
var headerData = data.splice(0,headers); // Skip header rows
getDateRange();
var lastCol = sheet1.getMaxColumns();
for(var i = headers; i < data.length ; i++){
if(data[i][8].getTime() <= globalEndDate && data[i][8].getTime() >= globalStartDate){
sheet1.getRange(i + headers, 1, 1, lastCol).setBackground('Yellow');
}
}
var filteredData = data.filter( checkDate );
var outputData = headerData.concat(filteredData); // Put headers back
Logger.log(filteredData)
sheet2.clearContents(); // Clear content, keep format
// Save filtered values
sheet2.getRange(1, 1, outputData.length, outputData[0].length).setValues(outputData);
}
I am trying to move an entire row if a date is entered into column 6. The code works when I try to move a specific text, but if i try to use any date range, nothing happens. I have a feeling that the way that i'm expressing my IF statement is incorrect. Any suggestions would be greatly appreciated.
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
var d = Date(month, day, year);
// BEGINNING OF MAIN
if(s.getName() == "UNITS ON ORDER" && r.getColumn() == 6 && r.getDate() == d ) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("UNITS ON CONSIGNMENT");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I haven't tested your guy's solutions, yet. But what I did to get around it, in the column there is a TBD text field, and i set the IF statement to !=... because the person is entering in the date, and it isn't coming from a machine.
If you only want to move rows you when a date is entered, maybe you can try to use Date.parse() ?
Maybe something like this, will do the trick ?
function onEdit(event) {
var ss = event.source;
var s = ss.getActiveSheet();
var r = event.range;
if (s.getName() == "UNITS ON ORDER" && r.columnStart == 6 && !isNaN(Date.parse(r.getValue()))) {
var numColumns = s.getLastColumn();
ss.getSheetByName("UNITS ON CONSIGNMENT")
.appendRow(s.getRange(r.rowStart, 1, 1, numColumns)
.getValues()[0])
s.deleteRow(r.rowStart);
}
}