I used the following function to iterate CONCATENATE in the spreadsheets. However, it shows the following error
Missing; before statement. (line 11, file "Code").
function iterate()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var startRow = 2;
var lastRow = sheet.getLastRow();
for (var i = startRow; i <= lastRow; i++)
{
var result(i) = =CONCATENATE("http://cdn.staticmb.com/mbphoto/property/original_images/",A(i), "/ ",E(i), "/" ,C(i),"/",D(i)) ;
var range = sheet.getRange("F2,F15");
range.setValues(result(i));
}
}
Besides several javascript syntax errors like those pointed out in comments, the biggest issue is that you are trying to use "=CONCATENATE" in javascript. Its not a javascript function, none of the sheet cell formulas are, those can only be used inside sheet cells. You need to code the concatenation using javascript functions or operators like var a= b + "x" + d. That cleared out it should be easy to code it or google for it. You are also using result(i) where apparently you want to use an array. Look up the correct syntax for creating and adding elements to an array in javascript.
Related
I want to run a script that copies a sheet data to a master sheet (append all my sheets).
The first part of copying and pasting is working but I want to add a column which tells me the name of the origin sheet. I wrote a loop for it but nothing is happening when I executing the script (only the copy and paste). This is my whole code:
function appendSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getActiveSheet();
var reportLastRow = sh.getLastRow()
var reportLastColumn = sh.getLastColumn()
var reportData = sh.getSheetValues(3,1,reportLastRow,reportLastColumn);
var recordsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("2020 Data");
var lastRow = recordsSheet.getLastRow();
//var recordLastRow = sh.getLastRow();
var recordLastColumn = recordsSheet.getLastColumn();
var reportSheetName = sh.getSheetName();
recordsSheet.getRange(lastRow + 1,1,reportLastRow,reportLastColumn).setValues(reportData);
var arrayLength = (lastRow - reportData.length);
for (var i = 0 ; i <= arrayLength ; i ++) {
var taskDateCell = recordsSheet.getRange(arrayLength - i, recordLastColumn);
taskDateCell.setValues(reportSheetName);
}
}
Your code has several problems you should fix
Be aware of the fact that the method getRange() expects the syntax firstRow, firstColumn, numRows, numColumns - not firstRow, firstColumn, lastRow, lastColumn. You need to adjust your range and your function getSheetValues() (I assume it is you custom funciton based on the method getRange() accordingly.
If you assign a value to one cell at a time taskDateCell, you should use setValue() instead of setValues()
It seems like your definition of arrayLength might not be right. Test it by logging it.
Your main problem:
You define:
for (var i = arrayLength ; i < arrayLength ; i ++)
In other words:
Set i to arrayLength and iterate while i is smaller than arrayLength.
This condition is never fullfilled, and thus the number of iterations will be zero.
As a genral advice: Implement in your code many logs - to visualize important values, such a range notations and length of arrays, or counter variables in a loop - this will help you to find bugs faster.
Explanation:
First of all I optimized your code. You have unnecessary lines of code which make your code difficult to be understood but also slow. The optimizations involve reducing the number of lines to the minimum, defining constant variables, making the variable names more descriptive and finally getting rid of the for loop by replacing it with a more efficient approach.
Another correction would be at this line: sh.getSheetValues(3,1,reportLastRow,reportLastColumn); Here you are starting from the third row but you are getting two rows extra; reportLastRow is the number of rows you want to get but since you are starting from the third row you need to deduct 2.
To answer your question, one way to solve your problem is to set the name of the report to the last column of the records sheet where you entered the data from the report sheet. Since you want to add the same value (sheet name) to every row, you can select a 2D range but use setValue.
I am not a big fan of getActiveSheet in const report_sh = ss.getActiveSheet(); since this line is assuming that you have selected the desired sheet (report sheet) in the UI. Please be careful with that, otherwise change that line to something like that:
const report_sh = ss.getSheetByName('report sheet');
and of course adjust 'report sheet' to the name of the sheet you want to append.
Solution:
function appendSheet() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const records_sh = ss.getSheetByName("2020 Data");
const report_sh = ss.getActiveSheet();
const reportData = report_sh.getSheetValues(3,1,report_sh.getLastRow()-2,report_sh.getLastColumn());
const records_lr = records_sh.getLastRow();
records_sh.getRange(records_lr+1,1,reportData.length,reportData[0].length).setValues(reportData);
SpreadsheetApp.flush();
records_sh.getRange(records_lr+1,records_sh.getLastColumn()+1,reportData.length,1).setValue(report_sh.getSheetName());
}
I have a spreadsheet where every day a new column gets added with:
sheet.insertColumnAfter(6)
now i want to show/hide the columns starting at column(7) up till the last column of the sheet (which is a dynamic value).
i had the following thought and no idea why it doenst work:
function Historyausblenden() {
var bereich = SpreadsheetApp.getActive();
var letzte = bereich.getLastColumn();
bereich.getRange("G",letzte).activate();
bereich.getActiveSheet().hideColumns(bereich.getActiveRange().getColumn(), bereich.getActiveRange().getNumColumns());
bereich.getRange('F:F').activate();
}
It seems that getRange doesnt accept var letzte.
The errorcode says: "Methode getRange(string,number) not found!"
Why? What does that mean?
Several issues in your code.
You can't call getLastColumn() on a spreadsheet.
String concatenation in javascript is most easily done with + (e.g. "G" + letzte).
You can't activate a range without first selecting the sheet.
Lastly, you don't really need to activate to accomplish what you're trying to do, but you may have another reason for doing so.
Try this instead (and make sure you're selecting the correct sheet in the third line):
function hideHistory() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName("Sheet1");
var lastColumn = sheet.getMaxColumns();
var startColumn = 7;
sheet.hideColumns(startColumn, lastColumn-startColumn+1);
}
I set a different background color for the even rows from the Spreadsheet sheet using Google Apps Script but it is very very very slow...any ideas how can I optimize it?
Example Spreadsheet: https://docs.google.com/spreadsheets/d/1yRotjooCRpuuSTjjgFEzw4xxqPLJwMZJPchYQeNvUyw/edit?usp=sharing
See the GS code by going to Tools -> Script Editor...
This is the code:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var range = ss.getRange("A1:Z1000");
ss.setActiveRange(range);
var totalRows = SpreadsheetApp.getActiveRange().getNumRows();
var totalColumns = SpreadsheetApp.getActiveRange().getNumColumns();
var startRow = SpreadsheetApp.getActiveRange().getRow();
var startColumn = SpreadsheetApp.getActiveRange().getColumn();
var sheet = SpreadsheetApp.getActiveSheet();
var row = startRow;
while (row < totalRows+startRow)
{
var column = startColumn;
while (column < totalColumns+startColumn){
if(row%2 == 0){
sheet.getRange(row, column).setBackground("#F3F3F3");
}
column++;
}
row++;
}
}
You can use new applyRowBanding():
Applies a default row banding theme to the range. By default, the banding has header and no footer color.
Example:
function setColors() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var range = ss.getRange("A1:Z1000");
// first remove any existing alternating colors in range to prevent error "Exception: You cannot add alternating background colors to a range that already has alternating background colors."
range.getBandings().forEach(banding => banding.remove());
// apply alternate background colors
range.applyRowBanding();
}
Result:
For more options also see
applyRowBanding(bandingTheme)
applyRowBanding(bandingTheme, showHeader, showFooter)
Go line by line instead of cell by cell.
You can also loop directly on the lines you want to change.
function setBackgroundColorOnEvenLines() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var totalRows = sheet.getMaxRows();
var totalColumns = sheet.getMaxColumns()
for (var i=2; i <= totalRows; i+=2){
sheet.getRange(i, 1, 1, totalColumns).setBackground("#F3F3F3");
}
}
This reference shows how to reference an entire line like above.
While you've asked for a Google Apps Script solution, I prefer to set a conditional formatting by formula rather than do this as a scripted solution - I feel it's less complicated, faster and more intuitive.
=mod(A1,2)=0
Will format all even rows in the range defined.
You might also like to look into this call:
https://developers.google.com/apps-script/reference/spreadsheet/range#getbackgrounds
and its sister call
https://developers.google.com/apps-script/reference/spreadsheet/range#setbackgroundscolor
This returns a two dimensional array for the entire range of all background colours.
Using this you can get an array of the whole range, step through it in increments of two, and set all of the elements of each row to the alternate background colour you wish (perhaps using one of the methods described here: Javascript | Set all values of an array). Then at the end call setBackgroundColors(color) to set the colors.
This way, you only make one call to actually update the spreadsheet at the end - and that's the part that will take the most time and which will have slowed down your original code the most.
I am using Google app scrips and I want to iterate through a spreadsheet that will be updated weekly. (this is why i dont want to set a range i want to be able to iterate through the entire sheet.)
Is this possible? If yes can you give an example of how this would be done?
and if this isn't a good idea, why not?
Thank you!
Example code
function doGet(e){
var ss = SpreadsheetApp.openById('key in here');
var sheet = ss.getSheetByName("Form Responses");
var range = sheet.getRange(1,1);
var dataRange = range.getValue().toString();
app.add(app.createHTML("There are " + dataRange + " posts today"))
return app;
Something like this, but I want to be able to see the whole sheet not just the range
Henrique Abreu and Srik provided you with correct answer - getDataRange on sheet should serve your purpose.
function doGet(e){
var sheet = SpreadsheetApp.openById('spreadsheetId').getSheetByName('sheetName');
var data = sheet.getDataRange().getValues();;
...
}
data is now 2-dimensional array, you can iterate through it, get last column/row containing content etc. Please read through class reference here: https://developers.google.com/apps-script/reference/spreadsheet/sheet
You cannot iterate over the sheet by itself, but always iterate over the vales of range.
However you don't have to use a fixed range but can compute the range at every script execution.
To do this you could use getlastcolumn() and getLastRow().
This two methods return the last column or row with content in it.
A commodity method is getDataRange() which directly gives you the range with data in it.
Every script execution this range will extend over all your cells and columns with content.
Look at the example from Google API documentation:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// This represents ALL the data
var range = sheet.getDataRange();
var values = range.getValues();
// This logs the spreadsheet in CSV format with a trailing comma
for (var i = 0; i < values.length; i++) {
var row = "";
for (var j = 0; j < values[i].length; j++) {
if (values[i][j]) {
row = row + values[i][j];
}
row = row + ",";
}
Logger.log(row);
}
Hope that helps.
I'd like to unmerge all the cells of my google spreadsheet using script. I believe that VBA has this option (cells.unmerge) but I can't find a similar operation in GAS. I've tried this script but it didn't seem to work.
function MyFunction() {
var Sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var Range = Sheet.getDataRange().activate();
Range.clearFormat();
}
The correct word is "Range.breakApart" not "unmerge". Note that this only works when the range it is called on encompasses all merged cells.
Try this code:
function unmerge() {
var app = SpreadsheetApp;
// get current active sheet use single line coding
var activeSheet =app.getActiveSpreadsheet().getActiveSheet();
// get last row
var lstrow= activeSheet.getLastRow();
// see below description **
var mergerange = activeSheet.getRange(13,4,lstrow).getMergedRanges();
for (var i = 0; i < mergerange.length; i++) {
Logger.log(mergerange[i].getA1Notation());
Logger.log(mergerange[i].getDisplayValue());
mergerange[i].breakApart();
}
}
** 13= start row number. 4 = column number of merge cells.