Transporting ranges of values that are not in the same line - google-apps-script

I have this code bit where it gets some ranges and the get the values inside them, one by one. I've tried to use GetRangeList to shorten it, but i had issues using SetValues along it because they turned out to be a string. The code actually works, it does everything it needs to do, but i'm trying to optmize it. Is there any way?
I've also tried to specify the range as a matrix, like "E12:G15", but then it doesn't transpose to a whole line, it reads it as equal to the source.
var dados1 = origem.getRange("E12:G12");
var source1 = dados1.getValues();
var dados2 = origem.getRange("E13:G13");
var source2 = dados2.getValues();
var dados3 = origem.getRange("E14:G14");
var source3 = dados3.getValues();
var dados4 = origem.getRange("E15:G15");
var source4 = dados4.getValues();
sheetBase.getRange(sheetBase.getLastRow()+1, 1, 1, 3).setValues(sourceEqpt);
sheetBase.getRange(sheetBase.getLastRow(), 4, 1, 3).setValues(source1);
sheetBase.getRange(sheetBase.getLastRow(), 7, 1, 3).setValues(source2);
sheetBase.getRange(sheetBase.getLastRow(), 10, 1, 3).setValues(source3);
sheetBase.getRange(sheetBase.getLastRow(), 13, 1, 3).setValues(source4);

Use Array.concat(), Array.flat() and Sheet.appendRow(), like this:
const data = sourceEqpt.concat(origem.getRange('E12:G15').getValues()).flat();
sheetBase.appendRow(data);

Related

Copy specific Columns data from Last Row and paste to another sheet

I was trying to copy/fetch data from specific columns of the last row from my "Total" sheet, and pass those to another sheet named "vnSheet". The code below which i found earlier works fine. But, it copies all the row & column data from the mother sheet, which I don't want to happen.
function copySheet() {
var sourceSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Total");
var destSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("vnSheet");
var columns_to_be_copied = ['A', 'B', 'D', 'F'];
var columns_to_be_pasted = ['A', 'B', 'D', 'F'];
for (column in columns_to_be_copied) {
var copy_range_string = columns_to_be_copied[column] + ':' + columns_to_be_copied[column];
var paste_range_string = columns_to_be_pasted[column] + ':' + columns_to_be_pasted[column];
var source = sourceSheet.getRange(copy_range_string);
var destination = destSheet.getRange(paste_range_string);
source.copyTo(destination, {contentsOnly:true});
}
}
Here, I want to Copy 'A', 'B', 'D', 'F'(except 'C' & 'E' ) column data only from Last row of "Total" and paste those data into the same columns of the "vnSheet" but in the Last row. I searched almost all over the internet and found no solution of my problem, all I found was similar to the code above.
As I'm new to this, my coding experience is limited but I'm a gd learner :) Any help to solve that problem will be greatly appreciated.
Thank you.
So there are a few things
You currently are not getting the last row, as far as I can tell
You currently have duplicate variables to hold the same array
You currently are copying an entire row, which is not what you want
Assuming there are already values in columns C and E in your Target Sheet there are a few ways to approach a solution:
You get the existing values from Target Sheet and then overwrite the columns you want to overwrite, then you update the entire row using one array
You only overwrite the particular cells you want to update, leaving the rest as is
Option 1 above will be quicker, but we are speaking fractions of a second.
Therefore I recommend option 2, as it does not touch an existing row with field you don't want to change.
My proposal is here:
function copyHandler(){
const activeSheet = SpreadsheetApp.getActive()
var sourceSheet = activeSheet.getSheetByName("Total");
const sourceLastRowNum = sourceSheet.getLastRow()
var destSheet = activeSheet.getSheetByName("vnSheet");
const destLastRowNum = destSheet.getLastRow() + 1
const lastRow = sourceSheet.getRange(sourceLastRowNum, 1, 1, 6).getValues()[0]
lastRow.forEach( (value, index) => {
// Skip column C and column E
if( index == 2 || index == 4) return
destSheet.getRange(destLastRowNum, index+1).setValue(value)
})
}
Use sourceSheet.getLastRow() before the for loop to get the row number of the last row in your "Total" sheet, then add this value after each column letters.
Let's say that you assign the result of the above to a lastRow, then you can use this variable this way:
var copy_range_string = columns_to_be_copied[column] + lastRow + ':' + columns_to_be_copied[column] + lastRow;
NOTE:
You might find helpful to read https://developers.google.com/apps-script/guides/support/best-practices. This article suggest to avoid doing calls to Google Apps Script classes as they are slow. One way to reduce the number of calls do achieve the result that you are looking is by using getRangeList at it allows to get multiple ranges at once. Another way is by using the Advanced Sheets Service as it allow to do batch updates.

Exception: The starting row of the range is too small - Logs Numbers Why?

I have a basic script to take numbers from a sheet and use them to create a range, as well as using the last column function. I have had the error range is too small for the posting range.
When I log the output for both the column and row numbers these come out as expected!
I thought initially, it was because one was a last column pull and the other was pulling an integer from the cell in the sheets, as they were coming with decimal places, so I have overcome this with the conversion to number and then removing the decimals with the .tofixed() but this does not work either. Any ideas?
function weeklyData() {
var sourcess = SpreadsheetApp.openById('1B93Oq2s9Nou5hVgOb3y3t15t9xnqRMBnrYkAed-oxrE'); // key of source spreadsheet
var sourceSheet = sourcess.getSheetByName('Measures & Answers'); // source sheet name - change to your actual sheet name
var lr = Number(sourceSheet.getRange(2,3).getDataRegion(SpreadsheetApp.Dimension.ROWS).getLastRow()).toFixed(0);
for(var i=0;i<lr+1;i++){
var dataValue = sourceSheet.getRange(i+2,3).getValue(); //This weeks numbers to update into table
var rowdataRange = sourceSheet.getRange(i+2,4).getValue(); //The row that the data needs to be pasted
var rowformat = Number(rowdataRange);
var row = rowformat.toFixed(0);
var pasteSheet = sourcess.getSheetByName('WHERE DATA ENDS UP'); // Data is to be pasted - change to your actual sheet name
var pasteColumn = pasteSheet.getRange(12,12).getDataRegion(SpreadsheetApp.Dimension.COLUMNS).getLastColumn()+1;
var column = pasteColumn.toFixed(0); // Column that is free for this weeks data
var pasteRange = pasteSheet.getRange(row,column,1,1);
Logger.log(pasteRange);
// pasteRange.setValue(dataValue);
}};
Your script works fine for me. I suspect this is an example script you've adapted from somewhere and trying to apply it to your data structure?
The reason you are getting the error is probably because the data in column 4 of your source sheet is not of number format? Either change your data or change the following line to the column containing numeric values.
var rowdataRange = sourceSheet.getRange(i+2,4).getValue();
This script is poorly written for this particular use.
You might want to check your Spreadsheet since it has lots of random values at random ranges.
When you use the following command Logger.log(pasteSheet.getLastColumn()); the number returned is 3753: which means that that is the next available column at which your data will be pasted.
The error message you were getting is due to the fact that the range was incorrect and you were passing wrong values in order to access it, which was most likely because of the values mentioned above.
Moreover, after cleaning all the unnecessary data, you can make use of the below script.
Snippet
function weeklyData() {
var spreadsheet = SpreadsheetApp.openById("ID_OF_THE_SPREADSHEET");
var sourceSheet = spreadsheet.getSheetByName("Measures & Answers");
var pasteSheet = spreadsheet.getSheetByName("WHERE DATA ENDS UP");
var valsToCopy = sourceSheet.getRange(2, 3, sourceSheet.getLastRow(), 1).getValues();
var rowsAt = sourceSheet.getRange(2, 4, sourceSheet.getLastRow(), 1).getValues();
var column = pasteSheet.getRange(12,12).getDataRegion(SpreadsheetApp.Dimension.COLUMNS).getLastColumn()+1;
for (var i = 0; i < valsToCopy.length; i++)
if (rowsAt[i][0] != "")
pasteSheet.getRange(parseInt(rowsAt[i][0]), parseInt(column)).setValue(valsToCopy[i][0].toString());
}
Explanation
The above script gathers all the data that needs to be copied as well as the rows associated with it. In order to make sure you don't end up using inappropriate values for the ranges, an if condition has been placed to make sure the value is not empty.
Reference
Sheet Class Apps Script - getLastColumn();
Sheet Class Apps Script - getRange(row, column, numRows, numColumns);

Google Scripts function not doing anything (Google Script tied to Google Sheets)

I have this code on a dice roller sheet I'm trying to make. In column 1, I'm putting the number of dice being used, in column 3, I'm putting the type of dice used (d4 is 4, d6 is 6, d8 is 8, etc.), in column 5, I'm putting the interior modifier (mod for every dice), and in column 7, I'm putting the outside modifier (overall modifier after everything is rolled).
In column 9, everything is supposed to be consolidated as shown in the code below... But nothing's happening on the sheet itself.
Note: No listed errors, it seems to be running properly, but nothing's being displayed.
Quick edit, just for completeness' sake, I replaced all instances of " with ', nothing happened, which I figured, but I'm a bit new haha
function onEdit() { // Column 7
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Spreadsheet
var sheeta = "Rolls";
var sheet = ss.getSheetByName(sheeta); // Active sheet
var numberrange = sheet.getActiveCell();
numberrange = (numberrange.getRow(),1);
var typerange = (numberrange.getRow(),3);
var modrange = (numberrange.getRow(),5);
var outermodrange = (numberrange.getRow(),7);
var finalrange = (numberrange.getRow(),9);
var results = "=" + numberrange.getValue() +"*(TRUNC(RAND()*(" + typerange.getValue() + "-1)+" + modrange.getValue() + "))+" + outermodrange.getValue(); // =1*(TRUNC(RAND()*(6-1)+0))+0
finalrange.setValue(results);
}
This is not range numberrange = (numberrange.getRow(),1); rather this is just a (X,Y).
I don't know why you didn't mentioned, I think you must be getting error while executing the script.
To convert this into range you should do something like numberrange = sheet.getRange(numberrange.getRow(),1);
Here finalrange.setValue(results); results is a formula I guess, so kindly use finalrange.setFormula(formula) function.
Let me know if this doesn't solve your issue or if you have any doubt.

How to display the values in columns in Google app script

I got the output as below (row wise):
one
two
three
But I would like to display the value as below (column wise, single value in each cell):
one two three
Can any one please tell me how can I achieve this using getRange function in Google app script ?
Thanks.
Unless you are setting only 1 value, I recommend using getRange(startRow, startCol, numRows, numCols) together with Range class methods getValues() and setValues().
getValues() produces a 2d array which you can access with indexes (let's use integer variables row and col in our example) data[row][col]
So let's say you wish to set one, two, three to column A, B and C in row 1, then you simply have to do
var targetRange = SpreadsheetApp.getActiveSheet().getRange(1, 1, 1, 3)
var data = [['One', 'Two', 'Three']]
targetRamge.setValues(data)
Now let's say I want to write One, Two and Three into Column A over rows 1 2 and 3 then it is only slightly different:
var targetRange = SpreadsheetApp.getActiveSheet().getRange(1, 1, 3, 1) //we now get 1 column, but 3 rows
var data = [['One'], ['Two'], ['Three']] //Each array inside of the main array is a new row
targetRamge.setValues(data)
And there you have it. Simply manipulate the data as a 2D array all the time and use .getValues() and .setValues() with a range that uses multiple rows and/or columns.
Not sure if this is helpful. Have you heard about appendRow()? This will add your array to the last row of the sheet.
function append() {
var arr = ["a","b","c"]
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Entities')
sheet.appendRow(arr)
}

Getting server error message when referencing getLastRow()+1

I had a sheet that was working using some of the same code... In the last few days trying to work on my current project, stuff that used to work no longer works and I'm getting errors for all sorts of different stuff.
Currently, I can't move on until I figure this one out.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var clientList = ss.getSheetByName("ClientList");
var tracker = ss.getSheetByName("Tracker");
var tr_activeRow = tracker.getActiveCell().getRow();
var tr_clientName = tracker.getRange(tr_activeRow,1);
var tr_birthDate = tracker.getRange(tr_activeRow,5);
function addNewName() {
if(tr_clientName.getValue() == "New" && tr_birthDate.getValue() != ""){
tracker.getRange(tr_activeRow, 2, 1, 4).copyValuesToRange(clientList, 1, 4, clientList.getLastRow()+1, 1);
}
}
When trying to run the code I get:
We're sorry, a server error occurred. Please wait a bit and try again.
I've tried a few things and know that it's getLastRow()+1 that's the problem. I also tried getLastRow() & getLastRow()-1 to see if the code runs and it runs just fine. Only seems to be a problem when I'm using a positive integer...
What am I doing wrong?!? or is this a problem with sheets/apps script?
The parameters for copyValuesToRange() are:
copyValuesToRange(sheet, column, columnEnd, row, rowEnd)
You are designating the row end to be row 1.
.copyValuesToRange(clientList, 1, 4, clientList.getLastRow()+1, 1);
The rowEnd should be a number that is bigger than or the same as (for one row) the row parameter.
Your are only getting one row,
tracker.getRange(tr_activeRow, 2, 1, 4).copyVa . . . .
so the row and rowEnd should be the same.
var theLastRow = clientList.getLastRow()+1;
tracker.getRange(tr_activeRow, 2, 1, 4)
.copyValuesToRange(clientList, 1, 4, theLastRow, theLastRow);