Reading a matrix of data into a script function from Google Sheets - google-apps-script

I am new to Google Sheet script so I am trying to learn by looking at other professional code. I have noticed that most routines that read in arrays use .getDataRange().getValues() which reads in the whole worksheet.
The worksheets I work on have lots of different data info on any one sheet. Is there an easy way to read in a subset of the sheet and not the whole sheet?
As an example: If I want to read in range D6:J45 (note the ranges can change based on user request):
How can I load in only that matrix data into a 2 dimensional array in Script?
If I have to use nested for loops, .length seems to get me # of rows, how can get number of columns in range?

Use getRange(a1Notation) to get the values of the specified range.
getValues() returns a 2D array. The number of columns corresponds to the length of the inner arrays, so you have to retrieve the length of an element of the outer array, as shown below:
var values = SpreadsheetApp.getActiveSheet().getRange("D6:J45").getValues();
var numberOfColumns = values[0].length;

Related

Using named ranged in google sheets as variables in custom formulas

Not sure if this is going to make sense but here I go.
What I want to do is to create a formula that isn't linked to a cell directly. In example: if I want to calculate carryweight for a tabletop game like D&D I would need the formula (strengthBonus x 5). For my current attempt I renamed the range (cell rather) strengthBonus to MOD_STR so when I put the formula =(multiply(MOD_STR,5) it works like a charm. Then I named that range "CARRYWEIGHT" and then use it elsewhere.
What I would like to be able to do is to make a new variable, similar to the way that "Define Named Range" does, but instead of relying on the variables being somewhere on the spreadsheet they would process from an internal formula. For example, if I type =carryweight into a cell it would run the equation =MULTIPLY(MOD_STR,5) in that cell and output the answer. I know nothing about code yet but have just been pointed in the direction of tutorials but I'm also asking for help here.
The code I have tried is
function CARRYWEIGHT(MOD_STR){
return MOD_STR*2}
and something else, I can't remember what but I got it to at least accept it in the spreadsheet. When I type it in I get an error stating that the outcome isn't a number.
I have no idea where to go from here.
Thank you in advanced for your help.
The difference between sheets formulas and Apps Script is that in Apps Script you need to retrieve the value of the range corresponding to the name of a named range
You cannot simply multiply the name of the range (which is a string!) with a number
Here is a sample of how to retrieve a range by name and make calculations wiht the value stored in it:
function CARRYWEIGHT(MOD_STR){
// retrieve all named ranges in the spreadsheet
var namedRanges = SpreadsheetApp.getActive().getNamedRanges();
//loop through all the results
for (var i = 0; i < namedRanges.length; i++){
var range = namedRanges[i];
//if the range with the name equal to the value of MOD_STR is found, get the cell content of this range
if(range.getName()==MOD_STR){
var value = range.getRange().getValue();
// perform the calculation with the cell content of the named range
return value*2;
}
}
}
From the cell, call the function as =CARRYWEIGHT("paste here the name of the range of interest"), do not forget the quotes (unless it is a cell reference)!
I hope this helped you to get started, for further understanding plese consult the following references.
References
Named Ranges
Loops
Conditional statements
Ranges
getValue()

Copying and pasting data in Google Sheets to another column

I have a dashboard that is reporting live data based on a growing customer database, and I am currently tracking the daily process by copying and pasting the data in the column into the next on a daily basis.
I'd like to create a script that automatically copies the values from an array (B:B) for example, into another sheet OR into the next available column to the right.
You may refer to the image below for further clarity.
Sample
I saw may threads on this but they were all about copying into a different row, as opposed to a different column.
Many thanks in advance!
The getLastRow() method is used to return the position of the last row that has content.
The getLastColumn() method is used to return the position of the last column that has content.
Therefore, in order to be able to copy the data into the next available column, I suggest you try this:
function copyColumn() {
var ss = SpreadsheetApp.openById("ID_OF_THE_SPREADSHEET");
var sheetFrom = ss.getSheetByName("SHEET_FROM");
var sheetTo = ss.getSheetByName("SHEET_TO");
var values = sheetFrom.getRange(NO_OF_THE_ROW_WHERE_DATA_STARTS, 3, sheetFrom.getLastRow(), 1).getValues();
sheetTo.getRange(NO_OF_THE_ROW_WHERE_DATA_STARTS,sheetTo.getLastColumn()+1,values.length,1).setValues(values);
}
The above script localizes all the data that needs to be copied by using the getRange() method and is copied by using getValues().
NO_OF_THE_ROW_WHERE_DATA_STARTS is the value representing the number of the row where your data starts (in your case the row of No of LP - Secured);
3 is the value representing the C column (where the data you want to be copied is located);
sheetFrom.getLastRow() is the value representing the end of the data you want to be copied;
1 is the value representing the number of columns that need to be copied.
Afterwards, the getRange() method is used again in order to be able to identify where the data needs to be pasted and setValues() in order to actually paste it.
Note: The above script works for different spreadsheets and/or different sheets OR for sheets in the same spreadsheet. If you want to use it for the latter case, you just have to put the name of your sheet instead of SHEET_FROM and SHEET_TO.
Moreover, I suggest you check the following links since they might be of help:
Sheet Class Apps Script - getRange();
Range Class Apps Script - getValues();
Range Class Apps Script - setValues();
Sheet Class Apps Script - getLastColumn();
Sheet Class Apps Script - getLastRow();

Google script copy data from a sheet to another in efficent way

I have to copy data from one spreadsheet to another.
On the source I have a sheet with columns DataName and DataID
I need to copy DataName column in SSdest sheet('Data'), DataID in SSdest sheet('ID').
I can do it in several ways, but I need to be time effective due to a big load of data. I pick data using Data = Source.getDataRange().getValues()
I can paste in the correct way using a for loop with setvalue() but is time-consuming. Is there a way to paste only one column from getValues data?
as #Casper told you, you can use range.getValues() to get a multidimensional array then use range.setValues(). You only need to set the range to one column to get all the datas wanted as so : sheet.getRange(rowNumber, columnNumber, numberOfRows).getValues().
One other solution would be to select all the datas with getDataRange(), then programatically using javascript create a new array you will then add using setValues(array)

How to use Google Apps Script to bring in Spreadsheet values efficiently

I currently use the following code to bring in many values from a spreadsheet
myValues["TitleText"] = ss.getRange('B9').getValue();
I then display the values in a index.html form using the same Google Apps Script like
<div id="title"><?= data.TitleText ?></div>
I was wondering if I should use something else. Maybe like an ArrayFormula?
I guess it looks to me like I am taking many trips back to the sheet to get all of the values that I need. It would be nice to get all values in one visit thus speeding up the loading and processing of the form.
If a one trip approach is possible; what would it look like?
If the data is in an array, there is no "built-in" way to associate one value with another value. With an object, you can associate the "key" with the "value". There are ways to do the same thing with arrays, but it's a lot "trickier". Whether you should use an array or an object, depends on the "bigger picture". If you want to associate a title with a value, and the position of the title and value could be changing in the spreadsheet, then it MIGHT make sense to compile the data in an object before sending it to your HTML. But then there is the issue of performance. It can be better to construct the HTML in the server code, and then send the HTML string back to the client, and not just the data.
If you have lots of scriptlets, you might try having just one printing scriptlet, create the HTML string in the ".gs" server code, and then send the HTML back instead of sending just the data back.
If you compile the data in some special format, send the data, then you need to unscramble the data and construct the HTML, that might be more processing than just building the HTML from the start in the server code.
The getRange() method has four different parameter configurations. You are using the a1Notation variation. I would use this variation:
getRange(starting row, starting column, number of Rows, number of Columns)
Then you can use code like this:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('the sheet name');
var allData = sheet
.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn())
.getValues();
If you only want to get the values in column B, starting in row 2, you can do this:
var colB_Data = sheet
.getRange(2, 2, sheet.getLastRow())
.getValues();
The getValues() method returns a two dimensional array. But if you are only getting one column of data, all the inner arrays only have one element. If you need a one dimensional array, you can (in this case) convert the two dimensional array to a one dimensional array with:
colB_Data = colB_Data.toString().split(",");

How do I create a Range class programatically in my google spreadsheet script?

So I have this google script that I want to use to create charts in my spreadsheet. I'm basically programatically creating content (with the use of spreadsheet data) that I then want to plot. The way I used to do it is by filling one of the sheets with all the data and then using that data to plot, but I was hoping to skip that step and feed the javascript arrays directly into my addRange method.
So I've got a script that creates a new chart:
// insert the scenario chart
var scenarioChartBuilder = sheet.newChart();
scenarioChartBuilder.setPosition(5, 6, 5, 5)
.setChartType(Charts.ChartType.AREA)
.addRange(rangeObject);
sheet.insertChart(scenarioChartBuilder.build());
The problem is; how do I make "rangeObject", given that I only have javascript arrays, and don't want to use actual spreadsheet data? Or is there another way of plotting data that isn't actually in a spreadsheet?
Range data is actually just a multidimensional array.
So a rangeObject could just be defined like;
var rangeobject = [[data, data, data],[data, data, data]];
The first array represents the row and the second array the column data.
programmatically you could get the data like;
var dataFirstRowSecondColumn = rangedata[0][1]; //0 indexed array!
So, to add a range is just to pass a multidimensional array (with content data).
But beware ;-) When adding to a chart i would think that you would have to mind that each column would only contain on kind of data to be valid.
In code you could directly use my first example.