Google Sheets - Script; getRange getLastRow copyTo - google-apps-script

I'm rewriting a daily tracker that takes a row of data, and appends it to the last row on a second sheet for historical data.
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("TODAY_TRACKER!P2:T2");
var destSheet = ss.getSheetByName("DATA");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
This just copies the row to the last row beginning at 1,1 on the data sheet.
I'm updating the tracking sheet to take the days numbers and make a table of weekly data; I want to append this row of data to the last row at a specific position on the same sheet.
var source = ss.getRange("NEW_TTRACKER!J3:O3");
var destRange = ss.getRange(ss.getLastRow(7,10,1,6)+1,1);
source.copyTo (destRange, {contentsOnly: true});
This obviously doesn't work, I was just taking a stab.
I'm attempting to copy the first row of data to column 7 row 10 for 1 row and 6 columns.
Then subsequent rows in the days following to go beneath the last.
Help is appreciated, thanks in advance.

It does not work since there's a syntax error on your destRange. First it's missing one opening parenthesis, second you're adding an incorrect syntax on the getRange function. The first parameter you used did not include some additional methods to pull the range and get the last row of the range. Also using getLastRow() will get the last row on the entire sheet so if you have any other data below the required range it will probably count that as well. So instead, we can approach this by getting values of data on the range and using length to determine which subarray has the last data and use that as reference to when moving to the next blank row.
See code below
function copyDataArray() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var destSheet = ss.getSheetByName("NEW_TTRACKER");
var source = destSheet.getRange("J3:O3");
//Define the position of the last available data on the weekly section
var lastrowonrange = destSheet.getRange("J7:J11").getValues().filter(String).length;
//Selects the area whare to past the data based on the last available data
var destRange = destSheet.getRange(lastrowonrange+7,10,1,6);
source.copyTo(destRange, {contentsOnly: true});
};
I'm able to run it properly that it appends data on the destRange.

Related

Copy/paste values every day under previous pasted cell?

Here's my problem : i'm trying to copy a value from one cell in "sheet1" to another cell in "sheet2".
But I want to run this script everyday (using trigger) because the value change every day. So the paste has to be in B2 the first day, B3 the second day, etc. I want to be able to follow the value day by day and have an historic.
Here's my current script :
function backup(){
var sourceSheet = "Portfolio" ;
var sourceRange = "N15" ;
var targetSheet = "Suivi perfs journalières" ;
var targetRange = "B2:B999" ;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sourceSheet);
var values = sheet.getRange(sourceRange).getValues();
ss.getSheetByName(targetSheet).getRange(targetRange).setValues(values);
I have 2 problem :
My script send me this error : Exception: The number of rows of data does not match the number of rows in the range. There are 1 lines of data, but the range has 998. (line 12, "CopyPastePortfolioValue" file)
I don't know how to paste the value in a new cell everyday (paste in the cell under the previous each day)
Thanks for your help!
I believe your goal as follows.
You want to retrieve the value from the cell N15 in the source sheet and append the value to the target sheet.
Modification points:
When setValues(values) is used, the lengths of rows and columns of values are required to match to the range. In your script, values of var values = sheet.getRange(sourceRange).getValues(); is 1 row and 1 column. But the target range is B2:B999. By this, such error occurs. I think that this is the answer for your 1st question.
In order to append the value to the target sheet, in your case, I would like to propose to use appendRow. I think that this is the answer for your 2nd question.
And, when a value from a cell, you can also use getValue instead of getValues.
When above points are reflected to your script, it becomes as follows.
Modified script:
function backup(){
var sourceSheet = "Portfolio";
var sourceRange = "N15";
var targetSheet = "Suivi perfs journalières";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sourceSheet);
var value = sheet.getRange(sourceRange).getValue(); // Modified
ss.getSheetByName(targetSheet).appendRow([value]); // Modified
}
References:
setValues(values)
appendRow(rowContents)

appendRow not working when appending to a filtered range in Google Sheets

I wrote a script that is supposed to append a row to a filtered range within a Google Sheets. My script works in normal situation. But when the last row of the destination range is deleted AND the range is filtered on one of the fields (image below illustrates the situation), the appendRow does not work.
Screenshot of the situations where appendRow does/doesn't work:
[1
Here is my code:
function myFunction() {
outputRowArray = [1,2];
destinationUrl = "XXX";
destinationSheet = "Sheet1"
SpreadsheetApp.openByUrl(destinationUrl).getSheetByName(destinationSheet).appendRow(outputRowArray);
}
You are missing that appendRow appends a row to the sheet, that means that the row is added after the last row with data in sheet. Also you are missing that the filter boundaries are only updated when inserting a row/column that are part of the filter range (this should be done between two rows/columns) but not when appending them (inserting the row/column after the last row/column of the filter range)
On the past I have seeing similar questions claiming that appendRows don't work but what was happening is that the sheet include some values (sometimes an empty string) several rows below of the rows shows in the screen.
To help you to understand what is happening log some sheets characteristics by using Class Sheets methods like
getLastRow()
getMaxRows()
To log things you could use Logger.log(something) and console.log(something). for further details checkout https://developers.google.com/apps-script/guides/support/troubleshooting
Something else to try is to log the last row after appending a new row, but bear in mind that you might need to use SpreadsheetApp.flush() first. Example:
function myFunction() {
outputRowArray = [1,2];
destinationUrl = "XXX";
destinationSheet = "Sheet1"
var sheet = SpreadsheetApp.openByUrl(destinationUrl).getSheetByName(destinationSheet);
sheet.appendRow(outputRowArray);
SpreadsheetApp.flush();
var lastRow = sheet.getLastRow();
console.info(lastRow);
}
More than a work around then a solution.
function myFunction() {
outputRowArray = [1,2];
destinationUrl = "XXX";
destinationSheet = "Sheet1"
var sheet = SpreadsheetApp.openByUrl(destinationUrl).getSheetByName(destinationSheet)
var last_row = sheet.getLastRow()
var insert_range = sheet.getRange(last_row+1,1,1,outputRowArray.length()) // not really sure that I got right the dims
insert_range.setValues([outputRowArray])
}

Trying to build G Sheets scrip that will copy and paste a dynamic range within same spreadsheet

I'm trying to build a script that will allow me to copy and value paste a range from tab "robert" to tab "brendan". However, the range in "robert" is dynamic, so sometimes it will need to copy and paste A1:M3 or A1:M20. I'd also like it to append to the the first rows of the destination. So when run, the script looks for values on the source tab (robert), copies them, and pastes their values at the top of the destination (brendan) without overwriting existing data.
So far I've worked with the below script from a different thread:
function moveValuesOnly() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange('Robert!A1:M100');
source.copyTo(ss.getRange('Brendan!A4'), {contentsOnly: true});
source.clear();
}
The problem here is the script range is static, and it overwrites anything in the destination. I do like the clearing of the source though and the values paste. Any help would be greatly appreciated!
Define the range using variables. Use getLastRow() and getLastColumn() Instead of hard-coding it.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var robWs = ss.getSheetByName("Robert");
var brenWs = ss.getSheetByName("Brendan");
var robLr = robWs.getLastRow()
var robLc = robWs.getLastColumn()
//range starts at row 1 and column 1 (A1), you may need to change accordingly
var vals = robWs.getRange(1,1,lr,lc).getValues;
//paste range also starts at A1. you can find the lr on this sheet and start the range there
brenWs.getRange(1,1,lr,lc).setValues(vals);
function moveValuesOnly() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Robert');
var rg=sh.getActiveRange();//copies active range for source
var vA=rg.getValues();
dsh=ss.getSheetByName('Brendan');
dsr=4;//destination start row
dsc=1;//destination start col
dsa=2;//destination number of rows to append to
drg=dsh.getRange(dsr,dsc,rg.getHeight(),rg.getWidth());
var dvA=drg.getValues();
vA.forEach(function(r,i){
if(i<dsa){
r.forEach(function(c,j){
//only write data in destination for these rows if destination value is null
if(dvA[i][j]='') {
dvA[i][j]=c;
}
});
}else{
dvA[i][j]=c;
}
})
drg.setValues(dvA);
}

Set values to ranges in a different spreadsheet

Can anybody offer suggestions about how to update or set values to a range in a different spreadsheet. I know the importRange function will bring values into the active sheet, but I want to "push" a single row of data from the active sheet to a row at the bottom of a sheet called FinalData, which is in a different spreadsheet.
The data I want to "push" is populated by other code, resulting in a single row of data in a sheet called TempData. The data exists in range TempData!A2:U2.
My goal is to append data from TempData!A2:U2 to a new row at the bottom of a table called "DataFinal", which is in a completely separate google spreadsheet (but on the same "google drive".)
Here's what I tried so far:
// Row to FinalData
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var startSheet = ss.getSheetByName("TempData");
var sourceRange = ss.getRange ("TempData!A2:U");
var target = SpreadsheetApp.openById("1bWKS_Z1JwLSCO5WSq1iNP1LLQpVXnspA4WkzdyxYDNY");
var targetSheet = target.getSheetByName("DataFinal");
var lastRow = targetSheet.getLastRow();
targetSheet.insertRowAfter(lastRow);
sourceRange.copyTo(targetSheet.getRange(lastRow + 1,1), {contentsOnly: true});
When I run it I get an error that says "Target range and source range must be on the same spreadsheet.". There must be a way to do this-- any suggestions would be welcome.
copyTo() can be used for the same spreadsheet.
From your script, I think that you can achieve it using getValues() and setValues(), because you use contentsOnly: true. So how about this modification?
From :
sourceRange.copyTo(targetSheet.getRange(lastRow + 1,1), {contentsOnly: true})
To :
var sourceValues = sourceRange.getValues();
targetSheet.getRange(lastRow + 1, 1, sourceValues.length, sourceValues[0].length).setValues(sourceValues);
Note :
If you want to use copyTo(), this thread might be useful for your situation.
References :
copyTo()
getValues()
setValues()
If this was not what you want, please tell me. I would like to modify it.

Google Sheets: Those rows are out of bounds error

I am brand new to writing code and I am fumbling through this trying to come up with a spreadsheet that is fed info from a form. I have searched and searched for the answer to this problem for days but I cannot figure it out on my own without some help..so HELP! :)
What my script does it creates a copy of a sheet based on a trigger every night so that I have a record of form responses for each day. I want to to delete (not clear) all rows except the top 6 rows each time a new sheet is created so the form will add lines each time a response is given. I keep getting the Those rows are out of bounds. (line 17, file "DailyClear") when I try to run the script.
Here is what I've got
function dailyclear(e)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Today');
sheet.copyTo(ss)
var nusheet = ss.getSheetByName('Copy of Today')
var value = nusheet.getRange("B2").getCell(1,1).getValue()
SpreadsheetApp.setActiveSheet(nusheet)
Logger.log("Current index of sheet: %s", nusheet.getIndex())
ss.moveActiveSheet(2);
nusheet.setName(value);
//Clear "Today"
var lastrow = sheet.getLastRow()
sheet.deleteRows(7, lastrow-6)
//Set Date Value for "Today"
var dd = Utilities.formatDate(new Date(), "GMT-5", "MM/dd/yy");
sheet.getRange("B2").getCell(1,1).setValue(dd);
}
It will not allow me to delete the 7th row and retain rows 1-6 without throwing that error if the 7th row is blank and the only row that exists. If I start adding information from form responses in the cells and it starts creating rows and I run the script it throws up the error Sorry, it is not possible to delete all non-frozen rows. (line 17, file "DailyClear"). And on top of all that when a new sheet is created I have the 7th row clear ready for the first response from the form to fill and the form puts the first response of the day on row 8 and leaves 7 blank! This is driving me crazy...anyone recommend a good book for beginners before I go crazy? :( Thanks for any help I can get, here is a link to my sheet..
https://docs.google.com/spreadsheets/d/1NZxXjMptx6ldzL2CKk6OwJcq_heIv995ZGVeIE59xNc/edit?usp=sharing
Thank you to anyone who can help
As noted already, you cannot delete all non-frozen rows, so Row 7 will have to stay. Perhaps shrink it down and add a fill or some formatting so it just doesn't look like an empty row, and then since data is entered on row 8 anyway, change your script slightly to accomodate:
function dailyclear(e)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Today');
sheet.copyTo(ss)
var nusheet = ss.getSheetByName('Copy of Today')
var value = nusheet.getRange("B2").getCell(1,1).getValue()
SpreadsheetApp.setActiveSheet(nusheet)
Logger.log("Current index of sheet: %s", nusheet.getIndex())
ss.moveActiveSheet(2);
nusheet.setName(value);
//Clear "Today"
var lastrow = sheet.getLastRow()
sheet.deleteRows(8, lastrow-7);
//Set Date Value for "Today"
var dd = Utilities.formatDate(new Date(), "GMT-5", "MM/dd/yy");
sheet.getRange("B2").getCell(1,1).setValue(dd);
}