He extendido la excelente idea en la respuesta del usuario 79865 , para que funcione para más casos y con múltiples argumentos pasados a la función personalizada.
Para usarlo, copie el código a continuación y luego, en su función personalizada, llame GetParamRanges()
así, pasándole el nombre de su función:
function CustomFunc(ref1, ref2) {
var ranges = GetParamRanges("CustomFunc"); // substitute your function name here
// ranges[0] contains the range object for ref1 (or null)
// ranges[1] contains the range object for ref2 (or null)
... do what you want
return what_you_want;
}
Aquí hay un ejemplo para devolver el color de una celda:
/**
* Returns the background color of a cell
*
* @param {cell_ref} The address of the cell
* @return The color of the cell
* @customfunction
*/
function GetColor(ref) {
return GetParamRanges("GetColor")[0].getBackground();
}
Aquí está el código y alguna explicación más:
/**
* Returns an array of the range object(s) referenced by the parameters in a call to a custom function from a cell
* The array will have an entry for each parameter. If the parameter was a reference to a cell or range then
* its array element will contain the corresponding range object, otherwise it will be null.
*
* Limitations:
* - A range is returned only if a parameter expression is a single reference.
* For example,=CustomFunc(A1+A2) would not return a range.
* - The parameter expressions in the cell formula may not contain commas or brackets.
* For example, =CustomFunc(A1:A3,ATAN2(4,3),B:E) would not parse correctly.
* - The custom function may not appear more than once in the cell formula.
* - Sheet names may not contain commas, quotes or closing brackets.
* - The cell formula may contain white space around the commas separating the custom function parameters, or after
* the custom function name, but not elsewhere within the custom function invocation.
* - There may be other limitations.
*
* Examples:
* Cell formula: =CUSTOMFUNC($A$1)
* Usage: var ranges = GetParamRanges("CustomFunc");
* Result: ranges[0]: range object for cell A1 in the sheet containing the formula
*
* Cell formula: =CUSTOMFUNC(3, 'Expenses'!B7)
* Usage: var ranges = GetParamRanges("CustomFunc");
* Result: ranges[0]: null
* ranges[1]: range object for cell B7 in sheet Expenses
*
* Cell formula: =sqrt(4+myfunction(A1:C3))
* Usage: var ranges = GetParamRanges("MyFunction");
* Result: ranges[0]: range object for cells A1 through C3 in the sheet containing the formula
*
* Cell formula: =CustomFunc(A1+A2, A1, A2)
* Usage: var ranges = GetParamRanges("CustomFunc");
* Result: ranges[0]: null
* ranges[1]: range object for cell A1 in the sheet containing the formula
* ranges[2]: range object for cell A2 in the sheet containing the formula
*
* @param {funcName} The name of the custom function (string, case-insensitive)
* @return The range(s) referenced by the parameters to the call
*/
function GetParamRanges(funcName) {
var ourSheet = SpreadsheetApp.getActiveSheet();
var formula = SpreadsheetApp.getActiveRange().getFormula();
var re = new RegExp(".+" + funcName + "\\s*\\((.*?)\\)","i");
var ranges=[]; // array of results
try {
var args = formula.match(re)[1].split(/\s*,\s*/) // arguments to custom function, separated by commas
// if there are no args it fails and drops out here
for (var i=0; i<args.length; i++) {
var arg=args[i].split('!'); // see if arg has a sheet name
try {
if (arg.length == 1) { // if there's no sheet name then use the whole arg as the range definition
ranges[i] = ourSheet.getRange(arg[0]);
}
else { // if there's a sheet name, use it (after removing quotes around it)
var sheetName=arg[0].replace(/'/g, '');
var otherSheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
ranges[i] = otherSheet.getRange(arg[1]);
}
}
catch(e) { // assume it couldn't be identified as a range for whatever reason
ranges[i]=null;
}
}
}
catch(e) {}
return ranges
}