I have a named range in Google Sheets (A1:K14). All I'm trying to do is add a new row at the bottom of the named range. It seems like an easy task. The named range doesn't expand using this code and I don't get an error message. It does insert a new row outside of the named range, which is not what I'm trying to do. If I change to insertRowBefore (lastRow), the new blank row is inserted and the named range is expanded. I'm teaching myself GAS, so this is probably a simple mistake on my part
var sheet = SpreadsheetApp.getActiveSheet()
var Range = sheet.setActiveRange(range);
var data = Range.getValues();
Logger.log(range.getA1Notation());
var lastRow = SpreadsheetApp.getActiveSheet().getRange('DataRange').getNumRows();
SpreadsheetApp.getActive().insertRowAfter(lastRow);
return range;
Adding rows and/or columns to a namedRange
This function has the defaults setup to add one row.
//r is number of rows to add
//c is number of columns to add
function addRowAndColumnsToNamedRange(name,r,c) {
var name=name||'One';//default name
var r=r||1;//default number of rows to add
var c=c||0;//default number columns to add
var ss=SpreadsheetApp.getActive();
var nrgA=ss.getNamedRanges();
for(var i=0;i<nrgA.length;i++) {
if(nrgA[i].getName()==name) {
var nr=nrgA[i];
var h=nr.getRange().getHeight();
var w=nr.getRange().getWidth();
var sh=nr.getRange().getSheet();
var row=nr.getRange().getRow();
var col=nr.getRange().getColumn();
var rg=sh.getRange(row,col,h+r,w+c);
ss.setNamedRange(name,rg);
break;
}
}
}
Class NamedRange
Class Range
I think one of the approach can be to get that NamedRange and expand it explicitly.
Something like this:
Get that NamedRange using getNamedRanges() :
Set range of that NamedRange including new row using setRange(range)
Related
I've got limited knowledge of google script and I'm trying to get better every day. I'm trying to conditionally set the value of 2 cells based on the value in cells contained in other rows. I've got a sample sheet (here) with appointments on it. You'll also see the output desired on the output sheet.
When two or more appointments are taken by the same person based on his email address I want to write Yes in column Duplicate for every duplicate appointments but the most recent (based on Column E, that is the date when the appointment was created) and that are greater than the current date (if the appointment is already in the past no need to do anything). I also want to set the value of the column L to "Not Coming" which is a cell containing a data validation that I already automated on my main spreadsheet.
Here is the script that I already designed based on other questions answered here on stackoverflow. I'm not really familiar with indexes and how to proceed with them. The script runs without errors but nothing happens.
var currentDate = new Date()
// Master
var sheetMaster = ss.getSheets()[0];
var allValues=sheetMaster.getRange(2,1,sheetMaster.getLastRow()-1,sheetMaster.getLastColumn()).getValues();
var emailValues=sheetMaster.getRange(2,3,sheetMaster.getLastRow()-1,3).getValues();
var dateCreatedAtValues=sheetMaster.getRange(2,5,sheetMaster.getLastRow()-1,5).getValues();
var duplicateColumn=sheetMaster.getRange(2,11,sheetMaster.getLastRow()-1,11);
var eM=[];//emails
var dA=[];//dates
var eR=[];//entire rows
var dC=[];//duplicateColumn Yes or empty
function analyzeDuplicateEntries() {
for(var i=0;i<emailValues.length;i++) {
var idx=eM.indexOf(emailValues[i][0]);
if(idx==-1) {
eM.push(emailValues[i][0]);
dA.push(dateCreatedAtValues[i][0]);
eR.push(allValues[i]);
}
else if(new Date(dateCreatedAtValues[i][0]).valueOf() > new Date(dA[idx]).valueOf() && new Date(dateCreatedAtValues[i][0]).valueOf()> currentDate) {
duplicateColumn[i][0].setValue("Yes");
}
}
} ```
You are retrieving the wrong column and set the values to a range cell incorrectly
var mailValues=sheetMaster.getRange(2,3,sheetMaster.getLastRow()-1,3).getValues(); will return columns 3 to 5 (see documentation, while your emails are in column B, that is column 2.
Pay attention that the first parameter in getRange(row, column, numRows, numColumns) is the number of the columns to retrieve, rather than the last column
Mind that to use setValue on a range that contains more than one cell, you need to retrieve first the respective cell with getCell()
Take thereby into consideration that the cell indexes start with 1 (opposed to array indexes that start with 0`).
A simple (not optimal) way to rewrite your code would be:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var currentDate = new Date()
// Master
var sheetMaster = ss.getSheets()[0];
var allValues=sheetMaster.getRange(2,1,sheetMaster.getLastRow()-1,sheetMaster.getLastColumn()).getValues();
var emailValues=sheetMaster.getRange(2,2,sheetMaster.getLastRow()-1,1).getValues();
var dateCreatedAtValues=sheetMaster.getRange(2,5,sheetMaster.getLastRow()-1,1).getValues();
var duplicateColumn=sheetMaster.getRange(2,11,sheetMaster.getLastRow()-1,1);
var eM=[];//emails
var dA=[];//dates
var eR=[];//entire rows
var dC=[];//duplicateColumn Yes or empty
function analyzeDuplicateEntries() {
for(var i=0;i<emailValues.length;i++) {
var idx=eM.indexOf(emailValues[i][0]);
if(idx==-1) {
eM.push(emailValues[i][0]);
dA.push(dateCreatedAtValues[i][0]);
eR.push(allValues[i]);
}
else if(new Date(dateCreatedAtValues[i][0]).valueOf() > new Date(dA[idx]).valueOf() && new Date(dateCreatedAtValues[i][0]).valueOf()> currentDate) {
duplicateColumn.getCell(i+1, 1).setValue("Yes");
}
}
}
I am trying to automatically fill in the last row of a Google Sheet into a range from C2:K{{last_row}}. However, I am not sure how to proceed given my following code:
var dataSpreadsheetUrl = "https://docs.google.com/spreadsheets/sjhsak";
//make sure this includes the '
var ss = SpreadsheetApp.openByUrl(dataSpreadsheetUrl);
var deck = SlidesApp.getActivePresentation();
var sheet = ss.getSheetByName('Form_Responses');
var values = sheet.getRange('C2:K{{last_row}}').getValues();
How would I do this?
I am not sure what is your goal, but you must be looking for this:
sheet.getRange(`C2:K${sheet.getLastRow()}`).getValues();
If you want to store values starting from the last row and first column you could do this:
sheet.getRange(sheet.getLastRow()+1,1,values.length,values[0].length).setValues(values);
References:
getLastRow()
Template literals
Trying to combine two scripts here:
1) Get a cell value in a specific sheet
function getval() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('master'), true);
spreadsheet.getCurrentCell().offset(2, 4).activate();
};
2) Create a new sheet and rename it according to cell value
spreadsheet.insertSheet(1);
spreadsheet.getActiveSheet().setName('');
The second step is where I struggle. How can I use the results of the getval function as a variable to place inside setName?
function insertAndNameNewSheet() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('master');
var name=sh.getCurrentCell().offset(2, 4).getValue();//2 rows down and 4 columns to the right
ss.insertSheet(name,1);
}
insertSheet(name,index)
Best Practices
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);
}
So I've created a program that is supposed to mark one of multiple columns when the if conditions are met, so we can categorize our marketing sectors.
If you look at the last line of code you will see sheet (which encapsulates everything) getRange (which defines the range that the next part,getCell should be inside of ) and then you will see getCell.
I added +1 to the get cell Variable because it is not considered an array and therefore doesn't start with zero, which means it an sum of 4 would start in fourth row (as opposed to the 5th row for arrays).The problem is that I get a "Cell reference out of range and google script editor will highlight the aforementioned row.
If the get range is within the sheet, and the getCell is within the getRange I dont know how this could happen.
function myFunction() {
var app = SpreadsheetApp;
var sheet = app.getActiveSpreadsheet().getActiveSheet();
var lr= sheet.getLastRow();
var dataRangeContact = sheet.getRange("B4:B"+lr);
var dataContact = dataRangeContact.getValues();
var dataRangeComp= sheet.getRange("M4:M"+lr);
var dataComp=dataRangeComp.getValues();
var IndigoColumn= sheet.getRange("L4:L"+lr);
var validIndigoColumn =12;
var validLabColumn=11;
var validDesColumn=10;
var validPocColumn=9;
var validArtColumn=8;
for(var i=3; i<=lr; i++) {
var lr=sheet.getLastRow();
var rowTwo=dataContact[i].toString();
var rowThirteen=dataComp[i].toString();
if (rowThirteen=="University Lab") {
if (rowTwo.match(/(process engineer|analytical chemist|scientist|sr.scientist|research scientist|test Engineer|Medical Devices professional|scientific)/i)) {
sheet.getRange(4,12,lr).getCell(i+1,validIndigoColumn).setValue("Y");
}
}
}}
I think this is the same function rewritten a little differently. It will most likely run faster. It only has one range so it may be easier to avoid range errors. Keep in mind that rows and columns start at 1 and array indices start at 0.
I sometimes do this sort of thing to keep them straight.
Anyway here's my shortened version of the function:
function myFunction(){
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var vA=rg.getValues();
for(var i=3;i<vA.length;i++){
if(vA[i][12]=='University Lab' && vA[i][1].toString().match(/(process engineer|analytical chemist|scientist|sr.scientist|research scientist|test Engineer|Medical Devices professional|scientific)/i)){
vA[i][11]='Y';
}
}
rg.setValues(vA);//rewrites the data into the range including all changes all at one time
}
I have no way to test it.