Combining These Two Scripts - google-apps-script

I'm trying to combine two scripts to run simultaneously but I can't get both of them to run. Below are the two separate scripts.
function onEdit(event) {
var sheet = event.source.getActiveSheet();
var editedCell = sheet.getActiveCell();
var columnToSortBy = 7;
var tableRange = "A2:T399"; // What to sort.
if(editedCell.getColumn() == columnToSortBy){
var range = sheet.getRange(tableRange);
range.sort( { column : columnToSortBy, ascending: false } );
}
}
and
function onEdit(event)
{
var timezone = "GMT-5";
var timestamp_format = "MM-dd-yyyy"; // Timestamp Format.
var updateColName = "Parent Sign-Out";
var timeStampColName = "Timestamp";
var sheet = event.source.getSheetByName('Area Check-in'); //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;
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);
}
}
I'm not sure if I need to name them individually. And if so, how would I add the names?

function onEdit(e) {
var sh=e.range.getSheet();
if(sh.getName()=='NameOfSheetYouWantThisToWorkOn') {
if(e.range.columnStart==7) {
e.range.getSheet().getRange("A2:T399").sort({column:7,ascending:false});
}
}
if(sh.getName()=='Area Check-in') {
var headers=sh.getRange(1,1,1,sh.getLastColumn()).getValues()[0];
var dateCol=headers.indexOf("Timestamp")+1;
var updateCol=headers.indexOf("Parent Sign-Out")+1;
if (dateCol>0 && e.range.rowStart>1 && e.range.columnStart == updateCol) {
sh.getRange(e.range.rowStart,dateCol).setValue(Utilities.formatDate(new Date(), "GMT-5", "MM-dd-yyyy"));
}
}
}

Related

columnEdit not applying to my range of columns

Script works really well but I have 12 columns and this script only works on A and B.
function onEditTwoWay(e) {
var ss = SpreadsheetApp;
var sheet = ss.getActiveSpreadsheet();
var sheet1 = sheet.getSheetByName("Dep1");
var sheet2 = sheet.getSheetByName("Dep2");
var cell = sheet.getActiveCell();
var value = cell.getValue();
var currentRow = cell.getRow();
var currentColumn = cell.getColumn();
var activeWorksheet = ["Dep1","Dep2"];
var columnEdit = [1,2,12];
if(activeWorksheet.indexOf(ss.getActiveSheet().getName()) > -1 &&
columnEdit.indexOf(currentColumn) > -1 && currentRow > 1) {
sheet1.getRange(currentRow, currentColumn).setValue(value);
sheet2.getRange(currentRow, currentColumn).setValue(value);
};
};
Try this:
function onEdit(e) {
const sh = e.range.getSheet();
var shts = ["Dep1", "Dep2"];
var cols = [1, 2, 12];
if (~shts.indexOf(sh.getName()) && ~cols.indexOf(e.range.columnStart) && e.range.rowStart > 1) {
shts.forEach(name => {
e.source.getSheetByName(name).getRange(e.range.rowStart, e.range.columnStart).setValue(e.value);
});
}
}
All columns need to be entered in columnEdit so changed from
columnEdit = [1,2,12] to columnEdit = [1,2,3,4,5,6,7,8,9,10,11,12]

How do I make a single script work on multiple tabs in the same sheet

I am fairly new to this, I have a script that will update the time stamp when any cell in the row is edited, however I cannot get it to work for multiple sheets. It works for Sheet 1 but no matter what I do I cannot get it to also work for Sheet 2 as well, I thought I could copy and paste it below and and change the sheet name but it hasn't worked
Here is the script
function onEdit(e)
{
var sheet = e.source.getActiveSheet();
if (sheet.getName() == "Sheet 1") //
{
var actRng = sheet.getActiveRange();
var rowIndex = actRng.getRowIndex();
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();
var dateCol = headers[0].indexOf("Timestamp") + 1;
if (dateCol > 0 && rowIndex > 1 && e.range.columnStart > 1)
{
sheet.getRange(rowIndex, dateCol).setValue(Utilities.formatDate(new Date(), "UTC+8", "MM-dd-yyyy"));
}
}
function onEdit(e) {
var sheet = e.source.getActiveSheet();
const selected = ['Sheet1', 'Sheet2'];
if (~selected.indexOf(sheet.getName())) {
var actRng = sheet.getActiveRange();
var rowIndex = actRng.getRowIndex();
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();
var dateCol = headers[0].indexOf("Timestamp") + 1;
if (dateCol > 0 && rowIndex > 1 && e.range.columnStart > 1) {
sheet.getRange(rowIndex, dateCol).setValue(Utilities.formatDate(new Date(), "UTC+8", "MM-dd-yyyy"));
}
}
}

Check if in cell Today's date then continue

I found a script on the Internet and am trying to alter it a little to fit my needs. But stumbled upon a problem. The script takes a list of bookmarks from the drop down menu and if you write OK in the next cell, then it transfers the line to the selected bookmark. I want to confirm today's date.
Copy of the sheet. Also here some diffeent.
var actionCol = 7;
var nameCol = 6;
https://docs.google.com/spreadsheets/d/1P9avWP8i5Z4KA4zt3EoUZNbgMKeXwnOYKsgCG2_vSLE/edit?usp=sharing
/**
* Moves row of data to another spreadsheet based on criteria in column 6 to sheet with same name as the value in column 4.
*/
function onEdit(e) {
// see Sheet event objects docs
// https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events
var ss = e.source;
var s = e.range.getSheet();
var r = e.range;
// to let you modify where the action and move columns are in the form responses sheet
var actionCol = 10;
var nameCol = 9;
// Get the row and column of the active cell.
var rowIndex = r.getRowIndex();
var colIndex = r.getColumnIndex();
// Get the number of columns in the active sheet.
// -1 to drop our action/status column
var colNumber = s.getLastColumn()-1;
// if our action/status col is changed to ok do stuff
if (e.value == "ok" && colIndex == actionCol) {
// get our target sheet name - in this example we are using the priority column
var targetSheet = s.getRange(rowIndex, nameCol).getValue();
// if the sheet exists do more stuff
if (ss.getSheetByName(targetSheet)) {
// set our target sheet and target range
var targetSheet = ss.getSheetByName(targetSheet);
var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, colNumber);
// get our source range/row
var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
// new sheets says: 'Cannot cut from form data. Use copy instead.'
sourceRange.copyTo(targetRange);
// ..but we can still delete the row after
s.deleteRow(rowIndex);
// or you might want to keep but note move e.g. r.setValue("moved");
}
}
}
If I understand you correctly, you want to cut & paste the edited row if:
The edited column is G, and the value is a Date corresponding to today.
The corresponding name in column F refers to the name of an existing sheet.
In order to check that the two dates correspond to the same day, you can compare the values returned by getDate(), getMonth() and getFullYear(), as in this function (credits to Pointy):
function sameDay(d1, d2) {
return d1.getFullYear() === d2.getFullYear() &&
d1.getMonth() === d2.getMonth() &&
d1.getDate() === d2.getDate();
}
Then, you can call this in your main function:
function onEdit(e) {
var ss = e.source;
var s = e.range.getSheet();
var r = e.range;
var value = r.getValue();
var actionCol = 7;
var nameCol = 6;
var rowIndex = r.getRow();
var colIndex = r.getColumn();
var colNumber = s.getLastColumn();
if (value instanceof Date && colIndex == actionCol) {
var today = new Date();
if (sameDay(value, today)) {
var targetSheetName = s.getRange(rowIndex, nameCol).getValue();
var targetSheet = ss.getSheetByName(targetSheetName);
if (targetSheet) {
var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1);
sourceRange.copyTo(targetRange);
s.deleteRow(rowIndex);
}
}
}
}
Try it this way:
function onEdit(e) {
var ss = e.source;
var s = e.range.getSheet();
var r = e.range;
var actionCol = 10;
var nameCol = 9;
var rowIndex = r.rowStart;
var colIndex = r.columnStart;
var colNumber = s.getLastColumn()-1;
const dt=new Date(e.range.offset(0,n));//you add the column offset
const dtv=new Date(dt.getFullYear(),dt.getMonth(),dt.getDate()).valueOf();
const td=new Date();
const tdv=new Date(td.getFullYear(),td.getMonth(),td.getDate()).valueOf();
if (e.value == "ok" && colIndex == actionCol && dtv==tdv) {
var targetSheet = s.getRange(rowIndex, nameCol).getValue();
var tSh = ss.getSheetByName(targetSheet);
if (tSh) {
var targetRange = tSh.getRange(tSh.getLastRow()+1, 1, 1, colNumber);
var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
sourceRange.copyTo(targetRange);
s.deleteRow(rowIndex);
}
}
}

Timestamp script copying onto same cell of different sheet

I have a strange script issue I was hoping someone could help me with -- I have 2 different sheets with timestamps that update when the neighboring cell is initialed. The scripts for both sheets are exactly the same (with different sheet names of course) and are not intended to interact, but one of them keeps copying over to the other.
Whenever someone initials/timestamps sheet 1, the script runs successfully on sheet 1 but also updates the same cell on sheet 2. If the cell doesn't exist, extra rows get added to create it. This copying doesn't happen the other way around.
Is there anything I can do to stop this?
Code for sheet 1:
function onEdit(event)
{
var timezone = "PST";
var timestamp_format = "MM-dd-yyyy hh:mm:ss"; // Timestamp Format.
var updateColName = "Initials";
var timeStampColName = "Last Updated";
var sheet = event.source.getSheetByName('WC Labs'); //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;
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);
}
}
Code for sheet 2:
function onEdit(event)
{
var timezone = "EST";
var timestamp_format = "MM-dd-yyyy hh:mm:ss"; // Timestamp Format.
var updateColName = "Initials";
var timeStampColName = "Last Updated";
var sheet = event.source.getSheetByName('EC Labs'); //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;
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);
}
}
Keep things DRY: if there are two functions that do the same thing, you only need one.
getSheet method allows you to get the sheet that contains the currently edited Range - use it to acquire the reference to the currently edited sheet.
Use strict equality comparison (it will not change anything in your case, but builds a useful habit that will save you debugging time).
Exit as early as possible: if statements should handle edge cases, not main logic.
Use the newer V8 runtime (the snippet below uses ES6 syntax).
/**
* #param {{
* range : GoogleAppsScript.Spreadsheet.Range,
* timezone : (string|"PST")
* }} param0
*/
function onEdit({ range, timezone = "PST" }) {
const sheet = range.getSheet();
const timestamp_format = "MM-dd-yyyy hh:mm:ss";
const updateColName = "Initials";
const timeStampColName = "Last Updated";
const editColumn = range.getColumn();
const editIndex = range.getRowIndex();
const [header] = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();
const dateCol = header.indexOf(timeStampColName);
const updateCol = header.indexOf(updateColName) + 1;
if (dateCol < 0 && editIndex <= 1 && editColumn !== updateCol) { return; }
const cell = sheet.getRange(editIndex, dateCol + 1);
const date = Utilities.formatDate(new Date(), timezone, timestamp_format);
cell.setValue(date);
}
References
onEdit event object structure
The onEdit() function in both files is getting event.source.getActiveRange(); as the active range. Since you don't specify a particular sheet, whichever cell you are editing becomes active regardless of which sheet/tab it belongs.
Try to replace this line:
var actRng = event.source.getActiveRange();
in both files with the following:
var actRng = event.source.getSheetByName('WC Labs').getActiveRange();
and
var actRng = event.source.getSheetByName('EC Labs').getActiveRange();
respectively.
Code for sheet 1:
function onEdit(event)
{
var timezone = "PST";
var timestamp_format = "MM-dd-yyyy hh:mm:ss"; // Timestamp Format.
var updateColName = "Initials";
var timeStampColName = "Last Updated";
var sheet = event.source.getSheetByName('WC Labs'); //Name of the sheet where you want to run this script.
var actRng = event.source.getSheetByName('WC Labs').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;
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);
}
}
Code for sheet 2:
function onEdit(event)
{
var timezone = "EST";
var timestamp_format = "MM-dd-yyyy hh:mm:ss"; // Timestamp Format.
var updateColName = "Initials";
var timeStampColName = "Last Updated";
var sheet = event.source.getSheetByName('EC Labs'); //Name of the sheet where you want to run this script.
var actRng = event.source.getSheetByName('EC Labs').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;
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);
}
}

Changing from getActiveCell(); to getting a range instead

This may be fairly simple for you guys.
How to replace getActiveCell() for something I dont need to be online for the script to run, so I can set it up based on a time-trigger?
Check the code block below.
function MoveRows() {
var sheetNameToWatch = "Requests";
var sheetNameToMoveTo = "Approved";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
var range = sheet.getActiveCell();
var row = range.getRow();
if (sheet.getName() == sheetNameToWatch &&
sheet.getRange(row, 8).getValue() == "Y" &&
sheet.getRange(row, 12).getValue() == "Approved") {
{
var targetSheet = ss.getSheetByName(sheetNameToMoveTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
sheet.getRange(range.getRow(), 1, 1,
sheet.getLastColumn()).moveTo(targetRange);
sheet.deleteRow(range.getRow());
}
}}
Thank you!
After looking at your code a bit I'm guessing this maybe close to what your looking for.
function MoveRows() {
var sheetNameToWatch = "Requests";
var sheetNameToMoveTo = "Approved";
var ss = SpreadsheetApp.openById(id)
var sheet = ss.getSheetByName('Requests')
var range = sheet.getRange(sheet.getLastRow(),1,1,sheet.getLastColumn());
var values=range.getValues();
var row = range.getRow();
if (values[0][7] == "Y" && values[0][11] == "Approved") {
var targetSheet = ss.getSheetByName(sheetNameToMoveTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
range.moveTo(targetRange);//you could also just do targetSheet.appendRow(values[0]); Your call
sheet.deleteRow(range.getRow());
}
}