Copy/paste incremental data from one tab to another tab - google-apps-script

I have little coding experience but can usually cobble together a solution by looking at examples. This time have not been able to get it working or found examples within my skill range to parse.
Essentially I'd like to copy data from tab 1 and place it underneath the running data on tab 2, but only when there is data on tab 1 to copy.
I started with the following which does work, but doesn't check for available data, or vary the size the of the range of data captured so it runs and pastes a lot of blank space.
function CopyRows() {
var source = SpreadsheetApp.openById('key');
var sourcesheet = source.getSheetByName('ImportPage');
var target = SpreadsheetApp.openById('key')
var targetsheet = target.getSheetByName('TargetPage');
var targetrange = targetsheet.getRange(targetsheet.getLastRow() + 1 , 1);
sourcesheet.getRange(2, 1, sourcesheet.getLastRow(), sourcesheet.getLastColumn()).copyTo(targetrange);}
I think that what I need to add to this is a way to vary the range of data captured, and to halt the function if no data is present.
I have the data coming in from another sheet though the importrange function. it might be better to do the whole thing via script but that part is working well enough for now.
Any advice would be appreciated.

This might work:
function CopyRows() {
var source = SpreadsheetApp.openById('key');
var sourcesheet = source.getSheetByName('ImportPage');
var target = SpreadsheetApp.openById('key')
var targetsheet = target.getSheetByName('TargetPage');
var lastRowOfTrgtSheet = targetsheet.getLastRow();
var srcData = sourcesheet
.getRange(2, 1, sourcesheet.getLastRow(), sourcesheet.getLastColumn())
.getValues();
targetsheet.getRange(lastRowOfTrgtSheet+1, 1, srcData.length, srcData[0].length)
.setValues(srcData);
};
It uses the setValues() method instead of copyTo().
If you want to use copyTo(), you'll need to use the version of getRange() that takes 4 parameters, and subtract 1 from the length of the rows in the source sheet:
function CopyRows() {
var source = SpreadsheetApp.openById('key');
var sourcesheet = source.getSheetByName('ImportPage');
var target = SpreadsheetApp.openById('key')
var targetsheet = target.getSheetByName('TargetPage');
var lastRowOfTrgtSheet = targetsheet.getLastRow();
var srcLastRw = sourcesheet.getLastRow();
var targetrange = targetsheet
.getRange(lastRowOfTrgtSheet + 1, 1, srcLastRw-1, sourcesheet.getLastColumn());
sourcesheet.getRange(2, 1, sourcesheet.getLastRow(), sourcesheet.getLastColumn())
.copyTo(targetrange);
};

Related

I'm looking to improve the code I use to copy down data

I have some code made by recording a macro in Google Sheets. It does a copy and paste of data into a column. But it's a clumsy way to copy down and I'd like to do it better.
I currently use this code.
function import2() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Road MT'),
true);
spreadsheet.getRange('C2').activate();
spreadsheet.getRange('Imported!A2:A').copyTo(spreadsheet.getActiveRange(),
SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
I have also used code similar to below, but the problem with this code is that it throws an error if the rows don't actually exist. It's doesn't create new rows to fill the data.
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('\'Round Up\'!F:F').activate();
spreadsheet.getActiveRangeList().setNumberFormat('#')
var range = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
range.getRange("\'Road MT\'!AF2").setFormula('=\'Round Up\'!F2');
var lr = range.getLastRow();
var fillDownRange = range.getRange(2, 32, lr-1);
range.getRange("\'Road MT\'!AF2").copyTo(fillDownRange);
I use a script to do something like that. It won't create row your way, but if you know the range of what you are pasting, you can set the range of the data to copy to be rows that don't exist yet and it will make them.
var spreadsheet = SpreadsheetApp.getActive();
//this get what you want to copy and it's length
var sheetToCopy = spreadsheet.getSheetByName(<name>); //or similar
var rangeToCopy = sheetToCopy.getRange(<yourRange>)
var dataToCopy = rangeToCopy.getValues()
var nRowsToCopy = dataToCopy.length // or rangeToCopy.getLastRow()
var nColsToCopy = rangeToCopy.getLastColumn() //because dataToCopy[0].lenght might vary from dataToCopy[5].lenght
//this get get where you wanna copy it and set the proper range so it can be pasted
var fillDownSheet = spreadsheet.getSheetByName(<name>); //or similar
var fillDownRow = fillDownSheet.getLastRow()+1;
var fillDownRange = fillDownSheet.getRange(fillDownRow, <yourColIndex>, nRowsToCopy, nColsToCopy);
//this paste your data
fillDownRange.setValues(dataToCopy);
Alternatively, you could also use the copyToDestination() method like so :
var spreadsheet = SpreadsheetApp.getActive();
var sheetToCopy = spreadsheet.getSheetByName(<name>); //or similar
var rangeToCopy = sheetToCopy.getDataRange()
var nRowsToCopy = rangeToCopy.getLastRow()
var nColsToCopy = rangeToCopy.getLastColumn()
var fillDownSheet = spreadsheet.getSheetByName(<name>); //or similar
var fillDownRow = fillDownSheet.getLastRow();
var fillDownRange = fillDownSheet.getRange(fillDownRow, 1);
var fillDownGridID = fillDownRange.getGridId();
rangeToCopy.copyValuesToRange(fillDownGridID, 1, nRowsToCopy, fillDownRow, (fillDownRow+nColsToCopy))
But you need at least one empty row on your sheet or it's going to overwrite it.

The coordinates or dimensions of the range are invalid. - Moving rows with button

This is my first question here, so apologies for any errors in posting. I have found many related questions, but nothing that solved my problem. I have the code below in a spreadsheet that is supposed to move selected rows (the user enters the first row to archive and the last row to archive) to an archive sheet. I am getting this error:
The coordinates or dimensions of the range are invalid.
related to this line:
s.getRange(rowStart, 1, numR, 9).moveTo(target);
Any help would be greatly appreciated.
Here is the code:
function onButton() {
// assumes source data in sheet named Orders
// target sheet of move to named Archived
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Orders");
var cellStart = s.getRange(11,2);
var cellEnd = s.getRange(12,2);
var rowStart = cellStart.getValue();
var numR = cellEnd.getValue() - cellStart.getValue() + 1;
var targetSheet = ss.getSheetByName("Archived");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, numR);
s.getRange(rowStart, 1, numR, 9).moveTo(target);
s.deleteRows(rowStart, numRows);
}
For anyone reading this later on, the commenters gave me the clues I needed to fix it, here is the now-working code:
function onButton() {
// assumes source data in sheet named Orders
// target sheet of move to named Archived
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Orders");
var cellStart = s.getRange(2, 11);
var cellEnd = s.getRange(2, 12);
var rowStart = cellStart.getValue();
var numR = cellEnd.getValue() - cellStart.getValue() + 1;
var targetSheet = ss.getSheetByName("Archived");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(rowStart, 1, numR, 9).moveTo(target);
s.deleteRows(rowStart, numR);
}
Thanks everyone!

google sheets script conditionally move row to another spreadsheet

I am new to this and I am having some trouble trying to figure this out. I have a spreadsheet that collects data from a google form. I am trying to find a way to move that data based on a column answer to a different google sheet. (Not a sheet in the same document but a different document all together). It seems like there is some information about moving to a different tab in the same document, but not a different document.
I will first say that I tried just an IMPORTRANGE function, but that only mirrors the data, and does not let you update or change cells.
Here is what I have been able to piece together so far, but I may be way off.
I have a trigger that would run every hour.
function myFunction() {
var ss = SpreadsheetApp.openById('1U0I9SkbGkHgm-vRkwf2Ppc_yxlqrVlg2t8yKRy3sYuI');
var sheetOrg = ss.getSheetByName("Form Responses 1");
var value1ToWatch = "ANDERSON";
var value2ToWatch = "BARNES";
var sheetNameToMoveTheRowTo = "Sheet1"; //sheet has same name for each target openByID(" *url key* ")
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ts1 =SpreadsheetApp.openById("1PxV1PQrMdu_2aSru4dpan8cUgHYdlYPUp5anyzjMAms");
sheet1in = ts1.getSheetByName("Sheet1");
var ts2 = SpreadsheetApp.openById("1BYyQZNiXc2QqsyqWs7uazjl5B6mfFYM1xj3u8gWyYOQ");
sheet1in = ts2.getSheetByName("Sheet1");
arr = [],
values = sheetOrg.getDataRange().getValues(),
i = values.length;
while (--i) {
if (value1ToWatch.indexOf(values[i][1]) > -1) {
arr.unshift(values[i])
sheetOrg.deleteRow(i + 1)
sheet1in.getRange(sheet1in.getLastRow()+1, 1, arr.length,
arr[0].length).setValues(arr);
};
if (value2ToWatch.indexOf(values[i][1]) > -1) {
arr.unshift(values[i])
sheetOrg.deleteRow(i + 1)
sheet2in.getRange(sheet2in.getLastRow()+1, 1, arr.length,
arr[0].length).setValues(arr);
};
}
}
The sheet google forms dumps the information into is "Form Responses 1".
Column B is the cells I want to get the values from. (There are a total of 9 different values that it can be like "ANDERSON", "BARNES", "SMITH", etc).
For sheetNameToMoveTheRowTo is "Sheet1" - that may be confusing and I may need to change that, but for example
ts1 =SpreadsheetApp.openById("1PxV1PQrMdu_2aSru4dpan8cUgHYdlYPUp5anyzjMAms") the sheet name that I want the information moved to is "Sheet1".
ts2 = SpreadsheetApp.openById("1BYyQZNiXc2QqsyqWs7uazjl5B6mfFYM1xj3u8gWyYOQ") the sheet name is also "Sheet1" but in a different document.
I think if I were able to get the "ANDERSON" one to work, then I can just add additional variables for each possible response, and just copy and paste additional "IF" statements, just changing the valueToWatch and targetSheet values. <= if that is not correct please let me know
I have tried to both debug, and run the script above but nothing happens. There are no errors reported on the debug, but it is not moving any information over.
Any idea what I am doing wrong?
// UPDATE I got this to work. I have updated the code listed with what worked for me.
I think that copyTo() method will not work like you mentioned, it operates on same SpreadSheet. I'm sending you example with looping on source sheet data and then setting the target sheet values with it.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var allrange = ss.getActiveRange();
var range = sheet.getRange("A1:A10");
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 new Google SpreadSheet
var newSheet = SpreadsheetApp.openById('1F79XkNPWm2cCWlB2JP3K4tAYRESKUgtHK4Pn2vbJEiI').getSheets()[0];
var tmp = "A1:A" + dataLength ;
var newRange = newSheet.getRange( tmp );
newRange.setValues( allvals );
}
Here's a simple example of moving data from one spreadsheet to another.
function movingDataToSS(){
var ss=SpreadsheetApp.getActive();
var dss=SpreadsheetApp.openById('ssId');
var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var vA=rg.getValues();
var dsh=dss.getSheetByName('Sheet1');
var drg=dsh.getRange(1,1,rg.getHeight(),rg.getWidth()).setValues(vA);
}
If you interested in placing some conditions on your output by only getting output from odd rows and even columns.
function movingDataOddRowsAndEvenCols(){
var ss=SpreadsheetApp.getActive();
var dss=SpreadsheetApp.openById('ssId');
var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var vA=rg.getValues();
var h=rg.getHeight();
var w=rg.getWidth();
var dsh=dss.getSheetByName('Sheet1');
for(var i=0;i<h;i++){
var out=[];
if(i%2==0){
for(var j=0;j<w;j++){
if(j%2==1){
out.push(vA[i][j]);
}
}
dsh.appendRow(out);
}
}
}

Copy row to new sheet using Google Apps Script

I know it has been asked and answered here many times, but I can not make it work. I am trying to copy a row values (no formulas) from one sheet to another sheet on googlesheets using Google Apps Script. Very basic, but somehow it is giving me hard time.
I have:
SourceSheet
SourceWorksheet
TargetSheet
TargetWorksheet
I am trying to Copy row values (no formulas) from SourceWorksheet(A2:K2), to a new row (after last used row) on TargetWorksheet. It will be again from (A:K) but row number will be different, each time it will create a new row after last row.
Any help would be really appreciated!
EDIT
I found this code below, but not sure how to modify it to read the range i mentioned above instead of all the rows from source worksheet, and I need to modify it so it finds last row on target worksheet then creates new row each time to write the values ( so it doesn't overwrite any data on target)
function myFunction() {
var source = SpreadsheetApp.openById('xxxxxx');
var sourcesheet = source.getSheetByName('sheet1');
var target = SpreadsheetApp.openById('xxxxx')
var targetsheet = target.getSheetByName('sheet1');
var targetrange = targetsheet.getRange(2, 1, sourcesheet.getLastRow(), sourcesheet.getLastColumn());
var rangeValues = sourcesheet.getRange(2, 1, sourcesheet.getLastRow(), sourcesheet.getLastColumn()).getValues();
targetrange.setValues(rangeValues);
}
To add a line to the last row of a form, use the sheet.appendRow() method.
In your example, var targetRange would not be needed. You could simply use targetSheet.appendRow(rangeValues) where the rangeValues = the range you're copying (as an array)
function myFunction() {
var source = SpreadsheetApp.openById('xxxxxx');
var sourcesheet = source.getSheetByName('sheet1');
var target = SpreadsheetApp.openById('xxxxx')
var targetsheet = target.getSheetByName('sheet1');
var rangeValues = sourcesheet.getRange(2, 1, sourcesheet.getLastRow(), sourcesheet.getLastColumn()).getValues();
targetSheet.appendRow(rangeValues);
}

Copy Columns from a sheet to add at lastcolumn in "archive" sheet with GAS

Sorry for my english. ^^
Erm, i´ve found a script to copy from a sheet to an other Sheet.
My problem is: its copy with rows.
I want to copy columns and add 2 columns to lastcolumn on script running.
It becames a problem, because columns has no a1notification. A=1, B=2, etc.
copyTo wants A1notification.
Heres my script:
function Archiv() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var target = SpreadsheetApp.openById("sheetid");
var source_sheet = ss.getSheetByName("sheetname");
var target_sheet = target.getSheetByName("sheetnametarget");
var source_range = source_sheet.getRange("D4:E89");
var last_col = target_sheet.getLastColumn();
target_sheet.insertColumnAfter(last_col);
var target_range = target_sheet.getRange(">>>>(lastcol+1)<<<<4:>>>>>(lastcol+2)<<<<89");
source_range.copyTo(target_range, {contentsOnly:true});
}
The script have to run every Monday to archive the content of 2 Columns.
I hope you can understand my wish.
I have tested many things, but nothing helps. :(
Many thanks in advance.
Sebastian
You can use another range selection mode that will makes things very simple, see this doc, using integers for row and column numbers.
Your code could become like this :
function Archiv() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var target = SpreadsheetApp.openById("sheetid");
var source_sheet = ss.getSheetByName("sheetname");
var target_sheet = target.getSheetByName("sheetnametarget");
var source_range = source_sheet.getRange("D4:E89");
var last_col = target_sheet.getLastColumn();
while(target_sheet.getMaxColumns()<=last_col+2){// add columns only if necessary
target_sheet.insertColumnAfter(last_col)}
var source_values = source_range.getValues();
var target_range = target_sheet.getRange(4,last_col+1,source_values.length,2);// row Nr4, starting on last column+1, 2 columns width and 89-4 rows heigth
target_range.setValues(source_values);
}
I used getValues() and setValues() instead of copyTo() that returned an error : target and source must be in the same spreadsheet