I am a new convert to Google from Microsoft and the comfort of VBA!
In a Spreadsheet I use
var range = sheet.getRange(2,1,sheet.getMaxRows()-1,sheet.getMaxColumns());
to work on all the columns and sort on multiple columns.
What I need to do is ignore the data in the first column and sort the rest.
An explained solution would be appreciated!
If you use range.getValues() you will get a 2 dimension javascript array, you can sort it the way you want and then you can rewrite its value to the sheet using
sheet.getRange(2,1, array.length,array[0].length).setValues(array);
Related
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)
I wish to append multiple rows to a google sheet via GAS whilst being considerate of performance and undesired possiblities.
To achieve this for a single row, I would use appendRow as this tackles problems with intervening mutations and completes all actions in a single function.
Simple Example:
var sheet= SpreadsheetApp.openById(ssId).getSheetByName(sheetName);
sheet.appendRow(["foo", "bar", "foobar"]);
Of course to extend this to multiple rows, I could simply loop over this function for each row, though GAS best practices advises against such practices.
Attempts to use appendRow to add multiple rows via a 2D array were unsuccessful and led to the API using references to the secondary arrays as the values going into the row.
I therefore ask, is there a way to append multiple rows to a spreadsheet that still tackles the intervening mutuability that appendRow does and avoids looping where possible?
You can use the Range.setValues() method which will set the values at once, and a script lock (or another lock, depends on your use case) to prevent other instances of the script from doing appends at the same time. You just need to get the good range (with array length) and the good position (with sheet.getLastRow() + 1 method). Here is an example:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var example = [[1,2,3],[4,5,6],[7,8,9]];
LockService.getScriptLock().waitLock(60000);
sheet
.getRange(
sheet.getLastRow() + 1,
1,
example.length,
example[0].length
)
.setValues(example);
Caveat: This does not protect against humans or other scripts.
I would make sure to also make a row & column variable for this snippet of code. Sometimes GAS will throw an error if you try to add the object.length directly in the getrange function. i.e.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var example = [[1,2,3],[4,5,6],[7,8,9]];
var row = example.length;
var column = example[0].length;
sheet.getRange(sheet.getLastRow()+1, 1, row, column).setValues(example);
You should check out the official documentation for the Sheet Class, there are a number of bulk row insert methods listed, one of which may fit your criteria. If that proves insufficient you may want to look into the Advanced Sheet Service.
EDIT
In response to your comment, I don't believe there is a way to add rows and data in bulk as a purely atomic operation. But there is a way to address your concerns regarding intervening mutations, via the LockService API. This service allows you to prevent concurrent access to a block of code, so for your use case you can leverage the bulk insert methods to create new rows and populate them without having to worry about mutations.
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(",");
I just want to confirm if there is any inbuilt function is google apps script to reorder the columns in the spreadsheet or do I have to do something like this -
var r = currentSheet.getRange(1, 1, currentSheet.getLastRow() - 1, currentSheet.getLastColumn()).getValues();
for(var i1=0, dLen=r[0].length; i1<dLen; i1++) {
//something to reorder
}
Please help!
it depends. if you just want to present the data in a different order, just use the built-in "=query" cell function, selecting the rows in the order you want.
query has some limitations thou. for example each column must have a consistent type on all rows (date, number, string etc). there arr other built-in functions that do similar things.
if you actually want to change the source range, you need to do it by getting the entire range array values, transforming it (possibly needing to take care of functions too) and writting the entire new array in a single range write.
I've just learnt about arrayformula and continue for keeping formulas into new rows, now im trying to get a single string to copy into new rows "N". How can I achieve this?
Basically, i've got some columns with formulas that are copied down using array formula, i've tried to use this to copy "N" into a column which needs to be pre-filled with "N" how it has not work, is there any other ways I can achieve this?
Overall I'm just asking is there a way to fill a single column with the letter "N" using either a formula or a script? If yes how?
Many thanks
The most efficient way using a script would be like this :
function myFunction() {
var s = SpreadsheetApp.getActiveSheet();
var col = [];
for(var n=0 ; n<s.getMaxRows();n++){
col.push(['N']);
}
s.getRange('N:N').setValues(col); // write data in any column, N in this example :-)
}
It creates a 2D array with the right value and size and writes it on the sheet in one single step.
Don't have a spreadsheet at hand to try, but try
= arrayformula(if(N:N=0;"N";"N"))