Use Google to find help fast. For example, search on "xpressdox choosefromlist".

Working with repeated elements – Part 2

Working with repeated elements – Part 2

This recipe continues the discussion in Working with repeated elements, which has as its example a Will where the children are the repeating elements.

Another common issue with repeating data is the requirement firstly to present a list of the repeating instances (in the previous example, the children) and then refer to items within the list by their ordinal values (i.e. first, second, third, etc.).  This is a rather complicated way of saying something like this:

Suppose some of the children in the list are still at school, and some not.  Then suppose the Will needs to refer to the still-at-school children by saying something like:

Any children still in school, which at the time of writing are the second, third and fifth child, will be provided for ….

As a starting point, something like this would get the process going:

Any children still in school, which at the time of writing  <<When(count(Child[StillInSchool = “Yes”]) > 1,are,is)>> the <<ForEach(Child)>><<If(StillInSchool = ‘Yes’)>><<Ordinal()>><<When(count(../Child) > 1),!, )>> <<End()>><<End(forEach)>> child, will be provided for …

This will work nicely if there is more than one child, but will not place “and” between the last and second-last children.  Usually this is tackled using the last() function, but last() applies to all of the elements in the ForEach, and in this case that is not correct, as we need it to apply only to the sub-list of children who are still at school, not to all the children.

What we need to do is keep a separate count of children still at school (i.e. set a variable to the value of count(Child[StillAtSchool = ‘Yes’)])) and also a manual version of position() – recording the position in the sub-list of still-at-school children.  For this we will set a variable NumberOfSchoolChild which will be incremented each time a still-in-school child is dealt with.

This is what it would look like:

<<SetV(‘TotalSchoolChildren”,count(Child[StillAtSchool = “Yes”]))>>
<<SetV(‘NumberOfSchoolChild’,1)>><<SetV(‘OneLess’,GetV(‘TotalSchoolChildren’)-1)>>

Any children still in school, which are the time of writing <<When(GetV(‘TotalSchoolChildren’) > 1,are,is)>> the <<ForEach(Child)>><<If(StillAtSchool = “Yes”)>><<Ordinal()>><<If(GetV(‘TotalSchoolChildren’) > 1)>><<If(GetV(‘NumberOfSchoolChild’) < GetV(‘OneLess’))>>, <<Else()>><<If(GetV(‘NumberOfSchoolChild’) = GetV(‘OneLess’))>> and <<End()>><<End(If/Else)>><<End(TotalSchoolChildren > 1)>><<IncrementV(‘NumberOfSchoolChild’)>><<End(StillAtSchool)>><<End(ForEach)>> child, will be provided for …

It is quite complicated, but then it’s a complicated problem!  And this is the solution.

The last example is shown below laid out in a way that is easier to read.  But beware – this is only for human readers, the code should be written as above otherwise the sentence will not be formatted correctly.

Any children still in school, which are the time of writing <<When(GetV(‘TotalSchoolChildren’) > 1,are,is)>> the

<<ForEach(Child)>>
   <<If(StillAtSchool = “Yes”)>>
   <<Ordinal()>>
      <<If(GetV(‘TotalSchoolChildren’) > 1)>>
         <<If(GetV(‘NumberOfSchoolChild’) < GetV(‘OneLess’))>>

,

         <<Else()>>
            <<If(GetV(‘NumberOfSchoolChild’) = GetV(‘OneLess’))>>

and

            <<End()>>
         <<End(If/Else)>>
      <<End(TotalSchoolChildren > 1)>>
      <<IncrementV(‘NumberOfSchoolChild’)>>
   <<End(StillAtSchool)>>
<<End(ForEach)>>
child, will be provided for …

Using ListDelimiter

In version 4.6 of XpressDox, the ListDelimiter function was introduced to assist with just this sort of problem.

Using ListDelimiter, the above code would look like:

<<SetV(‘TotalSchoolChildren”,count(Child[StillAtSchool = “Yes”]))>>
<<SetV(‘NumberOfSchoolChild’,1)>><<SetV(‘OneLess’,GetV(‘TotalSchoolChildren’)-1)>>

Any children still in school, which are the time of writing <<When(GetV(‘TotalSchoolChildren’) > 1,are,is)>> the <<ForEach(Child)>><<If(StillAtSchool = “Yes”)>><<Ordinal()>><<ListDelimiter(GetV('NumberOfSchoolChild'),GetV('OneLess'),', ',' and ')>><<IncrementV(‘NumberOfSchoolChild’)>><<End(StillAtSchool)>><<End(ForEach)>> child, will be provided for …

Leave a Reply