This is my first Google Script and I am coming from a VBA background so I have likely missed something obvious. I am attempting to copy from one sheet to another, some that is quite simple in VBA, but I am struggling with it and I dont understand what I am missing
The below code I would have though would copy a range in one sheet to another sheet. Not the whole range, just a section of it and only 1 row per an OnEdit()
I checked the ranges I am wanting to copy from and copy to using targetSheet.getRange(targetSheet.get1stNonEmptyRowFromBottom(1) + 1, 1,1,numColumns-1).activate(); & sheet.getRange(row, 1, 1, numColumns-1).activate(); and it selects the range I would expect
Currently the execution doesn't show any fails either
function onEdit(e) {
//This is sheet we will be copied to
const VALUE = ["LEAD","LANDSCAPE"];
//This is the column for the check box
const COLUMN_NUMBER = 25
//The main sheet that is being copied from
const MAIN_SHEET = 'Form Responses 1'
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var lead_or_landscape = sheet.getRange(row,20).getValue();
//This is so we dont run this by mistake on another cell edit or sheet
if((COLUMN_NUMBER == cell.getColumn() && MAIN_SHEET == sheet.getName && cell.isChecked() == true)
&& (lead_or_landscape == VALUE[0] || lead_or_landscape == VALUE[1])){
//copies row from current sheet to the specificed sheet (Lead or landscape)
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName(lead_or_landscape);
var target = targetSheet.getRange(targetSheet.get1stNonEmptyRowFromBottom(1) + 1, 1,1,numColumns-1);
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target());
}
}
Object.prototype.get1stNonEmptyRowFromBottom = function (columnNumber, offsetRow = 1) {
const search = this.getRange(offsetRow, columnNumber, this.getMaxRows()).createTextFinder(".").useRegularExpression(true).findPrevious();
return search ? search.getRow() : offsetRow;
};
You've to use parentheses in sheet.getName() and not use them in copyTo(target())
And you can use sheet.appendRow() method instead of copyTo(), that is easier.
function onEdit(e) {
//This is sheet we will be copied to
const sheets = ["LEAD","LANDSCAPE"];
//This is the column for the check box
const colNumber = 25;
//The main sheet that is being copied from
const mainSheet = 'Form Responses 1';
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var leadOrLandscape = sheet.getRange(row,20).getValue();
//This is so we dont run this by mistake on another cell edit or sheet
if(colNumber == cell.getColumn()
&& mainSheet == sheet.getName()
&& cell.isChecked() == true
&& sheets.includes(leadOrLandscape)){
//copies row from current sheet to the specificed sheet (Lead or landscape)
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName(leadOrLandscape);
targetSheet.appendRow(sheet.getRange(row, 1, 1, numColumns-1).getValues()[0])
}
}
I just took a quick look at your code, are you sure about this line?
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target());
it shouldn't rather be
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target);
Related
For starters, I am a complete beginner at using Apps Scripts for Google Sheets at my new workplace, and we do not have an IT department who can help us create this file. I am trying to create a shared file that can be accessed by our client, our service technicians, and our main office simultaneously, so I opted to create a Google Sheet.
I am hoping to automate this process to prevent users (except myself) from needing to manually edit, move and sort data across multiple sheets that might cause the file to break or become inconsistent. For this to work, I need users to only be able to create entries in our 'main' worksheet and only view the other sheets. From here, I'd like to automate the file to move rows to specific sheets named after each unit when it's marked "DONE", and also organize each unit's sheet by the date column. Our intention is for these sheets to provide us with a running history of all the work that has been done each unit.
NOTE: I have 54 units and counting and I currently will have to copy & paste the code multiple times and edit each one to match the unit numbers. I currently have a one unit set-up, but I think there's something wrong with the code or the triggers I have set-up as it does not automatically sort the destination sheet. Either way, I think there has to be a simpler way to do this.
Any advice would be appreciated!
Here's the code that I've used thus far:
function trailer27() {
// moves a row from a sheet to another when a magic value is entered in a column
// adjust the following variables to fit your needs
// see https://productforums.google.com/d/topic/docs/ehoCZjFPBao/discussion
var sheetNameToWatch = "WORKSHEET";
var columnNumberToWatch = 6;2 // column A = 1, B = 2, etc.
var valueToWatch = "Yes";"27"
var sheetNameToMoveTheRowTo = "27"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
if (sheet.getName() == sheetNameToWatch && 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, sheet.getLastColumn()).moveTo(targetRange);
sheet.deleteRow(range.getRow());
SpreadsheetApp.flush()
}
}
function Sort27() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("27")
var range = sheet.getRange("A3:F1000");
// Sorts by the values in column 1 (J)
range.sort({column: 1, descending: false});
}
function SortWorksheet(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("WORKSHEET")
var range = sheet.getRange("A3:F1000");
// Sorts by the values in column 10 (J)
range.sort({column: 1, descending: false});
}
function undoMove() {
// moves a row from a sheet to another when a magic value is entered in a column
// adjust the following variables to fit your needs
// see https://productforums.google.com/d/topic/docs/ehoCZjFPBao/discussion
var sheetNameToWatch = "27"
var columnNumberToWatch = 6; // column A = 1, B = 2, etc.
var valueToWatch = "CALLED"; "EMAIL"
var sheetNameToMoveTheRowTo = "WORKSHEET";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
if (sheet.getName() == sheetNameToWatch && 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, sheet.getLastColumn()).moveTo(targetRange);
sheet.deleteRow(range.getRow());
SpreadsheetApp.flush()
}
}
If this is meant to be an onEdit function it's worth using the event object even considering the difficulty in debugging
function trailer27(e) {
const sheet = e.range.getSheet();
var sheetNameToWatch = "WORKSHEET";
var columnNumberToWatch = 6; 2 // column A = 1, B = 2, etc.
var valueToWatch = "Yes"; "27"
var sheetNameToMoveTheRowTo = "27"
if (sheet.getName() == sheetNameToWatch && e.range.columnStart == columnNumberToWatch && e.value == valueToWatch) {
var targetSheet = e.source.getSheetByName(sheetNameToMoveTheRowTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
sheet.getRange(e.range.rowStart, 1, 1, sheet.getLastColumn()).moveTo(targetRange);
sheet.deleteRow(e.range.rowStart);
SpreadsheetApp.flush();
}
}
I have a script for archiving rows into one tab to another tab based on cell edit within the same spreadsheet. However the size of the sheet is getting very large resulting in slow page load. I was just wondering, as I'm not too experienced in scripts, if it were to possible to "archive" rows into a completely separate google sheet (new URL).
Note: At the moment, if you change Column 6 cell value to "Archive" it sends from one sheet ("Content Production Master") to another sheet ("Content Archive").
See code below for what I've got at the moment - any help would be very useful!
// assumes source data in sheet named Content Production Master
// target sheet of move to named Content Archive
// test column with "Archive" is col6
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Content Production Master" && r.getColumn() == 6 && r.getValue() == "Archive") {
var row = r.getRow();
var lastRow = r.getLastRow(); //Save the last edited row index
var numColumns = s.getLastColumn();
var numRows = lastRow-row + 1; // Corrected this calculation
var targetSheet = ss.getSheetByName("Content Archive");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
//s.getRange(row, 1, 1, numColumns).moveTo(target);
s.getRange(row, 1, numRows, numColumns).moveTo(target); // Take in account the lastRow when archiving the edited range.
//s.deleteRow(row);
for (let i = row; i<=lastRow; i++) {
s.deleteRow(row);
console.log(`Deleted row ${row} at pass number ${i}`);
}
}
}
Since it is not possible to move data from your source sheet to a different spreadsheet using move(target). You can manually get the data to be moved and paste that to another spreadsheet using getValues() and setValues(values).
Sample Code:
function onEdit(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var r = ss.getActiveRange();
if(s.getName() == "Content Production Master" && r.getColumn() == 6 && r.getValue() == "Archive") {
//var targetSs = SpreadsheetApp.openById('1xh0huhm7ghGP7Y_5jNSFh7eaNX4iVoOL4SY95IWqpfs');
var targetSs = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1xh0huhm7ghGP7Y_5jNSFh7eaNX4iVoOL4SY95IWqpfs/edit?resourcekey=0-j6u0gdSEBp-F9SZYlZYi1g#gid=93990300');
var targetSheet = targetSs.getSheetByName("Content Archive");
var row = r.getRow();
var lastRow = r.getLastRow(); //Save the last edited row index
var numColumns = s.getLastColumn();
var numRows = lastRow-row + 1; // Corrected this calculation
//Get data to be moved
var data = s.getRange(row, 1, numRows, numColumns).getValues();
//Paste the values to the target sheet on another spreadsheet
targetSheet.getRange(targetSheet.getLastRow()+1,1,data.length,data[0].length).setValues(data);
//Delete data in the source sheet
s.deleteRows(row, numRows);
}
}
Pre-requisite(use installable onEdit trigger):
What it does?
After checking if the modified cell is in column 6 with value "Archive". Open the target spreadsheet using either openByUrl(url) or openById(id). Then select the target sheet.
Get the row values of the range to be moved using getValues()
Write the values to your target sheet using setValues(values)
Delete the archived rows in your source sheet using deleteRows(rowPosition, howMany)
Output:
Source Sheet (Before)
Source Sheet (After)
Target Sheet (After)
I'm a beginner in coding and on SO, but I'm trying to understand what I'm doing and what is happening in the code.
I'm wanting to move a row between different spreadsheets.
I have a script in "CORE" Spreadsheet, which moves a row between the "Home" and "Finished" sheets Link to the spreadsheet:
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if (s.getName() == "Home" && r.getColumn() == 5 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Finished");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
else if (s.getName() == "Finished" && r.getColumn() == 5 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Home");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I searched how to move the data located on "Finished" sheet to another spreedsheet called "DATA BASE" Link to the spreadsheet:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Finished");
var range = sheet.getRange("A1:E2");
var values = range.getValues();
var allvals = [];
for (var i = 0; i < values.length; i++) {
allvals.push(values[i]) ;
}
var dataLength = allvals.length;
// alert data
var ui = SpreadsheetApp.getUi();
// ui.alert( JSON.stringify(allvals) )
// copy to another Google Spreadsheet
var newSheet = SpreadsheetApp.openById('1Xn-hrPPr3tQwWMbKdWxHTXcazOqWu1bdHT6A5LZmlD8').getSheets()[0];
var tmp = "A1:E" + dataLength;
var newRange = newSheet.getRange(tmp);
newRange.setValues(values);
}
But I want to transfer the data from sheet "CORE"/"Finished" to sheet "DATA BASE"/ "DB" without rewriting the other rows already on the DB sheet. My idea is to make the spreadsheet "DATA BASE" a real database, where other sheets put data in it and other sheets use this data.
Is it possible to move rows between different spreadsheets like in the first code? I know its impossible to use the .openById() with the function onEdit(), but the most important thing is to move the rows without rewriting the other rows already in the target sheet (DB).
Moving a row to another spreadsheet with installable onEdit trigger
This is just an example of moving the data in a row from one spreadsheet to another with an installable onEdit Trigger. If you wish to play with it don't forget to add the target spreadsheet id.
function onMyEdit(e) {
//e.source.toast('Entry');
var sh=e.range.getSheet();
//Logger.log(JSON.stringify(e));
if(sh.getName()=='Sheet2' && e.range.columnStart==11 && e.value=="TRUE") {
//e.source.toast('Access');
e.range.setValue('FALSE');
var tss=SpreadsheetApp.openById('SSID');
var tsh=tss.getSheetByName('Sheet2');
var v=sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()-1).getValues();
Logger.log(v);
tsh.getRange(tsh.getLastRow()+1,1,v.length,v[0].length).setValues(v);
sh.deleteRow(e.range.rowStart);
}
}
I have been asked to create a live Google Sheets Spreadsheet to track the work schedule at our yard. I have no experience with a script but found out I could program my sheet instead of hiding formulas and it would yield a cleaner result. I have been able to make the sheet organize itself and I was able to make it Archive manually (onEdit). What I'm looking for is to have it automatically run the code at 1 am so when we arrive at work it archives based on a cell value in a certain column.
This is an example of my onEdit script that works, but when someone is trying to check off the "YES" column there is some lag and can cause the wrong cell to be checked, which I then manually correct.
function onEdit() {
var sheetNameToWatch = "Schedule";
var columnNumberToWatch = 28;
var valueToWatch = "Yes";
var sheetNameToMoveTheRowTo = "Archive";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
if (sheet.getName() == sheetNameToWatch && 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, sheet.getLastColumn()).moveTo(targetRange);
sheet.deleteRow(range.getRow());
}
}
So this code runs at 100% failure but saves and executes, and I honestly don't know why. Could be I misunderstand the values I need to insert after the "function" area. I did have this setup with an "Auto Archive" trigger that created a menu button with a "Run" option on the sheet, but when you click that it only does the last row with "Yes" in column 28 (every press of the button will move 1 row until all rows are moved) and the button won't work for the other users of the sheet.
function createTrigger() {
ScriptApp.newTrigger("Move Archive") //Move Archive is the name of the script
.timeBased()
.everyMinutes(1) // only set to 1 minute for testing, I can change this out for a daily timer
.create();
}
function myFunction() {
var sheetNameToWatch = "Schedule"; // "schedule" is the sheet we enter info on
var columnNumberToWatch = 28; //Column is "AB"
var valueToWatch = "Yes";
var sheetNameToMoveTheRowTo = "Archive"; //"Archive is the sheet the info is sent to"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
if (sheet.getName() == sheetNameToWatch && 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, sheet.getLastColumn()).moveTo(targetRange); // I get its programmed for last row with "Yes" here, unsure on how to change this.
sheet.deleteRow(range.getRow());
function myfunction() {
ScriptApp.deleteTrigger("Move Archive"); // could have wrong value here
}
}
}
All I want is the sheet to "Archive" based on a "Yes" value in Column 28 (AB). I want every row with that column value to Archive at 1 am automatically. Any help is appreciated. If someone even wants to recommend a book or digital instruction for beginners that would be great.
You have four project files each containing scripts of the same name, performing the same or similar tasks. You are experiencing lagging because you have multiple simple and installable scripts of the same name. Essentially, they are all trying to execute at the same time.
The following answer should be considered as one possible solution to your situation.
The elements of this script are:
There is a single project file. Unnecessary project files have been deleted.
There is a single function.
The function is a single "simple" trigger (onEdit(e)) which takes advantage of the various event objects returns by onEdit. There are no installable triggers, and any/all installable triggers have been deleted.
The function updates the "Schedule" and "Archive" sheets as described in the question; and then sorts both the "Schedule" and "Archive" sheets.
If there is a change on the "Railcars" sheet, the function sorts that sheet.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var testrange = e.range;
var testsheet = testrange.getSheet();
var testsheetname = testsheet.getSheetName();
var testrow = testrange.getRow();
var testcolumn = testrange.getColumn();
var testvalue = e.value;
var testsheetLC = testsheet.getLastColumn();
var testsheetRange = testsheet.getRange(testrow,1,1,testsheetLC);
//Logger.log("DEBUG: the test sheet range is "+testsheetRange.getA1Notation());
//Logger.log("DEBUG: Range: "+testrange.getA1Notation());
//Logger.log("DEBUG: The row is "+testrow+", and the column is "+testcolumn);
//Logger.log("DEBUG: The spreadheetsheet is "+e.source.getName()+", the sheet name is "+testsheet+", the range = "+testrange.getA1Notation()+", and the new value = "+testvalue);
//Logger.log(JSON.stringify(e));
// Copy/Paste to Schedule/Archive
var sheetNameSchedule = "Schedule";
var colNumberSchedule = 28;
var valueSchedule = "Yes";
var sheetNameArchive = "Archive";
// Sort Schedule
var sortSchedule = [{column: 1, ascending: true},{column: 2, ascending: true},{column: 7, ascending: false}];// date // Appt (time) // Type (Out/In/RR)
// Sort Railcars
var sheetNameRailcars = "Railcars";
var sortRailcars = [{column: 1, ascending: true}];
if (testsheetname === sheetNameSchedule && testcolumn === colNumberSchedule && testvalue === valueSchedule){
// this is a match
// Logger.log("DEBUG: this was a match");
// copy/paste to archive
var targetSheet = ss.getSheetByName(sheetNameArchive);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
//Logger.log("DEBUG: the target range is "+targetRange.getA1Notation());
testsheetRange.moveTo(targetRange);
testsheet.deleteRow(testrow);
// sort the Schedule Sheet
var Avals = testsheet.getRange("A1:A").getValues();
var Alast = Avals.filter(String).length;
//Logger.log("DEBUG: The last row of content (in column A) = "+Alast+", and the last column = "+testsheetLC);
var sortrange = testsheet.getRange(2,1,Alast-1,testsheetLC);
//Logger.log("DEBUG: the sort range = "+sortrange.getA1Notation());
sortrange.sort(sortSchedule);
// sort the Archive Sheet
var ATvals = targetSheet.getRange("A1:A").getValues();
var ATlast = ATvals.filter(String).length;
//Logger.log("DEBUG: The last row of content (in column A) = "+ATlast+", and the last column = "+testsheetLC);
var sortrange = targetSheet.getRange(2,1,ATlast-1,testsheetLC);
//Logger.log("DEBUG: the sort range = "+sortrange.getA1Notation());
sortrange.sort(sortSchedule);
}
else if (testsheetname === sheetNameRailcars){
// sort the sheet
var Avals = testsheet.getRange("A1:A").getValues();
var Alast = Avals.filter(String).length;
//Logger.log("DEBUG: The last row of content (in column A) = "+Alast+", and the last column = "+testsheetLC);
var sortrange = testsheet.getRange(2,1,Alast-1,testsheetLC);
//Logger.log("DEBUG: the sort range = "+sortrange.getA1Notation());
sortrange.sort(sortRailcars);
}
}
You can set up an installable trigger to run this function at 1am every morning:
function scheduleToArchive() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var schedule = sheet.getSheetByName("Schedule");
var archive = sheet.getSheetByName("Archive");
var scheduleData = schedule.getRange(2, 1, (sheet.getRange('A:A').getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow()), 28);
for (row = 2; row <= scheduleData.getNumRows(); row++){
var data = schedule.getRange(row, 1, 1, 28).getValues();
if (data[0][27] == 'Yes'){
archive.getRange((archive.getLastRow() + 1), 1, 1, 28).setValues(data);
}
schedule.getRange(row, 1, 1, 28).clear();
}
}
In your spreadsheet, when getDataRange() is run on the sheet named 'Schedule', it returns row 631 as the last row with data even though there is only data in the first 20 rows, so to get around that I've used SpreadsheetApp.Direction.DOWN instead and run that on column A.
I am trying to write a script to copy column B:K of a specific row based on if column 11 (K) has a "Y" on it.
I have scripts that move from one sheet to another within the same spreadsheet that work just fine but I am really struggling with one spreadsheet to another and only moving part of the row instead of the whole thing.
Below is the script thus far... would love help!
function onEdit() {
var sss = SpreadsheetApp.openById("15RWoaW8tRLVGOTDrZvBLJwx0beWEsV3x8pfwGe2zMfc").getSheetByName("2018 2 Week Snapshot for Jim"); // sss = source spreadsheet
var r = sss.getActiveRange();
if(sss.getName() == "2018 2 Week Snapshot for Jim" && r.getColumn() == 11 && r.getValue() == "Y") {
var row = r.getRow();
var numColumns = sss.getLastColumn();
var tss = SpreadsheetApp.openById("1dSJOOw_oLVc6Nf-C0MY9715tZGuh69kR6-j_m8EJ-So"); // tss = target spreadsheet
var targetSheet = tss.getSheetByName("Test Sheet"); // ts = target sheet
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
tss.getRange(row, 1, 1, numColumns).copyTo(target);
}
}
This is my new code, still struggling:
function onEdit() {
var sss = SpreadsheetApp.openById('15RWoaW8tRLVGOTDrZvBLJwx0beWEsV3x8pfwGe2zMfc'); // sss = source spreadsheet
var ss = sss.getSheetByName('2018 2 Week Snapshot for Jim'); // ss = source sheet
var SRange = ss.getRange("C:K");
if(ss.getName() == "2018 2 Week Snapshot for Jim" && SRange.getColumn() == 9 && SRange.getValue() == "y") {
var row = SRange.getRow();
var numColumns = ss.getLastColumn();
var tss = SpreadsheetApp.openById('1dSJOOw_oLVc6Nf-C0MY9715tZGuh69kR6-j_m8EJ-So'); // tss = target spreadsheet
var ts = tss.getSheetByName('Test Sheet'); // ts = target sheet
var target = ts.getRange(ts.getLastRow() + 1, 1);
ss.getRange(row, 1, 1, numColumns).SetValues(target);
}
}
When users put y or Y to column K at the sheet of 2018 2 Week Snapshot for Jim on the active spreadsheet, you want to copy only the values of B:K to the last row at the sheet of "Test Sheet" on the spreadsheet of 1dSJOOw_oLVc6Nf-C0MY9715tZGuh69kR6-j_m8EJ-So.
Spreadsheet of 15RWoaW8tRLVGOTDrZvBLJwx0beWEsV3x8pfwGe2zMfc is the active spreadsheet.
If my understanding is correct, how about this modification?
Modification poonts:
set of setValues() is lower case.
values of setValues(values) is 2 dimentional array.
The range for setValues(values) is the range for putting the values.
When you use onEdit(), you can use an event object.
The script which reflected above is as follows.
Modified script:
function myFunction(e) {
var sourceSheetName = "2018 2 Week Snapshot for Jim";
var destinationSpreadsheetId = "1dSJOOw_oLVc6Nf-C0MY9715tZGuh69kR6-j_m8EJ-So";
var destinationSheetName = "Test Sheet";
if (e.source.getSheetName() == sourceSheetName && e.range.getA1Notation()[0] == "K" && e.value.toUpperCase() == "Y") {
var sourceValues = e.source.getRange("B:K").getValues().filter(function(e){return e.filter(String).length > 0});
var tss = SpreadsheetApp.openById(destinationSpreadsheetId);
var ts = tss.getSheetByName(destinationSheetName);
ts.getRange(ts.getLastRow() + 1, 1, sourceValues.length, sourceValues[0].length).setValues(sourceValues);
}
}
Note :
Before you use this script, please install myFunction() as an installable trigger.
References:
Event Objects
Installable Triggers
setValues()
If I misunderstand your situation, I'm sorry.