I\'m creating a board game and I have decided to choose Google sheets for that purpose. I have reduced my problem to a minimal example consisting of one sheet and one script
The problem is that when I change the dice faces in column C, the
DICEFACE
formulas are not being recalculated.
DIFACE is a custom function and custom functions are recalculated when the spreadsheet is opened and custom function arguments values change.
Considering the above, in order to minimize the changes to your custom function add a second argument to work as a trigger.
Change the regular expression
/=\w+\((.*)\)/i
to
/=\w+\((.*),.*\)/i
Then call your custom function in the following way
=DICEFACES(E2:I2,C2)
or
=DICEFACES(E2:I2,C2:C5)
Modified version of the OP custom function
/**
* Returns a matrix of dice faces corresponding to the dices in the provided range.
*
* @param {Array} unused_ref_to_range_containing_dices Reference to range. i.e. E2:I2
* @param {String|Number|Date|Array} ref_as_trigger Reference to a range used as trigger. i.e. C2 or C2:C5
* @return array
* @customfunction
*/
function DICEFACES(unused_ref_to_range_containing_dices,ref_as_trigger)
{
var app = SpreadsheetApp;
var spr = app.getActiveSheet();
// In the end this array will hold the dice faces. For example two
// 1d6 dices would result in [[1,2,3,4,5,6],[1,2,3,4,5,6]].
//
var Dices = [];
// The the formula inside the active cell (i.e. the cell on which
// we are calling this function). This is a string like:
//
// "=DICEFACES(E2:I2)"
//
var active_formula = spr.getActiveRange().getFormula();
// Set item_range to the one pointed to by the formula. This could
// be a range like E2:I2.
//
var item_range = spr.getRange(active_formula.match(/=\w+\((.*),.*\)/i)[1]); // CHANGED
// Loop over dice cells in the item_range.
//
for (var i = 1; i <= item_range.getNumColumns(); i++)
{
// "=B2", "=B3", ...
//
var dice_formula = item_range.getCell(1, i).getFormula();
// As soon as we encounter an empty formula, we skip (i.e. there are
// no more dices).
//
if (dice_formula == "")
{
break;
}
// A reference to the cell containing the dice image. We don't really
// need the image, the dice faces are of greater importance to us.
//
var dice_cell = spr.getRange(dice_formula.substr(1));
// Move one column to the right prior to the dice_cell and retreive
// the value of the cell. This is a string like "1,2,3,4,5,6".
//
var dice_csv = dice_cell.offset(0, 1).getValue();
// Convert the CSV string to a javascript array like [1,2,3,4,5,6]
// and push it to Dices.
//
Dices.push(dice_csv.split(",").map(Number));
}
return Dices;
}