function getInfo(){
var id = "xyz";
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
for (var i = 2; i < (lastRow + 1); i++){
var Emails = sheet.getRange(i, getColIndexByName("Email")).getValue();
var row = Compare(Emails, id);
if(row)
PlusFreq(row, id);
else if (checkEmail(Emails))
setEmail(Emails, id);
}
}
My code is working fine , but the method getLastRow();
isn't working it's getting null, Why that is happening?
A week ago it was working properly but now does not it, besides I use the method en getLastRow other functions and also was not this working anymore.
You might want to take a look at the following line in the documentation:
method getLastRow()
Returns the position of the last row that has content.
You may have to check that the sheet contains at least one row with content before you call the getLastRow() function.
I managed to fix the error but do not know what it caused it, simply deleted the blank lines that existed after the 60 lines of content, and added them again, so stopped the error, I'm sure the lines estavao blank. error crazy
Related
I'm trying to insert values into cells. Here is my code:
var values = [
["test1", "test2", "test3"]
];
var ss = SpreadsheetApp.getActiveSpreadsheet()
// var sheet = ss.getSheets()[0]
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var cellsToWriteTo = []
function testFunction() {
var activeCell = sheet.getActiveCell();
var firstRow = activeCell.getRow()
var firstColumn = activeCell.getColumn()
cellsToWriteTo = `["R${firstRow}C${firstColumn}:R${firstRow}C${firstColumn + 2}"]`
console.log(cellsToWriteTo)
var range = sheet.getRange(cellsToWriteTo)
range.setValues(values);
}
This gives me the error:
Exception: Range not found
However if I copy and paste cellsToWriteTo from the console log and put it into getRange.. it works perfectly every time..
Things i have tried so far:
Thought it was to do with not fetching the spreadsheet correctly (getActiveSpreadsheet().getActiveSheet()).
Fixed how my values were organised (into arrays within arrays)
Googled the error message and looked at how to properly getRange/setRange in the documentation and in tutorials. Apparently you cannot set arbitrary cells if you are calling them from the excel sheet itself. This is my suspicion as to what is going wrong here. However how can this be the case if when I put in a simple string it functions fine. I am simply doing string interpolation here.
I know this is rudimentary stuff, any help would be appreciated.
Removing both brackets and quotation marks should make it work
Modification:
cellsToWriteTo = `R${firstRow}C${firstColumn}:R${firstRow}C${firstColumn + 2}`
Execution:
Output:
I'm trying to make a script that, whenever triggered, runs through each row checking if the checkboxes in column F are checked. If so, the content of column A in that row is replaced with a 0. Upon running the code, nothing happens. I am not sure where the script gets caught up, but I would assume it's in the for() loop. I have also included a picture of the spreadsheet itself for easier understanding. Any help is appreciated.
My code:
function onEditButAgain(event){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var editedCell = sheet.getActiveCell();
var columnToSortBy = 6;
if(editedCell.getColumn() == columnToSortBy)
{
for(var x = 2; x<=100; x++)
{
var checked = sheet.getRange(x, 6);
if(checked.isChecked == true)
{
var date = sheet.getRange(x, 1);
date.setValue("0");
}
}
}
}
The image of the spreadsheet itself:
Explanation:
Your goal is to manually execute a script that will change the value in column A whenever the cell in the same row in column F is checked.
The obvious issue in the code is isChecked which should be isChecked(). You use parenthesis when you want to execute a function and in this case you want to execute isChecked.
In this case, an onEdit script will be redundant. If you want to use an onEdit trigger with the name onEditButAgain you have to create an installable trigger. But you don't need an installable trigger for this purpose.
Although you can wrap up the following code in this answer in a simple onEdit() function, the event object is not used and the code won't be 100% efficient. But if you want to run it manually, you don't need a trigger anyway.
When you use a loop, it is not a good practice to use methods like getRange or isChecked or setValue because these methods are computationally expensive and your script will very slow. Work with arrays instead and getValues/setValues.
Solution:
function myFunction(){
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1'); // change it to your sheet name
const valA = sh.getRange('A2:A'+sh.getLastRow()).getValues().flat();
const cb = sh.getRange('F2:F'+sh.getLastRow()).getValues().flat();
const new_valA = cb.map((c,i)=> [c ? "0" : valA[i]]);
sh.getRange(2,1,new_valA.length,new_valA[0].length).setValues(new_valA);
}
Update 2: It was a permissions issue. I guess I have to duplicate all my scripts for each spreadsheet? Also I'm updating my code now that I've fixed it.
Update: my code is wrong (I need to drop the second for loop I think) but my question is why the script isn't running on my sheets.
I'm trying to write data to columns in a spreadsheet. Maybe I'm just having permissions issues?
This is my first time using Google scripts and I'm not familiar with JavaScript either. I have a spreadsheet with a lot of data and I successfully removed duplicates as defined by comparing the first two columns--no bugs, no issues, ran successfully first try. Now I'm trying to fill in data on two new, empty columns.
If column 2 is in the format "foo - bar", I want column 3 to be "foo" and col 4 "bar". So I wrote this script:
function parseTypes() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var newData = new Array();
for (i in data) {
var row = data[i];
var str = row[2];
var strSplit = str.split(" - ");
row[3] = strSplit[0];
if (strSplit[1] == "" || strSplit[1] == null || row[4] == undefined) {
row[4] = "";
} else {
row[4] = strSplit[1];
}
newData.push(row);
}
sheet.clearContents();
sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}
I debugged in and the string array strSplit is accurately being set to "foo,bar". My issue is that it's not actually writing the data to my spreadsheet. I don't know if it's my code or if I'm just running the script wrong because I barely know what I'm doing.
JavaScript use 0 based indexes but SpreadsheetApp use 1 based indexes. This means that row[2] returns the value of column C not column B.
You don't have to copy the script. The only thing you need to change is not using the SpreadsheetApp.getActiveSheet, but you have to use the SpreadsheetApp.openByUrl('https://blalaallla').getSheetByName('blalala') method. This way you don't have to copy it. Hope this helps.
Sorry if this is a bit newbie.
What I'm trying to do is take a column and delete the values in some of its cells if they do not contain a formula.
function clean() {
var ss = SpreadsheetApp.openById("KEY_REMOVED_FOR_OBVIOUS_REASONS");
var sheet = ss.getSheetByName("TEST");
var limit = sheet.getMaxRows();
for(var i = 6; i < limit; ++i){ // Declares variable "i", which represents the row we are currently checking. Basically says "if our row isn't the last one, execute this block then add to i".
var range = sheet.getRange(i,2);
if (range.getValue() != "") { // Leverages the fact that .getValue() cannot return functions. If our range is blank, execute this block.
range.clear();
}
}
}
I established a loop which checks every row one by one. What I'm wondering is, is there a more efficient way to do this than having to call the server every time I do the loop?
getValues() exists of course, but I'm not sure how one might interact with only the desired cells returned by that.
I did some testing. .getValues() will return the computed values if there are formulas.
The following code works for me.
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getLastRow();
var range = sheet.getRange(1,1, rows);
var values = range.getFormulas();
range.clear();
range.setFormulas(values);
}
Short answer
Regarding the too many calls issue, use getLastRow() instead of getMaxRows() and use the returned value (number of rows) to get the required range in just one call.
Explanation
getLastRow() returns the position of the last row that has content while getMaxRows() returns the maximum height of a sheet regardless of content.
getRange(row, column, numRows) returns in just one call the complete range.
I have this code that I found online and it works as needed, but it works for all my sheets or the tabs at the bottom if you want to call them. I want it to work
function onEdit(event)
{
var sheet = event.source.getActiveSheet();
var eventRange = event.source.getActiveRange();
var eventColumn = eventRange.getLastColumn();
if (eventColumn == 1)
{
var stampRange = eventRange.offset(0,10);
stampRange.setValue(new Date());
}
}
This is the original code, I tried adding in line 4 the following but i can't get it to work. I'm not experienced with javascript but I need your help as i'm trying my best. Thank you.
if(sheet.match(/*.13/)){
This is the line I added. Based on my reading online, the script should works only if the sheet name ends with 13. But it's not working.
You've got the right idea, but sheet is a Sheet Object, while .match() is a String method. Use the Sheet.getSheetName() method to get the name of the sheet (the words on the tab).
In an onEdit(), you usually want to bail out without investing much processing time, so you should put the test for the sheet name as early as possible.
If you want to match "Sheet13" exactly, you should test for just that - because your regex will also match "Apollo13" and "a13a", for example.
function onEdit(event)
{
var sheetName = event.source.getActiveSheet().getSheetName();
if (sheetName.match(/.13/) == null)
// These aren't the droids you're looking for...
return;
var eventRange = event.source.getActiveRange();
var eventColumn = eventRange.getLastColumn();
if (eventColumn == 1)
{
var stampRange = eventRange.offset(0,10);
stampRange.setValue(new Date());
}
}