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

counting multiple items with a condition in a repeating section

1668896754

Edited 1668896775
Duck
Pro
I've run into a situation that I'm having some difficulty writing a sheet worker for and was hoping for some help. I have a repeating section that looks basically like this: &lt;fieldset class="repeating_implantsneural"&gt; &nbsp; &lt;select name="attr_imp_styleneural"&gt;&lt;option value=1&gt;Cyber&lt;/option&gt;&lt;option value=2&gt;Biogen&lt;/option&gt;&lt;/select&gt; &nbsp; &lt;select name="attr_imp_neuralfeature1"&gt;&lt;option value=0&gt;---&lt;/option&gt;&lt;option value=1&gt;thing1&lt;/option&gt;&lt;option value=2&gt;thing2&lt;/option&gt;&lt;/select&gt; &nbsp; &lt;select name="attr_imp_neuralfeature2"&gt;&lt;option value=0&gt;---&lt;/option&gt;&lt;option value=1&gt;thing1&lt;/option&gt;&lt;option value=2&gt;thing2&lt;/option&gt;&lt;/select&gt; &lt;/fieldset&gt; I'm looking to get a count the total number of features that are not set to '---'. also, as a bonus looking to NOT count any feature set to 'thing 2' if&nbsp;imp_styleneural is set to 'biogen' so if the repeating section had these values: imp_styleneural imp_neuralfeature1 imp_neuralfeature2 cyber thing1 --- cyber thing1 thing2 biogen thing1 thing2 The returned count would be 4. 1 from the first item 2 from the second item 1 from the third item (since it is biogen, ignore the thing2 feature) I think I should be able to do this with a sheet worker (something like&nbsp; <a href="https://app.roll20.net/forum/post/5376553/repeating-section-count-up-items-that-match-criteria" rel="nofollow">https://app.roll20.net/forum/post/5376553/repeating-section-count-up-items-that-match-criteria</a> ) &nbsp;but I haven't had success yet. Any help would be appreciated!
So I'm trying to tackle this a different way. The actual repeating section I'm working with: &lt;fieldset class="repeating_implantssenses"&gt; &lt;select style="width: 75px" name="attr_style"&gt;&lt;option value=1&gt;Cyber&lt;/option&gt;&lt;option value=2&gt;Biogen&lt;/option&gt;&lt;/select&gt; &lt;select style="width: 80px" name="attr_which"&gt;&lt;option value=1&gt;Sight&lt;/option&gt;&lt;option value=2&gt;Hearing&lt;/option&gt;&lt;option value=3&gt;Taste&lt;/option&gt;&lt;option value=4&gt;Touch&lt;/option&gt;&lt;option value=5&gt;Smell&lt;/option&gt;&lt;/select&gt; &lt;select style="width: 100px" name="attr_feature1"&gt;&lt;option value=0&gt;---&lt;/option&gt;&lt;option value=1&gt;dampening&lt;/option&gt;&lt;option value=2&gt;widened&lt;/option&gt;&lt;option value=3&gt;heightened&lt;/option&gt;&lt;option value=4&gt;lifelike&lt;/option&gt;&lt;/select&gt; &lt;select style="width: 100px" name="attr_feature2"&gt;&lt;option value=0&gt;---&lt;/option&gt;&lt;option value=1&gt;dampening&lt;/option&gt;&lt;option value=2&gt;widened&lt;/option&gt;&lt;option value=3&gt;heightened&lt;/option&gt;&lt;option value=4&gt;lifelike&lt;/option&gt;&lt;/select&gt; &lt;input name="attr_imp_sensenotes" style="width: 175px;" type="text"&nbsp; /&gt; &lt;input name="attr_featurecount" type="hidden"/&gt; &lt;/fieldset&gt; &lt;input name="attr_totalsensefeaturecount" type="hidden"/&gt; the script bits: on("change:repeating_implantssenses:feature1 change:repeating_implantssenses:feature2", function () { &nbsp; &nbsp; getSectionIDs(`repeating_implantssenses`, idArray =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; const fieldnames = []; &nbsp; &nbsp; &nbsp; &nbsp; idArray.forEach(id =&gt; fieldnames.push( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `repeating_implantssenses_${id}_style`, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `repeating_implantssenses_${id}_feature1`, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `repeating_implantssenses_${id}_feature2` &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; getAttrs([...fieldnames], function (values) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const output = {}; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; idArray.forEach(id =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let fets = 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const style = values[`repeating_implantssenses_${id}_style`]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const f1val = parseInt(values[`repeating_implantssenses_${id}_feature1`]) || 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const f2val = parseInt(values[`repeating_implantssenses_${id}_feature2`]) || 0; //if the feature is not '---' or is not 'biogen' and 'lifelife' add 1 to 'fets' if (f1val &gt; 0){ if(style === 0){ fets++ } else { if(f1val &lt; 4){ fets++ } } } //if the feature is not '---' or is not 'biogen' and 'lifelife' add 1 to 'fets' if (f2val &gt; 0){ if(style === 0){ fets++ } else { if(f2val &lt; 4){ fets++ } } } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; output[`repeating_implantssenses_${id}_featurecount`] = fets; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAttrs(output); &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }); }); The idea is that for each repeating sections like the one above to check each line in the repeating section to determine if there are 1 or 2 features to be counted and update the&nbsp; for each line. Then I'll use our good friend repeatingSum to update&nbsp; totalsensefeaturecount &nbsp;(not included in the script above).&nbsp; I feel like this work to total the number of non-0 ("---") features per line, but it isn't updating featurecount.&nbsp;
1669067120

Edited 1669067325
Oosh
Sheet Author
API Scripter
I'm not sure why the attributes aren't updating - the code looks good at first glance, but unless you're using repeatingSum elsewhere I wouldn't worry about it here - you've already done almost all of the work yourself. You only need one more line to get your total: output [ 'totalsensefeaturecount' ] = Object . values ( output ). reduce ((total , value) =&gt; total += value , 0 ) ; console . log ( output ) ; Of course, if you are using repeating sum already, there's no harm in calling it again, it's just an unnecessary extra setAttrs call, which can add a few hundred milliseconds of lag to your sheet, depending on the player's connection. Hardly the end of the world, but best avoided where possible. Also a good old line of logging so you can actually check the output object and make sure it all looks good. And throw more logging in the loop to make sure your f1val's etc. have the expected values. If it's not working, throw logs at it until you find where the problem is. edit - those lines go immediately before the setAttrs call (and outside the forEach loop), forgot to put surrounding code in
typo found on line 8 and made a few changes and it is working! on("change:repeating_implantssenses:style change:repeating_implantssenses:feature1 change:repeating_implantssenses:feature2", function () { &nbsp; &nbsp; getSectionIDs(`repeating_implantssenses`, idArray =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; const fieldnames = []; &nbsp; &nbsp; &nbsp; &nbsp; idArray.forEach(id =&gt; fieldnames.push( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `repeating_implantssenses_${id}_style`, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `repeating_implantssenses_${id}_feature1`, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `repeating_implantssenses_${id}_feature2` &nbsp; &nbsp; &nbsp; &nbsp; )); //&lt;-----------------------------------------------------------fixed this dumb typo &nbsp; &nbsp; &nbsp; &nbsp; getAttrs([...fieldnames], function (values) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const output = {}; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; idArray.forEach(id =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let fets = 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const style = parseInt(values[`repeating_implantssenses_${id}_style`]) || 0; //&lt;--not sure why i didn't pasreInt this before? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const f1val = parseInt(values[`repeating_implantssenses_${id}_feature1`]) || 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const f2val = parseInt(values[`repeating_implantssenses_${id}_feature2`]) || 0; if(style == 1) { //&lt;-----------------------------better logic &nbsp;&nbsp;&nbsp;&nbsp;if (f1val &gt; 0){fets ++}; &nbsp;&nbsp;&nbsp;&nbsp;if (f2val &gt; 0){fets ++}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} if(style == 2) { &nbsp;&nbsp;&nbsp;&nbsp;if (f1val &gt; 0){if (f1val &lt;4){fets ++}}; &nbsp;&nbsp;&nbsp;&nbsp;if (f2val &gt; 0){if (f2val &lt;4){fets ++}}; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; output[`repeating_implantssenses_${id}_featurecount`] = fets; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAttrs(output); &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }); }); I ended up using the repeatingSum in another worker to avoid what I assume was related to asynchronous biz. Thanks for taking a look, Oosh!
1669704488
GiGs
Pro
Sheet Author
API Scripter
I wrote repeatingSum, and it's not intended to be run in another sheetworker, you'll likely run into asynchronous timing errors. It's better to separate it out into its own sheet worker, as you have done.
Thanks for confirming my suspicions, GiGs. I'm slowly getting a handle on this stuff. I figure soon it'll be time to dig into the api :)&nbsp;