I skimmed the character sheet on github, and have a better idea of what you're after. I assumed earlier you wanted to total up the repeating section, but you just want something to update fields within the repeating section. So ignore my repeatingSum suggestion. You already have this code on('change:repeating_item:count change:repeating_item:cost change:repeating_item:carried change:repeating_item:weight', function (e) { getAttrs(['repeating_item_count', 'repeating_item_cost', 'repeating_item_weight', 'repeating_item_carried'], function (item) { setAttrs({ repeating_item_weighttotal: Math.round(item.repeating_item_count * item.repeating_item_weight * item.repeating_item_carried * 1000) / 1000, repeating_item_costtotal: Math.round(item.repeating_item_count * item.repeating_item_cost * 100) / 100 }); }); }); With a tweak to this, and a second sheet worker to handle in-place mass changes to the second sheet, you can do what you need without needing to use sheet:opened. I need to know about the attribute that handles the formatting. Is it a checkbox? what values does it have? To illustrate how to change the above, let's say it is a checkbox named "inventory_fixed_digits" and has a value of 0 or 1 (0 = not fixed, 1 = fixed digits). on('change:repeating_item:count change:repeating_item:cost change:repeating_item:carried change:repeating_item:weight', function (e) { getAttrs(['repeating_item_count', 'repeating_item_cost', 'repeating_item_weight', 'repeating_item_carried', 'inventory_fixed_digits'], function (item) {
const fixed = +item.inventory_fixed_digits || 0;
let weight = (+item.repeating_item_count||0) * (+item.repeating_item_weight||0) * (+item.repeating_item_carried||0);
let cost = (+item.repeating_item_count||0) * (+item.repeating_item_cost||0);
weight = fixed ? Number(Math.round(weight * 1000)/1000).toFixed(3) : Math.round(weight * 1000)/1000;
cost = fixed ? Number(Math.round(cost * 100)/100).toFixed(2) : Math.round(cost * 100)/100;
setAttrs({
repeating_item_weighttotal: weight,
repeating_item_costtotal: cost
});
});
}); Now whenever item changes, the weight or cost is calculated and takes into account the current format. So you just need a way to update all at once when the inventory_fixed_digits attribute is changed. on('change:inventory_fixed_digits',function(e) {
// getSectionIDs gives an array of all the row ids. getSectionIDs('item', function (ids) { if (ids.length === 0) { return; }
// need to get an array of all the attributes used in the repeating_items calculations, for getAttrs const fieldArray = []; ids.forEach(id => fieldArray.push( `repeating_item_${id}_count`, `repeating_item_${id}_cost`, `repeating_item_${id}_weight`, `repeating_item_${id}_carried` ));
getAttrs(fieldArray.concat(['inventory_fixed_digits']), function (item) {
const fixed = +item.inventory_fixed_digits; const items = {}; // initialise an object to hold the total weights and costs. ids.forEach(id => {
// for each row of the table, calculate the total weight and cost let weight = (+item[`repeating_item_${id}_count`]||0) * (+item[`repeating_item_${id}_weight`]||0) * (+item[`repeating_item_${id}_carried`]||0); let cost = (+item[`repeating_item_${id}_count`]||0) * (+item[`repeating_item_${id}_cost`]||0);
// save the totals, in the correct format (if fixed = 1 use the first forumila, if 0, the second) items[`repeating_item_${id}_weighttotal`] = fixed ? Number(Math.round(weight * 1000)/1000).toFixed(3) : Math.round(weight * 1000)/1000; items[`repeating_item_${id}_costtotal`] = fixed ? Number(Math.round(cost * 100)/100).toFixed(2) : Math.round(cost * 100)/100; }); setAttrs(items); }); }); }); Obviously I havent tested this, so there might be typos, but the process is sound. With this approach, the correct format is always used. Even if you dont use this approach, the last sheet worker shows you how to loop through a repeating section and make changes on each row, which was the original question. Note that I wrapped the numbers in the total formulas like this for a reason: (+item.repeating_item_count||0) * (+item.repeating_item_cost||0); If the cell on the sheet is empty, it can cause the calculation to fail and break the entire sheet worker till you enter a proper value. This way, each value is always treated as a number, so if one row has an empty cell (or even text but i assume your sheet doesnt allow that), the sheet worker still returns a value for the other rows or cells.