Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Help with RepeatingSum to track inventory total weight.

1653193718

Edited 1653194035
I'm using a custom version of Fantasy Age sheet and I'm trying to get the total weight from my inventory on an attribute outside a fieldset. It seems like I found what I need, but I have no idea on how to make it work. This is what I found: And this is what I have on my sheet: How can I get the total weight (sum of all quantity * weight) to be shown on other attribute outside that fieldset??
1653197203
GiGs
Pro
Sheet Author
API Scripter
You need a script block, and inside that block you need two things: a copy of the repeatingSum function a sheet worker that calls the repeatingSum function, which calls the attributes in the section, and names the attribute you are using as destination. I'd avoid using hyphens in attribute names by the way - just use letters and underscores. It'll make things simpler once you start using sheet workers.
1653366840

Edited 1653374248
Oh, I tried to get it, but I'm quite lost on this. I made this: But it doesn't work... and this is what I have about that fieldset (I changed the hyphens names): And I want the total weight to be shown on this attribute: Can you help me please? GiGs said: You need a script block, and inside that block you need two things: a copy of the repeatingSum function a sheet worker that calls the repeatingSum function, which calls the attributes in the section, and names the attribute you are using as destination. I'd avoid using hyphens in attribute names by the way - just use letters and underscores. It'll make things simpler once you start using sheet workers.
1653376875

Edited 1653377157
GiGs
Pro
Sheet Author
API Scripter
Screenshots are no good - I can't copy and edit those. Post the actual code.
1653378311

Edited 1653378863
GiGs
Pro
Sheet Author
API Scripter
also, based on the above pic, I wonder if something is missing from the script block. Can you post the entire script block (whichstarts <script type="text/worker">) In your first screenshot, you needd to remove some things. You only need the first 2 lines and the very last }); Everything from getAttrs should be removed. The function does that calculation. You might need to remove sheet:opened too - you dont need it.
1653401155

Edited 1653401602
I'm sorry, about those screenshots. Now I got this: on("change:repeating_equipment remove:repeating_equipment", function(values) { repeatingSum("income","equipment",["equipmentPeso","equipmentQuantity"]); }); I made the edits you said and now I have this scriptblock: <script type="text/worker"> console.log("Loading script(s)"); /*config Roll Queries translations */ on("sheet:opened", function(eventInfo){ setAttrs({ public_roll: getTranslationByKey("public_roll"), whisper_roll: getTranslationByKey("whisper_roll"), whisper: getTranslationByKey("whisper"), fighting_label: getTranslationByKey("fighting"), income_label: getTranslationByKey("income_label"), accuracy_label: getTranslationByKey("accuracy"), communication_label: getTranslationByKey("communication"), constitution_label: getTranslationByKey("constitution"), dexterity_label: getTranslationByKey("dexterity"), perception_label: getTranslationByKey("perception"), strength_label: getTranslationByKey("strength"), willpower_label: getTranslationByKey("willpower"), intelligence_label: getTranslationByKey("intelligence"), cunning_label: getTranslationByKey("cunning"), none: getTranslationByKey("none"), plus_one_tn: getTranslationByKey("plus_one_tn"), power_cost_label: getTranslationByKey("power_cost_label"), kanna_cost_label: getTranslationByKey("kanna_cost_label"), fatigue_tn_label: getTranslationByKey("fatigue_tn_label"), ability: getTranslationByKey("ability"), ability_value: getTranslationByKey("ability_value"), focus_value: getTranslationByKey("focus_value"), additional_modifier: getTranslationByKey("additional_modifier"), additional_modifier2: getTranslationByKey("additional_modifier2"), ability_score: getTranslationByKey("ability_score"), roll_description: getTranslationByKey("roll_description"), die_roll: getTranslationByKey("die_roll"), focus: getTranslationByKey("focus"), magic_label: getTranslationByKey("magic"), magic_arcana_focus: getTranslationByKey("magic_arcana_focus"), spellcasting_ability: getTranslationByKey("spellcasting_ability"), psychic_ability: getTranslationByKey("psychic_ability"), ability_focus: getTranslationByKey("ability_focus"), arcana_focus: getTranslationByKey("arcana_focus"), psychic_focus: getTranslationByKey("psychic_focus"), fatigue_check_for: getTranslationByKey("fatigue_check_for"), each_fatiguing_spell: getTranslationByKey("each_fatiguing_spell"), fear_label: getTranslationByKey("fear_label"), armor_penalty: getTranslationByKey("armor_penalty"), initiative_adjustment: getTranslationByKey("initiative_adjustment"), initiative: getTranslationByKey("initiative"), resources: getTranslationByKey("resources"), attack_bonus_label: getTranslationByKey("attack_bonus_label"), magic_arcana_focus: getTranslationByKey("magic_arcana_focus"), spellpower_label: getTranslationByKey("spellpower_label") }); }); on("change:fear", function(event) { console.log("Fear changed"); getAttrs(["fear"], function(v) { switch(v.fear) { case "0": setAttrs({ "fear-perception": 0, "fear-intelligence": 0, "fear-initiative": 0, "fear-accuracy": 0, "fear-fighting": 0 }); // setAttrs break; case "1": setAttrs({ "fear-perception": 1, "fear-intelligence": -1, "fear-initiative": 0, "fear-accuracy": 0, "fear-fighting": 0 }); // setAttrs break; case "2": setAttrs({ "fear-perception": 1, "fear-intelligence": -1, "fear-initiative": 1, "fear-accuracy": -1, "fear-fighting": -1 }); // setAttrs break; case "3": setAttrs({ "fear-perception": 2, "fear-intelligence": -2, "fear-initiative": 1, "fear-accuracy": -1, "fear-fighting": -1 }); // setAttrs break; case "4": setAttrs({ "fear-perception": 2, "fear-intelligence": -2, "fear-initiative": 2, "fear-accuracy": -2, "fear-fighting": -2 }); // setAttrs break; case "5": setAttrs({ "fear-perception": 2, "fear-intelligence": -2, "fear-initiative": 2, "fear-accuracy": -2, "fear-fighting": -2 }); // setAttrs break; default: console.log("Error: unknown value for fear"); }; // case }); // getAttrs }); // change:fear on("clicked:autoconfigure", function(event) { console.log("Clicked!"); getAttrs(["game"], function(v) { switch(v.game) { case "dragon-age": setAttrs({ "mana-toggle": 1, "initiative-toggle": 1, "fatigue-toggle": 0, "fear-toggle": 0, "horror-toggle": 0, "exp-toggle": 1, "conviction-toggle": 0, "corruption-toggle": 0, "ammo-toggle": 1, "power-list-toggle": 1, "spell-list-toggle": 1, "equipment-toggle": 1, "money-toggle": 1, "income-toggle": 0, "conditions-toggle": 0, color: "red" }); // setAttrs break; case "fantasy-age": setAttrs({ "mana-toggle": 1, "initiative-toggle": 1, "fatigue-toggle": 0, "fear-toggle": 0, "horror-toggle": 0, "exp-toggle": 0, "conviction-toggle": 0, "corruption-toggle": 0, "ammo-toggle": 1, "power-list-toggle": 1, "spell-list-toggle": 1, "equipment-toggle": 1, "money-toggle": 1, "income-toggle": 0, "conditions-toggle": 0, color: "green" }); // setAttrs break; case "titansgrave": setAttrs({ "mana-toggle": 1, "initiative-toggle": 1, "fatigue-toggle": 0, "fear-toggle": 0, "horror-toggle": 0, "exp-toggle": 0, "conviction-toggle": 0, "corruption-toggle": 0, "ammo-toggle": 1, "power-list-toggle": 1, "spell-list-toggle": 1, "equipment-toggle": 1, "money-toggle": 1, "income-toggle": 0, "conditions-toggle": 0, color: "teal1" }); // setAttrs break; case "blue-rose": setAttrs({ "mana-toggle": 0, "initiative-toggle": 1, "fatigue-toggle": 1, "fear-toggle": 0, "horror-toggle": 0, "exp-toggle": 0, "conviction-toggle": 1, "corruption-toggle": 1, "ammo-toggle": 0, "power-list-toggle": 1, "spell-list-toggle": 1, "equipment-toggle": 1, "money-toggle": 0, "income-toggle": 0, "conditions-toggle": 0, color: "blue2" }); // setAttrs break; case "the-expanse": setAttrs({ "mana-toggle": 0, "initiative-toggle": 1, "fatigue-toggle": 0, "fear-toggle": 0, "horror-toggle": 0, "exp-toggle": 0, "conviction-toggle": 0, "corruption-toggle": 0, "ammo-toggle": 1, "power-list-toggle": 1, "spell-list-toggle": 0, "equipment-toggle": 1, "money-toggle": 0, "income-toggle": 1, "conditions-toggle": 1, color: "stars" }); // setAttrs break; case "modern-age": setAttrs({ "mana-toggle": 1, "initiative-toggle": 1, "fatigue-toggle": 1, "fear-toggle": 0, "horror-toggle": 0, "exp-toggle": 1, "conviction-toggle": 0, "corruption-toggle": 0, "ammo-toggle": 1, "power-list-toggle": 1, "spell-list-toggle": 1, "equipment-toggle": 1, "money-toggle": 0, "income-toggle": 1, "conditions-toggle": 0, color: "orange" }); // setAttrs break; case "world-of-lazarus": setAttrs({ "mana-toggle": 0, "initiative-toggle": 1, "fatigue-toggle": 0, "fear-toggle": 0, "horror-toggle": 0, "exp-toggle": 1, "conviction-toggle": 0, "corruption-toggle": 0, "ammo-toggle": 1, "power-list-toggle": 1, "spell-list-toggle": 0, "equipment-toggle": 1, "money-toggle": 0, "income-toggle": 1, "conditions-toggle": 0, color: "lazarus" }); // setAttrs break; case "threefold": setAttrs({ "mana-toggle": 1, "initiative-toggle": 1, "fatigue-toggle": 1, "fear-toggle": 0, "horror-toggle": 0, "exp-toggle": 1, "conviction-toggle": 0, "corruption-toggle": 0, "ammo-toggle": 1, "power-list-toggle": 1, "spell-list-toggle": 1, "equipment-toggle": 1, "money-toggle": 0, "income-toggle": 1, "conditions-toggle": 0, color: "threefold" }); // setAttrs break; default: console.log("wait what happened"); }; // case }); // getAttrs }); // on clicked on("sheet:opened", function(event) { console.log("Opened!"); getAttrs(["cp", "sp", "gp"], function(v) { let cp = parseInt(v.cp,10)||0; let sp = parseInt(v.sp,10)||0; let gp = parseInt(v.gp,10)||0; if(cp != 0 || sp != 0 || gp != 0) { console.log("Hey there's legacy money in there"); setAttrs({ "legacy-money-toggle": 1}); } // if }); // getAttrs }); // sheet opened on("clicked:legacymoneyimport", function(event) { console.log("Clicked!"); getAttrs(["cp", "sp", "gp"], function(v) { console.log(`Converting ${v.cp} cp, ${v.sp} sp, ${v.gp} gp`); let setObj = {}; let cp = parseInt(v.cp,10)||0; let sp = parseInt(v.sp,10)||0; let gp = parseInt(v.gp,10)||0; let id = generateRowID(); setObj[`repeating_money_${id}_moneyname`] = "gp"; setObj[`repeating_money_${id}_moneyamount`] = gp; id = generateRowID(); setObj[`repeating_money_${id}_moneyname`] = "sp"; setObj[`repeating_money_${id}_moneyamount`] = sp; id = generateRowID(); setObj[`repeating_money_${id}_moneyname`] = "cp"; setObj[`repeating_money_${id}_moneyamount`] = cp; setObj.GP = 0; setObj.SP = 0; setObj.CP = 0; setObj["legacy-money-toggle"] = 0; setAttrs(setObj); }); // getAttrs }); // on clicked on("change:repeating_equipment remove:repeating_equipment", function(values) { repeatingSum("income","equipment",["equipmentPeso","equipmentQuantity"]); }); console.log("Script load complete"); </script> But it still doesn't work. I can't get a value from this on my Total Weigth. What am I doing wrong? Sorry if this is too basics, I'm trying to understand it.
1653440575
GiGs
Pro
Sheet Author
API Scripter
You need to copy the function in from the wiki page, as well. Immediately after the <script type="text/worker"> line, paste this: /* ===== PARAMETERS ========== destinations = the name of the attribute that stores the total quantity can be a single attribute, or an array: ['total_cost', 'total_weight'] If more than one, the matching fields must be in the same order. section = name of repeating fieldset, without the repeating_ fields = the name of the attribute field to be summed destination and fields both can be a single attribute: 'weight' or an array of attributes: ['weight','number','equipped'] */ const repeatingSum = (destinations, section, fields) = > { if ( ! Array . isArray (destinations)) destinations = [destinations. replace ( / \s / g , '' ). split ( ',' )]; if ( ! Array . isArray (fields)) fields = [fields. replace ( / \s / g , '' ). split ( ',' )]; getSectionIDs (`repeating_${section}`, idArray = > { const attrArray = idArray. reduce ((m, id) = > [...m, ...(fields. map (field = > `repeating_${section}_${id}_${field}`))], []); getAttrs ([...attrArray], v = > { const getValue = (section, id, field) = > v[`repeating_${section}_${id}_${field}`] = = = 'on'  ? 1  : parseFloat (v[`repeating_${section}_${id}_${field}`]) | | 0 ; const commonMultipliers = (fields. length < = destinations. length ) ? [] : fields. splice (destinations. length , fields. length - destinations. length ); const output = {}; destinations. forEach ((destination, index) = > { output[destination] = idArray. reduce ((total, id) = > total + getValue (section, id, fields[index]) * commonMultipliers. reduce ((subtotal, mult) = > subtotal * getValue (section, id, mult), 1 ), 0 ); }); setAttrs (output); }); }); }; This is a function that is not part of Roll20 as standard -it has to be added to your script block, and then you call that function in workers like this: on("change:repeating_equipment remove:repeating_equipment", function(values) { repeatingSum("income","equipment",["equipmentPeso","equipmentQuantity"]); });
It worked and it takes decimal numbers about my Kg units! Thank you so much for you attention and patience. I learned a lot this month doing customization on my sheet. Thank you deeply GiGs!
1653445586
GiGs
Pro
Sheet Author
API Scripter
You're welcome :)