I'm trying to learn how to manipulate with cell in Google spreadsheets with Google script. I have learned, that
Custom functions return values, but they cannot set values outside the cells they are in. In most circumstances, a custom function in cell A1 cannot modify cell A5. However, if a custom function returns a double array, the results overflow the cell containing the function and fill the cells below and to the right of the cell containing the custom function. You can test this with a custom function containing return [[1,2],[3,4]];
So I'm calling function in cell C14
function test(input){
var secondCell = SpreadsheetApp.getActiveSheet().getRange("C14").setValue("Ahoj");
return secondCell.getValue();
}
and still getting error
You do not have permission to call setValue
I can't even set data in cell from which I'm calling the function.
Does anybody know why is this not working ?
Edit:
I've read possible duplicate Why can't you use setValue in a custom function?
But this is not solving my problem.
I don't want to edit other cells. I only want to edit the original cell containing the formula. According the quoted text, I should be possible to edit cell, if it's original cell containing the formula. But my example is returning error even though it's accessing only itself.
Your code makes no sense, you set the value progamaticly in C14 to "Ahoj", then get this already know variable, and try to return it to set in the cell that you just tried to set the value to "Ahoj", which would replace the function you just used to run this very function. That's almost a paradox.
Your making a confusion, you can get the value of C14, but that function can't be called in C14, or if you want to set the value of C14 to "Ahoy", in that function all you need is:
function test(input){
return 'Ahoj';
}
If you want another cell to have the value of C14 then:
function test(input){
return SpreadsheetApp.getActiveSheet().getRange('C14').getValue();
}
The returned value will be the new cell value, it isn't done trough setValue.
Related
I am new to google scripts and I am having trouble with passing parameters from my google spreadsheet to my google script.
I have created a function in my script:
function functionname(ref) {
Logger.log(ref);
var value = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(ref).getValue();
//do stuff with the value read from the sheet
return modified_value;
}
and I am calling it in my google spreadsheet like:
=functionname(A4)
(the function is called from an empty A5 cell, with cell A4 filled with text).
I have initially tried with a static reference in the function, like:
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("H9").getValue()
In this situation, it worked perfectly, but I do not want to replicate the function for each cell I need to operate, given I need to deliver this to non-programmers and the list of cells will increase.
Initially, I read that passing the parameters from the cell will be sufficient to receive the value and I had tried also this solution. Still, no matter what I try, the value of ref is always "undefined".
Can anyone please help me understand what I am missing?
Thanks
No need for the SpreadSheetApps methods for custom function to pull the value from the SpreadSheet because it already gets the cell value that you are referencing. Just remove the var value = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(ref).getValue();
function functionname(ref) {
Logger.log(ref);
//do stuff with the value read from the sheet
return modified_value;
}
You can call this function directly on your spreadsheet. Don't forget to store the new value on a variable and return it, or return the computed value directly.
I have written a custom google apps script function that is being called by a google sheet. In this function an API is called and the result of this API is being returned so that it gets displayed in the calling cell of the google sheet.
My problem now is that the sheet calls this function everytime I open the document and there are over 80.000 cells with this function.
Is it possible to save the returned value to the cell and don't call the custom function again when an value has been returned? I want the function being called only once per cell, even if I close the document and reopen it. The returned value should be saved until something else is being written into to cell. That would make my sheets document much more usable than the current state.
From the question
Is it possible to save the returned value to the cell and don't call the custom function again when an value has been returned? I want the function being called only once per cell, even if I close the document and reopen it. The returned value should be saved until something else is being written into to cell. That would make my sheets document much more usable than the current state.
By solely using the custom function it's not possible. There isn't a straight forward solution is to achieve this, in order to keep things simple you should look for another way to implement what is being done by the custom funtion.
One option is to use a trigger (including a custom menu / a function assined to a drawing) to check if the cell that should have the value returned by the custom function is empty and in such case fill it with the corresponding value. The best trigger to use will depend on your spreadsheet workflow.
As specified by Ruben this is not possible, with a custom function.
In my particular case I have resorted to using an Apps Script function that is triggered by an edit event of the spreadsheet and verifies if the event is in the column where the function that I want to execute only once should be, later replacement its content with the result of calling the API.
function freezeValue(e) {
var rangeEvent = e.range;
var col = rangeEvent.getColumnIndex();
if (col === 2) { #Verify column of event
var value = rangeEvent.getValue();
/*Call your api*/
result_api = CALL_API(value)
rangeEvent.setValue(result_api);
}
}
Keep in mind that this implementation only works when each of the cells is edited one by one. To do the same with a row or a complete array of elements, you must go through each of the cells and follow the same procedure.
Thanks for looking into this
I have an App script custom function as below which return a formula for a cell. When I use this function from a cell in google sheet it shows the formula =Sum(1,2) instead of the evaluated result i.e 3.
function testReturningFormula(){
return "=Sum(1,2)";
}
If you set a cell with formula =testReturningFormula(), it cannot overwrite the cell's formula you've created. It can only return a string or array. You should have the formula itself parse the arguments you wish.
This should help:
https://developers.google.com/apps-script/guides/sheets/functions
The custom function is not returning a formula, it's returning a string.
It's not possible to use a custom function to return a formula, they only are able to return values. Reference https://developers.google.com/apps-script/guides/sheets/functions
I'm wondering if it is possible to edit the result of a custom function in Google Sheets when returning a 2-dimensional array.
If I try to delete a cell that is part of the returned array, it blinks but stays there.
If I enter something in a cell that is part of the returned 2-dimensional array, it works, but the function then does not return because the value is blocking the display of the 2-dimensional array (Array result was not expanded because it would overwrite data in A3.)
It's the same as for built-in functions returning an array (split, importrange, query, etc): output cannot be edited. But there is a workaround described below.
Suppose the output range is A1:B6. Elsewhere in a sheet, enter =A1 and copy this formula to a 2 by 6 range. This creates a range that is visually identical to the function output, but editable cell-by-cell. If you edit a cell in this new range, it will cease to depend on the function, but the rest will still be updated if the function input changes.
While applying conditional formatting in Google spreadsheet, I was wondering if it's possible to use a custom function that I created via script editor in the field 'custom formula is:'. Here is what I did:
Went to 'script editor' and typed my fn as follows:
function foo (param1, param2, param3) {
if (condition to check) {
...some action;
return true;
} else {
return false;
}
}
and saved.
In sheet, selected cells and opened 'conditional formatting' dialog
Created new rule and in the field 'custom formula is:' typed the following
=foo(param1, param2, param3)
Unfortunately, this didn't work.
Addition
Here is the sample sheet...
See the two tasks in there. My aim is to have the 'task title' automatically written inside of the yellow field (see the task in row 6 where I entered the value manually).
What I already tried was:
- Assign to every cell in range H5:BB7 following formula: =if(H$4=D5; B5; "")
This checks if the start date equals the cell date and displays the task title.
That does the trick, however the content of the cell with task title is clipped even if 'overflow' is on because the next cell is not empty.
I have also found that custom functions cannot be used for conditional formatting. However, I located a pretty simple workaround.
The custom formula that I tried to use is:
=hasGreen(CELL("address",$H3)&":"&CELL("address",$M3))
ie. format a cell based on a range of other cells in that row.
My solution was to place the above formula into column P. Then I changed my conditional formatting's custom formula to =P3
Worked like a charm. Any change to H3:M3 would call hasGreen and update the value of P3. The conditional formatting would note any change to P3, and adjust the formatting.
Short answer
A custom function can't be used as a part of a custom formula in the Google Sheets' conditional formatting built-in user interface.
Explanation
In Google Sheets, a custom function is like spreadsheet built-in functions but written by the user using the Google Apps Script editor. They can't modify other objects, only return one or multiple values.
By the other hand, a custom function only is calculated when it's added to a cell or when at least one of it's parameters changes. They can't use non-deterministic functions as parameters like NOW(), TODAY(), RAND() and RANDBETWEEN().
Test
In order to test the statement in the short answer, I created a did the following:
Create a simple custom function
function two() {
return 2;
}
Add the custom function as part of a custom formula in the conditional formatting side panel
=two()=2
Result:
Nothing changed.
References
Custom Functions in Google Sheets