A qRules customer recently came to us with a qRules task that I hadn't seen before. He had a highly nested data source divided into several sections, and he needed to copy some data from a secondary data source. Some of the data belonged in certain sections, and some belonged in other sections.
Now that Insert's /firstparentonly parameter is implemented, it would be possible to copy all of the secondary data rows into every section, and then filter the view to only display the ones that belong in each section, but this isn't ideal. It bloats the main data source, which can slow down InfoPath in a multitude of ways, most significantly in the rendering of the view. In the worst case, this can even crash InfoPath!
The solution we came up with is to use a field in each section to trigger the copy operation for just that section. We use some filtering to copy just the correct number of rows to each section and appropriately copy just the required values.
A form demonstrating this technique is available here (Right-click and select "Save target as..." to download it, and then rename its extension to XSN):
It contains a trial version of qRules. If the functionality doesn't work, please inject a newer trial or full version into it.
In this particular case, each section in the form has a Code field that corresponds to values in the secondary data source's Code field. For each section, we want to copy the secondary rows with the same code as that section, and leave all of the others.
Here are the salient details of the implementation.
CopyTrigger and StopAction
Each section group has a field called CopyTrigger, which will have rules to initiate the row copy for that particular group. There is also a field called StopAction, which serves as a dummy field which CopyTrigger can use to stop itself from executing.
CopyTrigger has three rules. The idea is that CopyTrigger will execute when it is set to the value "go" and then reset itself to blank.
1. In order to stop this action from infinitely repeating, the first rule is simply a rule to stop further rules from executing when CopyTrigger is blank. In InfoPath 2010, every rule must have some action, so here we just give it the arbitrary action of setting the StopAction field to blank.
2. The second rule initiates an Insert command to copy rows into the current section. The /parent XPath is filtered to target only the section that has CopyTrigger = 'go', which should be only the currently executing section. For the row count, the command uses the number of rows in the secondary data source that have the same code as the current section:
3. The final rule simply sets CopyTrigger back to its initial blank value so that it can be run again if needed.
SubChild, the actual group that we will be inserting, has rules to copy the actual values into the rows being inserted. This is a typical technique that we use for copying values using the Insert command, but it has a bit of an extra trick in that it's doubly filtered, first to filter out only the source rows that have the same code as the current section, and then a second filter to select the row within those rows that is in the same position as the row currently being inserted. This is the result:
Finally, we add a button that deletes all of the SubChild groups in the form, and then sets all of the CopyTrigger fields to go, and off the operation goes!
I hope this can prove useful to you if you have some need for this kind of scenario.