How to define range that could vary in google apps script - google-apps-script

I'm trying to make a copy of one spreadsheet using a (time driven) Google App Script. I found a very useful piece of code here, but my concern is that the range varies frequently (new rows are added). How can I copy the entire spreadsheet no matter if the range changes?. because as you can see in the code below I have defined the range, but when this changes the information out of the defined range will be discarded. What can I do?
Thanks in advance.
Here the code I'm using:
function saveAsSpreadsheet(){
var timestamp = new Date();
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var range = sheet.getRange('sheetName!A1:AO158');
sheet.setNamedRange('sheetName', range);
var TestRange = sheet.getRangeByName('sheetName').getValues();
Logger.log(TestRange);
var destFolder = DriveApp.getFolderById("folderID");
DriveApp.getFileById(sheet.getId()).makeCopy("FileName:"+ timestamp, destFolder);
}

If you need to get the range object defined by the first cell of column A and the last cell in column A that contains data, use this code:
var range = sheet.getRange(1, 1, sheet.getLastRow(), 1);
The getRange() method has several overloads and can accept numerical values defining the boundaries of the range as well. More on this here https://developers.google.com/apps-script/reference/spreadsheet/sheet#getRange(Integer,Integer)
If you need to copy everything, use getDataRange() method.

Related

Google app script to cut and paste a range from a google sheet to another google sheet

I'm trying to put together a script that cuts a range from a google spreadsheet and pastes it to another spreadsheet. The script works fine as long as the source sheet is the first sheet in my document. How can I fix it so that the script grabs the right sheet no matter where it is in my document?
I'm very very new at this and mostly used code I found online. Probably made a very obvious mistake..
function CopyRangeTo_OtherSheet() {
var sss = SpreadsheetApp.openById('1O1gML-IeOkx6n6RhCavay6Zg9zflalcVs0qkB2yu7bE');
var ss = sss.getSheetByName('Sheet1');
var range = ss.getRange(2,4,sss.getLastRow()-1,9);
var data = range.getValues();
var tss = SpreadsheetApp.openById('1WHoETM3QxV166ndnPW4Qv37Y6SBGPVw-CcEQxNpw0Co');
var ts = tss.getSheetByName('Sheet3');
ts.getRange(ts.getLastRow()+1, 1,50,9).setValues(data);
var spread = SpreadsheetApp.openById('1O1gML-IeOkx6n6RhCavay6Zg9zflalcVs0qkB2yu7bE');
var sheet = spread.getSheetByName("Sheet1");
sheet.getRange("D2:H").clearContent();
}
The number of rows will be different in each sheet. .getLastRow() on a spreadsheet class only returns the last row in first sheet. getLastRow of sheet instead
ss.getLastRow()
Your line var ss = sss.getSheetByName('Sheet1'); implies that you take the sheet with the name Sheet1.
This is the sheet you use to obtain your values from range and subsequently copy them.
If you want to copy / cut and paste values from a different sheet, simply paste the correct name of the sheet in var ss = sss.getSheetByName('PASTE HERE THE NAME OF THE SHEET');
Small annotation:
If the range you want to clear is the same from which you copied the
values, you do not need to define it again. You can simply replace the
lines
var spread = SpreadsheetApp.openById('1O1gML-IeOkx6n6RhCavay6Zg9zflalcVs0qkB2yu7bE');
var sheet = spread.getSheetByName("Sheet1");
sheet.getRange("D2:H").clearContent();
through
range.clearContents();
Also note:
setValues() only works if the range into which the values shall be set has the same dimension like the value range, i.e. the original range.
If your original range is 2,4,ss.getLastRow()-1,9, then the number of rows is ss.getLastRow()-1 and the number of columns 9.
Thus, you need to define
ts.getRange(ts.getLastRow()+1, 1,ss.getLastRow()-1,9).setValues(data);
to adapt the row number dynamically.

Selecting specific range instead of active range in App Script

I have written a script on Google App Script that will, at one point, get a range from one sheet, copy the values on that range and paste them to another sheet.
I have done so by doing this:
var range = sh.getDataRange().offset(0, 0);
var data = range.getValues();
var ts = SpreadsheetApp.openById('SHEETID').getSheetByName('SHEETNAME')
ts.getRange(ts.getLastRow() + 1, 1, data.length, data[0].length).setValues(data)
I would like, however, to specify the exact range to copy and another exact range to paste the data into.
I would like the range to be copied/pasted to be from columns A to Z whilst still keeping the getLastRow() in the script.
How would I do that?
Thanks for your help.
You can use getRange(a1Notation) to fetch a range and its contents. I usually go for A1 notation. Sample:
// Get a range A1:D4 on sheet titled "Invoices"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var range = ss.getRange("Invoices!A1:D4");
// Get cell A1 on the first sheet
var sheet = ss.getSheets()[0];
var cell = sheet.getRange("A1");
There are other variations of getRange you can use. Choose what you're comfortable with.
For copying and pasting altogether, you can use the copyTo(destination)
// The code below copies the first 5 columns over to the 6th column.
var sheet = SpreadsheetApp.getActiveSheet();

How to multiply a cell by 100 and copy the resulting value into the last column of another sheet

Having trouble with very simple code, I have successfully copied cells and ranges of cells to other sheets, but I cannot get the multiplication of a value to copy, I am sure this is very simple so apologize up front.
The error I get is "TypeError: Cannot find function getcopyTo in objec"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[1];
var nextsheet = ss.getSheets()[4];
var lastColumn = nextsheet.getLastColumn()+1;
var newData = sheet.getRange("D35").getValue()*100;
newData.getcopyTo(nextsheet.getRange(9,lastcolumn), {contentsOnly:true});
var newData = sheet.getRange("D35").getValue()*100;
This returns a number, like 4200. Then you try newData.getcopyTo which can't possibly work, there is no method "getcopyTo" in the number 4200. (Actually, there is no such method in Apps Script, it looks like some mix of getValues and copyTo). What you should do is
nextsheet.getRange(9,lastcolumn).setValue(newData);
The method copyTo is used in the form sourceRange.copyTo(targetRange) but that's direct copying from one range to another, without any manipulation like multiplying by 100.

ImportXML using Google Spreadsheets and Save Results Over-Time

I'm using ImportXML on Google Spreadsheets to scrape YouTube search results and capture the rankings of a video I'm tracking.
=IMPORTXML("https://www.youtube.com/results?search_query=control+theory&page=1"),"//div[#class='yt-lockup-byline']//a")
The scraping works well (and I get all the results for the first page). I then lookup the position of the YouTube results and save that in a cell.
However, the issue I'm having is when I'm trying to track that ranking over-time. Not sure how to do this but I'm looking for a way to run the =ImportXML function every day (is there a refresh command?) and save the result from that cell in a new row each time the function is run.
Any ideas?
importXML output is automatically updated (about every two hours), but you still need a script to save the past values somewhere: usually, on another sheet. Enter the following using Tools > Script Editor, adjusting the sheet names and the cell with the value of interest. Set it to run daily or weekly using Resources > Current project's triggers.
function storeValue() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1'); // where importXML is
var value = sheet.getRange("B3").getValue(); // where the cell of interest is
var sheet2 = ss.getSheetByName('Sheet2'); // where to store the data
var height = sheet2.getLastRow();
sheet2.insertRowAfter(height);
sheet2.getRange(height+1, 1, 1, 2).setValues([[new Date(), value]]);
}
At each run, the script appends two cells at the bottom of Sheet2: one with the timestamp (should be formatted as such), one with the value corresponding to that timestamp.
A version for storing a range of values such as B3:B7:
function storeValue() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
var values = sheet.getRange("B3:B7").getValues()[0];
var sheet2 = ss.getSheetByName('Sheet2'); // where to store the data
var height = sheet2.getLastRow();
sheet2.insertRowAfter(height);
sheet2.getRange(height+1, 1, 1, 6).setValues([[new Date()].concat(values)]);
// setting 6 cells instead of 2 on the previous line
}

How to get data from range of column cells using Google Apps Script(GAS)?

I want to get data from column A starting from cell A2 till cell A12. I try to use the following code but I keep getting error:
Cannot find method getDataRange(string). (line...
I don't want to use range = sheet.getDataRange(); because that will copy
entire sheet values! How I can fix above error ?
function getRangeData()
{
var sheet = SpreadsheetApp.getActiveSheet(),
range,
values_array;
range = sheet.getDataRange('A2:A12');
values_array = range.getValues();
Logger.log(values_array);
}
The getDataRange() function has no parameters. (documentation) You need to dig some more to find an alternate way to accomplish your wish.
The function that you are looking for is Sheet.getRange(), which supports several ways to express the desired range, including one that takes a string expressing a range in A1Notation.
function getRangeData() {
var sheet = SpreadsheetApp.getActiveSheet(),
range,
values_array;
range = sheet.getRange('A2:A12');
values_array = range.getValues();
Logger.log(JSON.stringify(values_array));
}