Remove a row from a sheet and copy to another spreadsheet - google-apps-script

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

Related

Create a manual trigger to Import data from same cell in google sheet 1 to new row and cell in google sheet 2 [duplicate]

I'm new to the world of javascript & google apps script and I'm struggling to get a row of data to move from one spreadsheet to another. I have it moving a row from sheet to sheet within the same spreadsheet but not across spreadsheets.
I know I need to use SpreadsheetApp.openById("insertID") rather than SpreadsheetApp.getActiveSpreadsheet() but I can't seem to make it work.
Here is the code I have that's working based on moving sheet to sheet, how do I modify it to move to a new spreadsheet?
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Timeline Submit" && r.getColumn() == 117 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("WIP");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target, {contentsOnly:true});
} else if(s.getName() == "WIP" && r.getColumn() == 117 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getColumn();
var targetSheet = ss.getSheetByName("Timeline Submit");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target, {contentsOnly:true});
}
}
I couldn't figure out everything in the second section of your code but it had too many errors so I just guessed and some of it.
Don't forget to go create a trigger for this in the Script Editor Edits/Current Project Triggers.
function installableOnEdit(e) {
var sh=e.range.getSheet();
if(sh.getName()=="Timeline Submit" && e.range.columnStart==117 && e.value==true) {
var ss=SpreadsheetApp.openById('id')
var tsh= ss.getSheetByName("WIP");
var trg=tsh.getRange(tsh.getLastRow()+1,1);
sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).copyTo(trg,{contentsOnly:true})
}else if(sh.getName()=="WIP" && e.range.columnStart==17 && e.value==false) {
var ss=SpreadsheetApp.openById('id')
var tsh=ss.getSheetByName('Timeline Submit');
var trg=sh.getRange(tsh.getLastRow()+1,1);
sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).copyTo(trg,{contentsOnly:true});
}
}

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

Move a row of data from one spreadsheet to another

I'm new to the world of javascript & google apps script and I'm struggling to get a row of data to move from one spreadsheet to another. I have it moving a row from sheet to sheet within the same spreadsheet but not across spreadsheets.
I know I need to use SpreadsheetApp.openById("insertID") rather than SpreadsheetApp.getActiveSpreadsheet() but I can't seem to make it work.
Here is the code I have that's working based on moving sheet to sheet, how do I modify it to move to a new spreadsheet?
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Timeline Submit" && r.getColumn() == 117 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("WIP");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target, {contentsOnly:true});
} else if(s.getName() == "WIP" && r.getColumn() == 117 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getColumn();
var targetSheet = ss.getSheetByName("Timeline Submit");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target, {contentsOnly:true});
}
}
I couldn't figure out everything in the second section of your code but it had too many errors so I just guessed and some of it.
Don't forget to go create a trigger for this in the Script Editor Edits/Current Project Triggers.
function installableOnEdit(e) {
var sh=e.range.getSheet();
if(sh.getName()=="Timeline Submit" && e.range.columnStart==117 && e.value==true) {
var ss=SpreadsheetApp.openById('id')
var tsh= ss.getSheetByName("WIP");
var trg=tsh.getRange(tsh.getLastRow()+1,1);
sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).copyTo(trg,{contentsOnly:true})
}else if(sh.getName()=="WIP" && e.range.columnStart==17 && e.value==false) {
var ss=SpreadsheetApp.openById('id')
var tsh=ss.getSheetByName('Timeline Submit');
var trg=sh.getRange(tsh.getLastRow()+1,1);
sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).copyTo(trg,{contentsOnly:true});
}
}

Automatically Copy Rows to Another Sheet Based on Cell Value

I'm pretty new to scripts so I apologize for my potential errors in explaining my issue. I'm working on a spreadsheet that will copy a row to another sheet when it meets a certain criteria (or a certain value in a column) and a second function which will move the row to another sheet upon meeting a certain criteria.
Using related questions/answers, I was able to write a script that deletes a row upon meeting criteria "Outbound" in column 4, see myFunction1 below. For myFunction2, I'm trying to instead just copy the row to another sheet when it meets criteria "M" in column 15, but when I enter that value in column 15 it copies the wrong row information.
Hopefully that makes sense! Code below:
function onEdit(event) {
myFunction1(event);
myFunction2(event);
}
function myFunction1(event){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Trailers in Yard" && r.getColumn() == 4 && r.getValue() == "Outbound") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Outbound");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
function myFunction2(event){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Trailers in Yard" && r.getColumn() == 15 && r.getValue() == "M") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Moves");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
}
}
Appreciate the assistance!
Try it this way:
function onEdit(e) {
//myFunction1(e);
myFunction2(e);
}
function myFunction2(e){
//e.source.toast('Flag1');
var sh=e.range.getSheet();
if(sh.getName()=="Sheet2" && e.range.columnStart==15 && e.range.getValue()=="M") {
//e.source.toast('Flag2');
var targetSheet=e.source.getSheetByName("Sheet1");
var target=targetSheet.getRange(targetSheet.getLastRow()+1,1);
sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).copyTo(target);
}
}
You'll have to change the sheet names.

Can't get getActiveSheet() from undefined

I'm trying to copy a row from sheet "Name1" to sheet "Name2" when entering "ok" in cell 1 (column 1) but I couldn't fix this error in the title (Cannot call method "getActiveSheet" from undefined). I have tried all those commented lines but no luck, I'm editing the cell and enter "ok" in that cell but not working.
function onEdit2(e) {
//var ss = SpreadsheetApp.getActiveSpreadsheet();
var ss = e.source;
//var s = SpreadsheetApp.openById("1yAJY3gO46A7Wr_fYtVHAB_wSElUdG2kkiH1clRg9o8k").getSheetByName('Name1');
var s = ss.getActiveSheet();
var r = e.source.getActiveRange();
if(s.getName() == "Name1" && r.getColumn() == 1 && r.getValue() == "ok") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Name2");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
the error I'm getting is
TypeError: Can not call method "getActiveSheet" from undefined. (Row 135).
I edited those first lines to those
var ss = SpreadsheetApp.getActiveSpreadsheet();
// var ss = e.source;
//var s = SpreadsheetApp.openById("1yAJY3gO46A7Wr_fYtVHAB_wSElUdG2kkiH1clRg8o9k").getSheetByName('Lista');
var s = ss.getActiveSheet();
var r = e.source.getActiveRange(); // I get error now here can't call getactiverange from undefined .
At this line:
var targetSheet = s.getSheetByName("Name2");
You're running the getSheetByName() on the Sheet and it needs to run on the Spreadsheet to be able to get the other Sheet Name2 , so just change that line to:
var targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Name2");
Also rename your function from onEdit2() to the reserved function name onEdit() so it gets triggered, or create an Installable Trigger
Your function should look like this:
function onEdit(e) {
var ss = e.source;
var s = ss.getActiveSheet();
var r = e.source.getActiveRange();
if(s.getName() == "Name1" && r.getColumn() == 1 && r.getValue() == "ok") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Name2"); // Changed
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I created an example Spreadsheet here.
When a sheet is edited, the function onEdit() is called, not onEdit2(). onEdit2 seems to be your custom function, so you must be calling that yourself from somewhere else. (maybe from within onEdit()?). If so, are you passing the event object e while calling it? (You have to call it like this:
onEdit2(e);
If you're not passing the parameter e, then you will get the error you're seeing, since ss will be undefined.
ref: GAS-trigger-events