I want to save server calls and try to load the sheet into memory before other actions:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Condo1");
var allSheetData = sheet.getDataRange().getValues(); // load all sheet data into memory
var lastRow = allSheetData.getLastRow();
But the web console states:
Error TypeError: allSheetData.getLastRow is not a function
at [unknown function](Code:9:28)
Is getLastRow() only applicable for sheets, not for other arrays of data?
I could not get an explicit answer in the documentation.
After help with the getLastRow() - thanks Marios! - I still am puzzled about the underlying objective, to minimize server calls. I have made a similar script where I get annoyed with the long execution time due to calling for every row, especially in longer tables. Now I wanted to make it better and manipulate the table locally. I am sure there are plenty similar issues on SO for google apps script, if I only could get a good search term. "async bulk request" did not give me good hits on SO.
Then I can start with selfstudy. Thank You!
Issue:
As you can see in the official documentation getLastRow is a function applied to a sheet object.
You are trying to apply getLastRow() to a 2D JavaScript array: [[x1,y1],[x2,y2]] and this is why you are getting a message that getLastRow can not be applied to a JavaScript array.
Solution:
You have two options:
Use the built in JavaScript array method length on allSheetData to get the number of "rows" this data array occupies:
var lastRow = allSheetData.length;
Apply getLastRow on the sheet object:
var lastRow = sheet.getLastRow();
Please note:
Make sure to understand what getLastRow() returns which is the last row in the sheet that has content.
In your case you are using getDataRange which implicity uses getLastRow to calculate the range. But if you want to manually define a range object, then length and getLastRow might give different results!
Related
I created an item named “import” under the menu “database” in my google sheet. What I want to execute with this item is that the excel file, with two columns only, can be uploaded and the values nested within them can be stored in an array without appending a new spreadsheet for this excel file. However, I got stuck in “how to upload excel file” this way. After loading the array with the newly uploaded data, another function will be called to add the name-style pair which doesn’t exist in sheet 1 from the array to the unoccupied cells. So this item is designed for updating the sheet1 automatically.
function interface() {
var ui = SpreadsheetApp.getUi();
var menu=ui.createMenu("Data base")
menu.addItem("Import","cal")
menu.addToUi()
}
function onOpen(){
interface()
}
function cal() {
var ss = SpreadsheetApp.getActive().getSheetByName("updated list");// I don't know how to accomplish this part so I created a sheet to store the data as an alternative for the time being.
var lastRow=ss.getLastRow()
var dataBase=ss.getRange(2,1,lastRow,1).getValues()// I want to store the valuse nested within this two columns but there is an error when I use "indexOf" to pick out the data which doesn't exist in sheet1 and push it to the unoccupied cells so I only take one column of values here(Making it one level deep only).
var dataBase2=ss.getRange(2,2,lastRow,1)
var ss1 = SpreadsheetApp.getActive().getSheetByName("sheet1")
var lastRow1=ss1.getLastRow();
var storedData=ss1.getRange(2,1,lastRow1,1).getValues()// Faced with the same problem as described above.
for(var i=0; i<lastRow1;i++){
if(storedData.indexOf(dataBase[i])==-1){
var counter=1
ss1.getRange(lastRow1+counter,1),setValue=dataBase[i]
ss1.getRange(lastRow1+counter,1),offset(0,1),setValue=dataBase2[i]// The error "offset is not defined" shows up here
Logger.log(ss1.getRange(lastRow1+counter,1),setValue=dataBase[i])
counter++
}
}
}
Sheet1 is the worksheet used for looking up who takes charge of which style
Updated list contains the data which I want to add to the array
The logic is that me and my team mates can just take a look at the sheet1 to look for the merchandiser(Name) to know the style he or she takes charge of. But this list should be updated at least once a week. So I wonder if it's possible to automatically add the names and styles in the "updated list" to sheet1 when there is no match found.
For example:
Jason S55567899 and
Nick Jack52578 should be added into worksheet1 right below the last occupied row since these two styles don't exist in sheet1 yet.
I am creating employee rosters for each division at my job that need to be checked daily. I have the roster and I would like to create a certain date range worth in a workbook for each division. I have the first sheet dated 090120, for example, and need to duplicate and rename up to 091220. Is there an easy way to do this without having to right click, duplicate, right click, rename on each tab? All the information for each one is identical and there are no formulas or anything like that. I am new to Google Sheets and am not tech savvy at all but there has to be an easier way to do this.
Solution:
function duplicateSheet(){
const ss = SpreadsheetApp.getActive();
const src_sheet = ss.getSheetByName('090120');
const dupl_sheets = ['090220','090320','090420','090520','090620',
'090720','090820','090920','091020','091120','091220'];
dupl_sheets.forEach(sheet=>{
var dupl_sheet=src_sheet.copyTo(ss);
dupl_sheet.setName(sheet);
});
}
Explanation:
dupl_sheets contains the names of the duplicate sheets you want to create.
forEach() is used to iterate over dupl_sheets and for every
sheet name it creates a sheet that is a duplicate of src_sheet.
Instructions:
Click on Tools => Script editor:
Copy/Paste the aforementioned code into the script editor and click run:
Result:
My basic problem is this.
I will be taking data from a Google Sheet that looks a LOT like this:
My current code is basically grabbing the selection turning it into a Range[], turning that into an object array, and going through that array row by row.
Here is the code:
var sheet = ss.getActiveSheet();
var ranger = sheet.getSelection().getActiveRange();
var num = ranger.getNumRows()
var dataArray = ranger.getValues();
for (var i = 0; i < num; i++) {
From here, I open the Doc from Template and replace placeholder values with those procured above:
body.replaceText("##SONG NAME##", songname);
body.replaceText("##Artist##", artist);
Each ROW of data is a new copy of a Google Doc.
So, in superficial terms:
I grab all data. Put it into an object array. Then for each row of the array (which is a different song for our business), I open a new doc, replace the data. Rename, save and close the doc.
Cleanse, Repeat.
I could create a business case to APPEND data to the same document.
Thus grab all data, put into object array, then each row is a new appended SECTION of the same document. Once the for loop ends, we rename, save close...
And that leads to my question:
What are the server implications of what I'm doing? What are the performance hits?
If I want this to run as quickly and efficiently as possible should I change the way I'm collecting data? How I'm passing and replacing the data in the target doc? Should I append? Or is it not a big hit to create anew each time?
I'm just looking for knowledge about the code running optimally, please don't surmise about business or aesthetics.
In Google Sheets looking as part of a script to store data in a range to an array then to check whether a certain column has an "Y" in so I can loop through and store these columns in new arrays.
I have the following code but am getting this error - "TypeError: Cannot read property "0.0" from undefined."
var data = sheet.getRange("A6:U37").getValues;
if (data[20][i]=="Y"){
(The if code is generating the error)
Believe I am misunderstanding how the range is stored in the array causing the error any advice?
In the first line of code you provided, you are referencing the function getValues rather than actually calling it. In order to do so, you just have to modify the code as follows:
var data = sheet.getRange("A6:U37").getValues();
if (data[20][i]=="Y"){
Next time you have issues similar to this one, you can consider using logging or other debugging techniques in order to debug your script.
I need a JavaScript method for my webpage to count how many rows are in a Google sheet (it's used as a response sheet for a form). I've been scouring the web for easy tutorials on how to make Google Sheets into a database.
Is there a simpler way to do it?
I don't have much experience in Google scripts, but all I need is a way I can have read access to the spreadsheet using preferably Ajax or some similar JavaScript method.
To retrieve the number of rows in your Google Spreadsheet use the following:
var ss = SpreadsheetApp.openById("1qNCf0wKl................");
var sheet = ss.getSheetByName("sheet_name");
var number = sheet.getMaxRows().toString();
var number = number.replace(".0","");
Logger.log(number);
In order to have read access to a Spreadsheet the guidance provided in the following link is good enough:
Query Google Spreadsheet with URL Parameters
For example, if you want to get all the cells with the word «budget» in your Spreadsheet, use the following script:
var id = "1qNCf0wKlx1RF......";
var column = "A";
var query = "budget";
var url = "https://docs.google.com/spreadsheets/d/"+id+"/gviz/tq?tq=SELECT%20*%20where%20"+column+"%20contains%20%22"+query+"%22";
var text = UrlFetchApp.fetch(url).getContentText().toString();
Logger.log(text);
For this, the Spreadsheet has to be published previously. After retrieving the «budget» rows the text has to be formated, but that's another issue.
Here is what you can do
Write a simple Apps script using ContentService that will return a JSON with the number of rows in the spreadsheet (and any other info you need). To get the number of rows, you can use the getLastRow() function
Publish your script as a service(web app) and make an AJAX call from your JS code.