Google script for move rows depending on checkbox - Google sheet - google-apps-script

I've got a script that moves a row from one tab "COMMUNICATIONS" to another tab "ARCHIVE" when a cell checkbox (column AE) is true but it's only working well with the row AE2 and it's not working when I check AE3 or AE6.
function onEdit() {
var sheetNameToWatch = "COMMUNICATIONS";
var sheetNameToMoveTheRowTo = "ARCHIVE";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName(sheetNameToWatch);
var sheet2 = ss.getSheetByName(sheetNameToMoveTheRowTo);
var cell1 = sheet1.getRange("AE2:AE1000");
var x= cell1.getValue();
Logger.log("a",x);
if(cell1.getValue()== false) {
Logger.log("box not checked");
sheet1.showSheet();
} else if (cell1.getValue() == true) {
var targetSheet = ss.getSheetByName(sheetNameToMoveTheRowTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
sheet.getRange(range.getRow(), 1, 1,
sheet.getLastColumn()).moveTo(targetRange);
sheet.deleteRow(range.getRow());
}
}

you can try this code. I Tested it on one of my sheets and it worked fine.
function onEdit(event) {
// assumes source data in sheet named Active
// target sheet of move to named Found
// test column with yes/no is col 13 or M
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "COMMUNICATIONS" && r.getColumn() == 13 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("ARCHIVE");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}

Related

Remove a row from a sheet and copy to another spreadsheet

I have managed to remove a row and place in a sheet within the same Google spreadsheet. However when I modify the script to copy a row onto a different sheet, nothing happens:
function onEdit(event) {
var ss =SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "CONTRACT REGISTRY DOCUMENT" && r.getColumn() == 58 && r.getValue() == "X") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var destination = SpreadsheetApp.openById('...');
var targetSheet = destination.getSheetByName("NOT RENEWED");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
The moveTo method can only move data within the same spreadsheet. It is best practice to use range.getValues() and range.setValues() to achieve the same behavior in different spreadsheets.
function onEdit(event) {
var ss =SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "CONTRACT REGISTRY DOCUMENT" && r.getColumn() == 58 && r.getValue() == "X") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var data = r.getValues();
// please supply the destination file ID as parameter here
var destination = SpreadsheetApp.openById('...');
var targetSheet = destination.getSheetByName("NOT RENEWED");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
target.setValues(data);
s.deleteRow(row);
}
}
It seems the problem here is that you're trying to access another file from your trigger (onEdit), but that is not possible because it'd require permission to change another spreadsheet: https://developers.google.com/apps-script/guides/triggers#restrictions
According to a related question, an installable trigger is the way to go here.
In this case, you need to add something like this to your code and run it to create the trigger:
function createSpreadsheetOnEditTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('moveRowToAnotherSheet')
.forSpreadsheet(ss)
.onEdit()
.create();
}
Based on this trigger, it is necessary to make a few changes to the original code you posted:
function moveRowToAnotherSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet(); // Changed
var r = s.getActiveRange(); // Changed
if(s.getName() == "CONTRACT REGISTRY DOCUMENT" && r.getColumn() == 58 && r.getValue() == "X") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var destination = SpreadsheetApp.openById('...');
var targetSheet = destination.getSheetByName("NOT RENEWED");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1, 1, targetSheet.getLastColumn()); // Changed
target.setValues(s.getRange(row, 1, 1, numColumns).getValues()); // Added to use setValues instead of moveTo
s.deleteRow(row);
}
}

Both Google Sheets scripts work, but don't work when both added

I have 2 different scripts, the first one copies the row when I select the name of the sheet from the drop down list and pastes it on the sheet with that name, the second script is a checkbox that when ticked then copies the entire row to another sheet and deletes it from the original sheet. So after I have first selected the option from the dropdown menu and then ticked the checkbox that row should be copied to 2 different sheets.
My trouble is that although both these scripts work when they're on their own, they don't work when I have them both.
Script 1
function onEdit(e) {
var sh=e.range.getSheet();
if(sh.getName()=='Approval' && e.range.columnStart==11) {
var v=sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).getValues();
var tsh=e.source.getSheetByName(e.value);
if(tsh) {
tsh.getRange(tsh.getLastRow() + 1,1,1,v[0].length).setValues(v);
}
}
}
Script 2
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Approval" && r.getColumn() == 12 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("ZSD Sheet");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I've looked at script merging but it's going waaaaaaay over my head so any help is hugely appreciated.
You can't have two or more onEdit() triggers. But you can do the following simple workaround. Add the following function to your scripts:
function onEdit(e) {
onEdit1(e)
onEdit2(e)
}
and then, modify your scripts as follows:
Script 1:
function onEdit1(e) {
var sh=e.range.getSheet();
if(sh.getName()=='Approval' && e.range.columnStart==11) {
var v=sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).getValues();
var tsh=e.source.getSheetByName(e.value);
if(tsh) {
tsh.getRange(tsh.getLastRow() + 1,1,1,v[0].length).setValues(v);
}
}
}
Script 2:
function onEdit2(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Approval" && r.getColumn() == 12 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("ZSD Sheet");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}

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());
}
}

Moving row from one sheet to another does not work with ARRAYFORMULA

I use the script below to move data from sheet (Invoice_Info) to (Invoice_Archive) when cell value ="Save" in column 20 in sheet (Invoice_Archive) I put arrayformula in column 21.
The problem is:
when the data is moved to sheet (Invoice_Archive) it's put at the end of sheet
when I remove the ARRAYFORMULA the script works well
What should I do to work script with arrayformula?
function onEdit() {
var sheetNameToWatch1 = "Invoice_Info";
var columnNumberToWatch = 20;
var valueToWatch = "Save";
var sheetNameToMoveTheRowTo = "Invoice_Archive";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
if ( (sheet.getName() == sheetNameToWatch1) && range.getColumn() == columnNumberToWatch && range.getValue() == valueToWatch) {
var targetSheet = ss.getSheetByName(sheetNameToMoveTheRowTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
sheet.getRange(range.getRow(), 1, 1, 20).copyTo(targetRange, {contentsOnly:true});
sheet.deleteRow(range.getRow());
}
}
I believe your issue is with getLastRow in the targetsheet. The arrayformula is causing the row to be wrong. Try gstting the last row of column a with data loke this:
function onEdit() {
var sheetNameToWatch1 = "Invoice_Info";
var columnNumberToWatch = 20;
var valueToWatch = "Save";
var sheetNameToMoveTheRowTo = "Invoice_Archive";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
if ( (sheet.getName() == sheetNameToWatch1) && range.getColumn() == columnNumberToWatch && range.getValue() == valueToWatch) {
var targetSheet = ss.getSheetByName(sheetNameToMoveTheRowTo);
var Avals= targetSheet.getRange("A1:A").getValues()
var Alast = Avals.filter(String).length;
var targetRange = targetSheet.getRange(Alast + 1, 1);
sheet.getRange(range.getRow(), 1, 1, 20).copyTo(targetRange, {contentsOnly:true});
sheet.deleteRow(range.getRow());
}
}

The coordinates of the target range are outside the dimensions of the sheet

I use this code and while in the past it worked well, today I received this error message:
The coordinates of the target range are outside the dimensions of the sheet. (line 27, ___.gs)
My code is not too complex:
function onEdit() {
var sheetNameToWatch1 = "Assign_Page";
var columnNumberToWatch = 19;
var valueToWatch = "Delivred";
var sheetNameToMoveTheRowTo = "K_Delivery_Archive";
var sheetNameToMoveTheRowTo2 = "Buffering";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
if (sheet.getName() == sheetNameToWatch1 && range.getColumn() == columnNumberToWatch && range.getValue() == valueToWatch) {
var targetSheet = ss.getSheetByName(sheetNameToMoveTheRowTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
sheet.getRange(range.getRow(), 1, 1, 22).copyTo(targetRange, {contentsOnly: true});
var targetSheet2 = ss.getSheetByName(sheetNameToMoveTheRowTo2);
var targetRange2 = targetSheet2.getRange(targetSheet2.getLastRow() + 1, 1);
sheet.getRange(range.getRow(), 1, 1, 22).copyTo(targetRange2, {contentsOnly: true});
sheet.deleteRow(range.getRow()); // line 27
var Sheet1 = ss.getSheetByName("Clients_Page");
var Sheet2 = ss.getSheetByName("Assign_Page");
var Sheet3 = ss.getSheetByName("Report");
var Sheet4 = ss.getSheetByName("Delivery_Information");
Sheet4.showSheet();
Sheet1.hideSheet();
Sheet2.hideSheet();
Sheet3.hideSheet();
}
}
What causes this error, and how can I resolve it?
It's very likely that the problem is due to
targetSheet2.getLastRow()+ 1
The proper solution will depend on several factors that are not mentioned by the OP, but here is a hint:
If the sheet has open ended formulas that return "" then the last row is the same as the maximum number of rows in the sheet and inserting more rows will not solve the problem.