Using Row() within a formula with appendRow - google-apps-script

So I'm pulling some data from GMail and adding a new row to a sheet that has a specific format. Name, Address, etc etc
On Column "P" I want to replicate the below:
=IF(NOT(ISBLANK($J3985)),"Replied", IF((TODAY()>=$O3985),"Late", "OK"))
However, I want to replace 3985 with Row(), for the row number that I'm appending, while I'm appending it. I've tried playing with: ADDRESS(row(),10) but this returns a string value that I can't seem to re-insert into a formula in a manner that works.
What I'm passing through in appendRow now:
var replied = "";
var later = x // a Date that's today + 6 weeks
var checkResult = `=IF(NOT(ISBLANK(` + replied + `)), "Replied", IF((TODAY()>=` + later + `), "Late", "OK"))`;
I want it so that I can populate the "responded" cell at a later point in the sheet and for this to still work. Would be keen to hear your suggestions for the same.

If you use appendRow:
=IF(NOT(ISBLANK(INDIRECT("RC[-6]",FALSE))),"Replied", IF((TODAY()>=INDIRECT("RC[-1]",FALSE)),"Late", "OK"))
If you use setFormulaR1C1:
Method A
Putting the row number directly with template literal
Method B
You could use setFormulaR1C1(formula)
'=IF(NOT(ISBLANK(RC[-6])), "Replied", IF((TODAY()>=RC[-1]), "Late", "OK"))';

Related

Trying to generate a unique code for every form reply

I am having some trouble getting a script that can generate a unique code for every form reply entry to work. Now, when I first tried writing it, I used the function name onFormReply(e) since I had read it somewhere, but turn out it didn't really work, so I'm trying to use onEdit(e), but it marks most values of the variables I wrote as undefined, even the argument (e) of the function itself (which is theoretically suposed to be custom and made to resemble the cell/s where the edit took place). Here is the code:
function onEdit(e) {
const ss = SpreadsheetApp.getActiveSheet();
const row = e.getRow();
var date = ss.getRange(row,1).getValue();
var department = ss.getRange(row,6).getValue();
department = department[0] + department[1]
var uniqueNumber = ss.getLastRow()
var finalCode = department + finalDate + uniqueNumber
ss.getRange(row,15).setValue(finalCode)
}
If you are dealing with Google Form responses, you can use the timestamp in column A as a unique ID. These timestamps are accurate down to the millisecond and will for all practical purposes always be unique.
The great benefit of this is that you do not need a script to get those unique IDs. Instead, use this array formula in row 1 of a free column in the right in the form responses sheet:
=arrayformula(
{
"Unique ID";
iferror( text( 1 / A2:A ^ -1, "yyyy-MM-dd_HH-mm-ss-000") )
}
)
The formula will fill the whole column automatically and will continue giving more results as new form responses are submitted.

Google Apps Script extract specific columns from sheet and put into new sheet using filter & map -- slow

Thanks in advance for your help. I'm new to apps script.
I have a gsheet with 98 columns and 25000 rows. All I want to do is copy 24 of the 98 columns to a new sheet.
Currently I am using filter & map, and it works:
var data = sourceSheet.getDataRange().getValues(); //read all columns & rows into array
var filterData = data.filter(function(e, j){return j > 0 && e}).map(function(e){return [e[88], e[14], e[13], e[4], e[17], e[87], e[91], e[48], e[57], e[31], e[89], e[82], e[70], e[97], e[47], e[30], e[72], e[71], e[67], e[34], e[33], e[00], e[38], e[39]]}); //extract just the columns I want into a new array
but that 2nd line takes almost an hour to execute! I presume because it is processing every element 1-by-1, even though it is just to return each one.
I haven't tried getValue'ing and setValue'ing columns one at a time because everything I read says limit external calls and do everything in memory. And I can't imagine pushing elements 1-by-1 would be faster than filtering.
Suggestions for faster execution?
function doCopy(SpreadID, OrgSheet, DestSheet, OrgRange, Sql, DestCell) {
var mySpread = SpreadsheetApp.openById(SpreadID);
var myQry = '=QUERY(' + OrgSheet + "!" + OrgRange + ',\"'+ Sql + '\")';
var myDestSheet = mySpread.getSheetByName(DestSheet);
myDestSheet.getRange(DestCell).setFormula(myQry);
}
Sample to call, but the destination sheet must be blank:
doCopy(spreadsheetId,"Sheet1", "Sheet2", "A:G", "Select A, C, F", "A1");
Another way to look at the problem which might be more time-effective and easy to implement is the following :
Duplicate the original sheet into a new one with copyTo(spreadsheet) (https://developers.google.com/apps-script/reference/spreadsheet/sheet#copytospreadsheet). You might also want to check this post for more information about creating a sheet into the same spreadsheet (Google Script to Duplicate Sheet that is Not Active)
Delete the columns you don't want to keep with deleteColumn(columnPosition) or deleteColumns(columnPosition, howMany)(see https://developers.google.com/apps-script/reference/spreadsheet/sheet#deletecolumncolumnposition).
You might also want to start deleting columns from the right side of the sheet to make the implementation easier.
Let me know if it helps.

Google Sheets Script .getValue() and .getDisplayValue() returning #REF For Some Reason

I had this function working before, but for some reason it is not working anymore.
This is a picture of the three pieces of data I am trying to collect. They have references to a couple other sheets in my file including some 'INDIRECT's. The following is the simple code I am trying to run to obtain the value of one of the pieces of data:
var ss = SpreadsheetApp.openById(logKey).getSheetByName("Investing");
var value = ss.getRange("G2").getValue();
var formula = ss.getRange("G2").getFormula();
Logger.log("Value: " + value + " Formula: " + formula);
... And this is the output:
[16-10-06 09:50:04:531 EDT] Value: #REF! Formula: =AD$2
As you can see from the output, it is successfully reading the cell from the spreadsheet, but it is not obtaining the value from the cell, just the formula. I don't understand why this is the case as in my sheet, the value it is trying to obtain is not '#REF!'.
As I said before, I had this general piece of code working before, but I must have changed something such that it broke what I am attempting to do.
Additional note: I am unsure if this code may be the culprit for some reason, even though it worked like this before. This is simply to convert columns numbers to row numbers form another sheet for easy copy and paste:
=INDEX(
INDIRECT(
CONCATENATE("QUOTES!",
REGEXEXTRACT(ADDRESS(ROW(), ((ROW()-3)*5)+4), "[A-Z]+"),
"4:",
REGEXEXTRACT(ADDRESS(ROW(), ((ROW()-3)*5)+4), "[A-Z]+")
)
),
COUNT(
INDIRECT(
CONCATENATE("QUOTES!",
REGEXEXTRACT(ADDRESS(ROW(), ((ROW()-3)*5)+4), "[A-Z]+"),
"4:",
REGEXEXTRACT(ADDRESS(ROW(), ((ROW()-3)*5)+4), "[A-Z]+")
)
)
)
)
Short answer
To avoid the #REF! error, the formula should not be placed on the second row. It could be placed on row 3 and below rows.
Explanation
ADDRESS(ROW(), ((ROW()-3)*5)+4) on any cell of row 2 returns the following error message:
Function ADDRESS parameter 2 value is -1. Valid values are between 1 and 18278 inclusive.

Setting a specific cell on the active sheet

I am attempting to set the value of a single cell on the active spread sheet. I know that I can uses .setValue to record a value to a single cell range. I want to get the range of a single cell than use .setValue to give it a specific value. I am using the following
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var testing_range = sheet.getRange("range_BOL_number");
logger.log("Rows: " + testing_range.getHeight() + " Columns: " + testing_range.getWidth());
var cell = testing_range.getCell(1, 0);
cell.setValue('999');
The problem is that when I try and run it, I get an error that says that the getCell call is out side of the range. The log entry tells me that testing_range is 2 rows by 1 column. Not sure what I am doing wrong as I copied the getCell code from the documentation.
its because getCell parameters are not zero based but one-based. you can see that from the example in the official docs. it uses getCell(1,1) to get the first cell from the example range:
https://developers.google.com/apps-script/reference/spreadsheet/range
personally i think it should be zero based as the parameters are not really "row" and "column" but a delta.

Get a specific cell value in a Google Spreadsheet Script

I am trying to modify a little script to email myself the results of a Google Form.
The script is working in its basic form, but I can't seem to be able to retrieve the value from a cell and copy it in the subject field.
Here is what I am trying:
var lastRow = SpreadsheetApp.getActiveSheet().getMaxRows();
var title = SpreadsheetApp.getActiveSheet().getRange(lastRow, 2).getValues();
var subject = "Todo List: " + title;
The script stops working though, when I do that :)
Any idea why? Thanks
Never tried this but looking at 'title' you have ...getValues() suggesting a collection of titles which you assign to a single variable what does getValues()[0] give you. Try indexing into that collection maybe..
getValues() will return a 2-dimensional Javascript array (so I think getValues()[0][0] should work); but as you are wanting to retrieve a single value from a single cell, you may as well just use getValue().
var title = SpreadsheetApp.getActiveSheet().getRange(lastRow, 2).getValue();