Modify Code - Copy Range to another Spreadsheet Google Sheets - google-apps-script

The code below copies range and moves to next Spreadsheet in same workbook called "Topup Required".
I would like it to send this data to another spreadsheet inside another workbook instead.
function onEdit(event) {
// assumes source data in sheet named PrepSheet
// target sheet of move to named TOP UP NEEDED
// getColumn with check-boxes is currently set to column I
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "PrepSheet" && r.getColumn() == 9 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("TOP UP NEEDED");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
}
}
I tried replacing
var targetSheet = ss.getSheetByName("TOP UP NEEDED");
with
var targetSheet = SpreadsheetApp.openById("sheet ID").getSheetByName("TOP UP NEEDED");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
but it didnt work
Could anyone tell me where i went wrong
Thanks

You want to copy the values and format from s.getRange(row, 1, 1, numColumns) to the last row on the sheet of TOP UP NEEDED in the Spreadsheet of sheet ID, when the cell is edited.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification point:
Unfortunately, in the current stage, copyTo() of Class range cannot be used for other Spreadsheet.
Pattern 1:
In this pattern, copyTo() is used. So both the values and the cell format are copied.
Modified script:
When your script is modified, please modify as follows.
From:
var targetSheet = ss.getSheetByName("TOP UP NEEDED");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
To:
var targetSS = SpreadsheetApp.openById("sheet ID");
s = SpreadsheetApp.getActiveSheet();
var tempSheet = s.copyTo(targetSS);
var targetSheet = targetSS.getSheetByName("TOP UP NEEDED");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
tempSheet.getRange(row, 1, 1, numColumns).copyTo(target);
targetSS.deleteSheet(tempSheet);
Pattern 2:
In this pattern, getValues() and appendRow() are used. So only the values are copied.
Modified script:
When your script is modified, please modify as follows.
From:
var targetSheet = ss.getSheetByName("TOP UP NEEDED");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
To:
var targetSheet = SpreadsheetApp.openById("sheet ID").getSheetByName("TOP UP NEEDED");
var sourceValues = s.getRange(row, 1, 1, numColumns).getValues()[0];
targetSheet.appendRow(sourceValues);
Note: IMPORTANT
In this modification, the simple trigger of onEdit() cannot be used. An error occurs at openById(). So please use the installable trigger of OnEdit event trigger. In this case, please modify the function name as follows.
From
function onEdit(event) {
To
function installedOnEdit(event) {
After this modification, please install the OnEdit event trigger to installedOnEdit as the installable trigger. By this, when the cell is edited, installedOnEdit is run without the double executions. Please be careful this.
References:
copyTo(destination) of Class Range
copyTo(spreadsheet) of Class Sheet
getValues()
appendRow(rowContents)
Simple Triggers
Installable Triggers
If I misunderstood your question and this was not the direction you want, I apologize.

Related

Is there a way for me to use the 1st cell of a row as a getsheetbyname parameter in google sheet?

function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Sheet1" && r.getColumn() == 3 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("id1");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
// s.deleteRow(row);
}
}
This is the code so far and I was wondering if there was a way for me to automatically append all of the row or "id" to their specific tab if their checkbox have been checked using the 1st cell of the row as the parameter for the getsheetbyname?
I tried to create a variable and put it in the getSheetByName() like the example below but it didn't work. I'm very new to javascript/apps script.
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Sheet253" && r.getColumn() == 2 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var a = row[0];
var targetSheet = ss.getSheetByName(a);
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
// s.deleteRow(row);
}
}
This is an example of the google sheet:
https://docs.google.com/spreadsheets/d/19TzSKyY4616sWpY2ONPj01F5CJDfsTJ7DmbFXPVKvJE/edit?usp=sharing
The result should look like the result in tab id1.
Modification points:
In your script, I thought that the event object can be used.
In your sample Spreadsheet, it seems that the checkbox is put to the column "C". When you want to run the script, when the checkbox is checked, the checked column is the column "C".
When these points are reflected in your script, how about the following modification?
Modified script:
From your provided sample Spreadsheet, this script supposes that the source sheet name is "Sheet1". Please be careful about this.
function onEdit(event) {
var ss = event.source;
var s = ss.getActiveSheet();
var r = event.range;
if (s.getName() == "Sheet1" && r.columnStart == 3 && r.isChecked()) {
var sheetName = r.offset(0, -2).getValue();
var targetSheet = ss.getSheetByName(sheetName);
if (!targetSheet) {
Browser.msgBox(`"${sheetName}" was not found.`);
return;
}
var row = r.rowStart;
var numColumns = s.getLastColumn();
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
// s.deleteRow(row);
}
}
In this script, when the checkbox of the column "C" of "Sheet1" is checked, the row is copied.
Note:
In your showing script, the edited row is used. So I modified your script by following your showing script. But, about This is the code so far and I was wondering if there was a way for me to automatically append all of the row or "id" to their specific tab if their checkbox has been checked using the 1st cell of the row as the parameter for the getsheetbyname?, if you want to copy all rows by one execution of the script, how about the following sample script? When this script is run, the checkboxes of column "C" of "Sheet1" are checked, and each value are copied to each sheet using the values of column "A".
function sample() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const srcSheet = ss.getSheetByName("Sheet1");
const obj = srcSheet.getRange("A2:C" + srcSheet.getLastRow()).getValues().reduce((o, r) => {
if (r[2] === true) {
o[r[0]] = o[r[0]] ? [...o[r[0]], r] : [r];
}
return o;
}, {});
Object.entries(obj).forEach(([name, values]) => {
const sheet = ss.getSheetByName(name);
const range = sheet.getRange(sheet.getLastRow() + 1, 1, values.length, values[0].length);
range.setValues(values).offset(0, 2, values.length, 1).insertCheckboxes();
});
}
Note:
This sample script is for your provided sample Spreadsheet. So, when you change the structure of the Spreadsheet, the script might not be able to be used. So, please be careful about this.
References:
Event Objects
getValues()
setValues(values)

Write remotely to another googlesheet

I have the function below I have copied from somewhere else. It basically moves a row you would have completed to another sheet in the same file (moves from sheet Origin to Target, Trigger is "Move").
What I would like to achieve is to be able to move that completed row to another google sheet file instead of another sheet in the same file. I have tried SpreadsheetApp.openByUrl and SpreadsheetApp.openByID, but nothing happens, I was expecting some permission request etc. but nothing, not even an error.
Can someone help me with this?
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Origin" && r.getColumn() == 10 && r.getValue() == "Move") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Target");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, (numColumns-1)).moveTo(target);
s.deleteRow(row);
}
I believe your goal as follows.
You want to copy the values of s.getRange(row, 1, 1, (numColumns-1)) to the last row of Target sheet in other Spreadsheet.
You want to run the script by OnEdit event trigger.
For this, how about this answer?
Modification points:
In order to use SpreadsheetApp.openByUrl and SpreadsheetApp.openByID, it is required to use the installable OnEdit event trigger instead of the simple trigger of OnEdit event trigger. When SpreadsheetApp.openByUrl and SpreadsheetApp.openByID are run with the simple trigger, an error related to the permission occurs.
I think that the reason of your issue is this.
When the values are moved to other Spreadsheet, move() cannot be used. So in this case, getValues and setValues are used.
When above points are reflected to your script, it becomes as follows.
Modified script:
Please copy and paste the following script. And, please install the OnEdit event trigger to the function of installedOnEdit as the installable trigger. By this, when the cell is edited, SpreadsheetApp.openById is run.
function installedOnEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Origin" && r.getColumn() == 10 && r.getValue() == "Move") {
var id = "###"; // Please set the Spreadsheet ID.
var dst = SpreadsheetApp.openById(id);
var targetSheet = dst.getSheetByName("Target");
var row = r.getRow();
var numColumns = s.getLastColumn();
var srcRange = s.getRange(row, 1, 1, (numColumns-1));
s.deleteRow(row);
targetSheet.getRange(targetSheet.getLastRow() + 1, 1, 1, numColumns - 1).setValues(srcRange.getValues());
}
}
References:
Simple Triggers
Installable Triggers

Auto Sort Data Moved by Script

My issue is, I have data being moved from one Sheet to another via script when marked "Complete". In the "Completed" sheet is where I want to sort the data. I already have an Autosort script that works only when debugging, not even on edit (tried editing everywhere), Let alone when data is moved to the sheet.
I want to be able to Auto sort whenever data is moved to the new sheet (I don't think its an onEdit function?)
I am not a programmer and I'm fairly new to Google Apps Script. I just dabble into code once in a while because I find it interesting, so I don't even know where to start to get the results I'm looking for.
This is the Auto Sort,
function AutoSortOnEdit() {
var sheetNames = ["Complete"];
var ss = SpreadsheetApp.getActiveSpreadsheet();
sheetNames.forEach(function(name) {
var sheet = ss.getSheetByName(name);
var range = sheet.getRange(4, 1, sheet.getLastRow() - 1,
sheet.getLastColumn());
range.sort({column: 2, ascending: true});
});
}
EDIT: I realized I was using a script for multiple sheets. I changed it for one sheet, same issues though.
function AutoSortOnEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Completed Returns");
var range = sheet.getRange(4, 1, sheet.getLastRow() - 1,
sheet.getLastColumn());
range.sort({column: 2, ascending: true});
}
Any help would be greatly appreciated!
I managed to get it working by throwing the 2 scripts together under 1 function like so. I could not figure out how to get the event function to run while calling multiple functions, so I just combined them. Above the 2 "}" brackets is the move Script and below them is the Auto sort.
function onEdit(e) {
var ss = e.source;
var s = ss.getActiveSheet();
var r = e.range;
var actionCol = 24;
var nameCol = 24;
var rowIndex = r.getRowIndex();
var colIndex = r.getColumnIndex();
var colNumber = s.getLastColumn();
if (e.value == "TRUE" && colIndex == actionCol) {
var targetSheet = ss.getSheetByName("Completed Returns");
if (ss.getSheetByName("Completed Returns")) {
var targetSheet = ss.getSheetByName("Completed Returns");
var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, colNumber);
var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
sourceRange.copyTo(targetRange);
s.deleteRow(rowIndex);
}
}
var sheet = ss.getSheetByName("Completed Returns");
var range = sheet.getRange(4, 1, sheet.getLastRow() - 1, sheet.getLastColumn());
range.sort({column: 2, ascending: true});
}
Thanks Everyone for the response!
You can add your function to one another
function AutoSortOnEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Completed Returns');
var range = sheet.getRange(
4,
1,
sheet.getLastRow() - 1,
sheet.getLastColumn()
);
range.sort({ column: 2, ascending: true });
}
function copyData() {}
function userActionRun() {
copyData();
AutoSortOnEdit();
}
At now you can bind it ti EDIT event
function onEdit(){
userActionRun();
}
You can use the Sort function to sort a data-set.
If you have a function that moves data form one sheet to another when the row is marked as complete, then you can add a line at the end of that to sort it.
You could also create a FilterView that sorts the whole sheet based on your parameters. Unlike Filters, FilterViews are saved between sessions.

Google Sheet Copy Row to New Sheet IF Formula Trigger

I'm trying to use a pretty standard copy row from one sheet to another sheet code when Column B shows 'Start', but Column B has the following formula in it:
=IF(A2 = "Complete","Start","Not Yet")
and this code doesn't seem to recognize the formula changing from 'Not Yet' to Start'. Any help would be greatly appreciated. Thanks!
function onEdit(event) {
// assumes source data in sheet named Needed
// target sheet of move to named Acquired
// test column with yes/no is col 4 or D
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Temp" && r.getColumn() == 1 && r.getValue() == "Complete") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Start");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
The issue is not that it does not "recognize" the formula changing value. If you look at your formula again after it is copied you should notice that the reference changes from A2 to Temp!A2.
moveTo works like if you individually cut-n-paste each cell into their new operation. This results in this "maintaining" of the reference to their original cells.
If this is not desired, maybe you should switch to copyTo. Which might have other side effects in your formulas. But should work fine for this simple one you exemplified.
s.getRange(row, 1, 1, numColumns).copyTo(target); //try copyTo here

Google Sheets: Row not copying to another sheet

I have two sheets. Pipeline and Archive. I also have a data validation list on column 5 that switches from blank to Yes only. When I debug it, it doesn't throw an error. But when I go to my sheet and change column 5 to yes, it doesn't move to the Archive sheet, nor does it delete anything.
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var c = s.getActiveCell();
if (s.getName() == "Pipeline" && c.getColumn() == 5 && c.getValue() == "Yes") {
var targetSheet = ss.getSheetByName("Archive");
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(c.getRow(), 1, 1, sheet.getLastColumn()).copyTo(targetRange, {contentsOnly:true});
s.deleteRow(c.getRow());
}
}
Change:
s.getRange(c.getRow(), 1, 1, sheet.getLastColumn()).copyTo(targetRange, {contentsOnly:true});
s.deleteRow(c.getRow());
To:
s.getRange(c.getRow(), 1, 1, s.getLastColumn()).copyTo(targetRange, {contentsOnly:true});
s.deleteRow(c.getRow());
Hopefully this appeases the PTB...