google sheets script get cell contents - json

I have a list of URLs in a google spreadhseet and I want to get the cell reference to be used as a URL in the script.
An example of a URL I will be getting data from: https://politicsandwar.com/api/nation/id=31831
I want to do something like getValue.("O2") or var urlData = "O2" but I don't know how to go about getting to that point.

You should first get a range and then get its values.
var sheet = SpreadsheetApp.getActiveSheet();
//Gets all cell values form column "O" starting from row 2. Returns a 2d array
var wholeColumnUrls = SpreadsheetApp.getActiveSheet().getRange("O2:O").getValues();
//Gets value from specific cell "O2".
var singleCellUrl = SpreadsheetApp.getActiveSheet().getRange("O2").getValue();
There are multiple ways of defining a range, in this example we use the A1notation variant. Which seems to be what you're looking for.
Also, notice the difference between getValues() and getValue(). The first returns a 2d array like:
[
[https://politicsandwar.com/api/nation/id=31831]
,[https://politicsandwar.com/api/nation/id=31832]
,[https://politicsandwar.com/api/nation/id=31833]
]
while the latter returns a single value like https://politicsandwar.com/api/nation/id=31831
That way you can choose wether you get all the values and iterate over them, or have your own logic to determine each cell and get the values separately.

Related

Google Sheets Apps Script, return random item from named range

I'm trying to create a custom function that I can give a name range as input and have it output a random item from the name range. I have multiple named ranges so it would be convenient to have one function that I could use for all of them. This is what I'm trying to replace =INDEX(named_range,RANDBETWEEN(1,COUNTA(named_range)),1)
This is what I've tried but it doesn't work:
function tfunction(n) {
var randomstuffs = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(n);
var randomstuff = randomstuffs[Math.floor(Math.random()*randomstuffs.length)];
Logger.log(randomstuff);
}
Thanks in advance
You can try this edited script:
function tfunction(n) {
//randomstuffs will only get all cell data that are not empty from a named range
var randomstuffs = [].concat.apply([], SpreadsheetApp.getActiveSpreadsheet().getRangeByName(n).getValues()).filter(String);
var randomstuff = randomstuffs[Math.floor(Math.random()*randomstuffs.length)];
return randomstuff;
}
Sample Result
Created a sample named range TestRange on Column A with 21 cells of data then tried the custom function =tfunction("TestRange") which returned a random cell value.
.getRangeByName() method returns a reference to a range, not the values in the range. You need to add .getValues() to it:
var randomstuffs = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(n).getValues();
Also keep in mind that .getValues() method returns a 2D array of values, indexed by row, then by column. So your var randomstuff declaration will need to be change to account for that, depending on how many rows and columns your range has.

App Script Conditional Formatting to apply on sheet by name

I have been trying to make a Google App Script code which highlight the cell if it has specific text like "L".
I have made a below code but its not working and when i run this no error appears. i do not know what is the problem.
Can you have a look at it, please that why its not working.
function formatting() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Dec');
var range = sheet.getRange("C:AG");
if (range == 'L') {
ss.range.setBackgroundColor('#ea9999');
}
}
Issues with the code:
Three things to mention:
range is a range object, not a string. In the if condition you are comparing an object of type range with an object of type string. You need to use getValue to get the values of the range object and then compare that with the string L.
This code will take a lot of time to complete because you have a large range of cells you want to check but also you are iteratively using GAS API methods. As explained in Best Practices it is way more efficient to use batch operations like getValues,
getBackgrounds and setBackgrounds.
Another improvement you can make is to use getLastRow to restrict the row limit of your range since you are looking for non-empty values. There is no reason for checking empty cells after the last row with content.
Google Apps Script Solution:
function formatting() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Dec');
const range = sheet.getRange("C1:AG"+sheet.getLastRow());
const values = range.getValues();
const bcolors = range.getBackgrounds();
const new_bcolors = values.map((r,i)=>r.map((c,j)=>c=='L'?'#ea9999':bcolors[i][j]))
range.setBackgrounds(new_bcolors)
}
Google Sheets Solution:
Another idea would be to just create a conditional formatting in Google Sheets:
and specify a custom color with your hex code:
JavaScript References:
map
ternary operator

getRange outputting "Range" instead of values

So, I'm making a code that copies certain data from our EOD worksheet, and copy/pasting the data onto another sheet, which acts as a summary.
I've got most of the code already working, but running into trouble with the getRange output. It just shows "Range" in the cell instead of my input, which should all be numbers.
function myFunction() {
var source = [];
var destSheet = SpreadsheetApp.getActive().getSheetByName('SnapshotSpreadsheet');
var destRange = destSheet.getRange(destSheet.getLastRow()+1,2);
source.push(sheet.getRange('B20'));
source.push(sheet.getRange('E20:F20'));
source.push(sheet.getRange('H20'));
source.push(sheet.getRange ('J20:I20'));
source.push(sheet.getRange ('M18'));
source.push(sheet.getRange ('K20'));
source.push(insertDate());
destSheet.getRange(2,1,1,7).setValues([source]);
I've included just the portion that is causing the issue. I defined source as an array, and stored values into the array, then just called for them to be output on the next available line. Everything seems to be lining up alright, just the values are all "Range".
You need to use getValue() (if single cell) or getValues() (if multiple cells) to get the content of those ranges.
Cfr https://developers.google.com/apps-script/reference/spreadsheet/range#getValue()
You'll need to do .getValues() for it to return the values of the cells
var values = sheet.getRange('E20:F20').getValues();
This returns a Two Dimensional array of values, so you'll have to work around that in your code. For example the line of code I just wrote would be an array like
[[Value at E20, Value at F20]]
so in order to access the Value at E20, you would call values[0][0] or for Value at F20, - values[0][1]

get range from google sheets using r1c1

I want to get range selected from r1c1 r2c2
I have
var rc1 = '0:0-3:3';
//considering the string
var res = ss.getActiveSheet().getRange('R0C0:R3C3');
ss.getActiveSheet().setActiveSelection(res);
I get error Range not found
Your range is not found cause you trying to get element out of the table. R0C0 does not exist, R1C1 is the first existing element.
If you want to get range selected from R1C1 to R2C2, you've got
function getWithRCNotation(){
var ss=SpreadsheetApp.getActiveSpreadsheet();
var res = ss.getActiveSheet().getRange('R1C1:R2C2');
ss.getActiveSheet().setActiveSelection(res);
}
Make sure that you follow the instructions in this documentation. Based from this thread, when you pass a range, a1:d12 for example, to a function in gSheets, the values of the cells in that range are passed as an array. Try to pass it as a string, like =function("a1:d12"), and deal with the string notation for a range, ...getRange(stringargument).

setFormulas to a new spreadsheets when created

I have been searching through question and example everywhere but I can not seem to find an answer. I need to set these formulas in the header row and columns AQ:1 to AV:1(AQ1:AV1).
["={"Hours:";ArrayFormula((IF(LEN(AE2:AE),((AF2:AF-AE2:AE)*24)+(((T2:T-S2:S)*24))+(((I2:I-H2:H)*24)),)))}",
"={"Rest Hours:";ArrayFormula((IF(LEN(AE2:AE),((M2:M)*24)+(((X2:X)*24))+(((AJ2:AJ)*24)),)))}",
"={"Rest Hours Wages:";ArrayFormula((IF(LEN(AE2:AE),(AI2:AI*(AJ2:AJ*24)+(L2:L*(M2:M*24)+(W2:W*(X2:X*24)))),)))}",
"={"Hours-RestHours:";ArrayFormula((IF(LEN(AE2:AE),((AQ2:AQ-AR2:AR)),)))}",
"={"Rate:";ArrayFormula((IF(LEN(AE2:AE),((E2:E+P2:P+AB2:AB)),)))}"],
and I need to put this into the second row of column AQ (AQ2).
["=ArrayFormula((IF(LEN(AE2:AE),((AT2:AT*AU2:AU)+AS2:AS),)))}"],
I keep getting this error message and I cannot save the script.
Missing ] after element list. (line 138, file "Code")
I think I know why but I need the headers to be titled with the correct text because I use the headers in other functions.
function setFormulas(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// This sets the formulas to be a row of sums, followed by a row of averages right below.
// The size of the two-dimensional array must match the size of the range.
var formulas = [
["={"Hours:";ArrayFormula((IF(LEN(AE2:AE),((AF2:AF-AE2:AE)*24)+(((T2:T-S2:S)*24))+(((I2:I-H2:H)*24)),)))}",
"={"Rest Hours:";ArrayFormula((IF(LEN(AE2:AE),((M2:M)*24)+(((X2:X)*24))+(((AJ2:AJ)*24)),)))}",
"={"Rest Hours Wages:";ArrayFormula((IF(LEN(AE2:AE),(AI2:AI*(AJ2:AJ*24)+(L2:L*(M2:M*24)+(W2:W*(X2:X*24)))),)))}",
"={"Hours-RestHours:";ArrayFormula((IF(LEN(AE2:AE),((AQ2:AQ-AR2:AR)),)))}",
"={"Rate:";ArrayFormula((IF(LEN(AE2:AE),((E2:E+P2:P+AB2:AB)),)))}",
"={"Wages:";ArrayFormula((IF(LEN(AE2:AE),((AT2:AT*AU2:AU)+AS2:AS),)))}"],
["=ArrayFormula((IF(LEN(AE2:AE),((AT2:AT*AU2:AU)+AS2:AS),)))}"],
];
var cell = sheet.getRange("AQ1:AW2");
cell.setFormulas(formulas);
}
Am I missing something or am I doing it completely wrong and need to find another way to do it. I also need to add the formulas to every sheet in the spreadsheet but I have not been able to test if it works. Thank you in advance for any help.
UPD:
It seems like double quotes are interfering here. To avoid this, you can use single quotes for formula enclosure and double quotes within formula, like this:
'={"Hours:";ArrayFormula((IF(LEN(AE2:AE),((AF2:AF-AE2:AE)*24)+(((T2:T-S2:S)*24))+(((I2:I-H2:H)*24)),)))}'
As mentioned in comments:
Arrays would expand so you are likely to need setting formulas in one row, like AQ1:AW1
Besides, if there's source data in columns AQ:AU (by the looks of formulas), setting array formulas in the same columns will most likely return error: Array result was not expanded because it would overwrite data in AQ18.
You seem to have an extra } at the end of the last formula
Try this and adjust to your needs:
function setFormulas(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// This sets the formulas to be a row of sums, followed by a row of averages right below.
// The size of the two-dimensional array must match the size of the range.
var formulas = [
['={"Hours:";ArrayFormula((IF(LEN(AE2:AE),((AF2:AF-AE2:AE)*24)+(((T2:T-S2:S)*24))+(((I2:I-H2:H)*24)),)))}',
'={"Rest Hours:";ArrayFormula((IF(LEN(AE2:AE),((M2:M)*24)+(((X2:X)*24))+(((AJ2:AJ)*24)),)))}',
'={"Rest Hours Wages:";ArrayFormula((IF(LEN(AE2:AE),(AI2:AI*(AJ2:AJ*24)+(L2:L*(M2:M*24)+(W2:W*(X2:X*24)))),)))}',
'={"Hours-RestHours:";ArrayFormula((IF(LEN(AE2:AE),((AQ2:AQ-AR2:AR)),)))}',
'={"Rate:";ArrayFormula((IF(LEN(AE2:AE),((E2:E+P2:P+AB2:AB)),)))}',
'={"Wages:";ArrayFormula((IF(LEN(AE2:AE),((AT2:AT*AU2:AU)+AS2:AS),)))}',
'=ArrayFormula((IF(LEN(AE2:AE),((AT2:AT*AU2:AU)+AS2:AS),)))']
];
var cell = sheet.getRange("AW1:BC1");
cell.setFormulas(formulas);
}