Microsoft

Blog Categories

Subscribe to RSS feed

Archives

Conditional logic in InfoPath

I consider InfoPath Forms Services to be one of the most underrated features of SharePoint. When combined with workflows, InfoPath allows us to streamline most day-to-day tasks. Sometimes that takes a little creativity…
A scenario that I’ve run into a few times now is trying to find the first non-null value from a given set of fields. Most recently, I created a production log in InfoPath where each row represented an hour’s worth of parts successfully produced. I wanted to be able to report on the most recent hour’s production (similar to SQL’s COALESCE statement), but there’s no obvious way to do that.
In most systems, we’d use some form of "if", "while", "switch" or other conditional statements. For InfoPath actions, validation, and formattion rules, most functions are geared around math or string manipulation.
A workaround
It turns out that we can create conditional logic in InfoPath through a combination of the string-length() function, multiplication, and number comparisons.
A warning: this approach definitely isn’t pretty, but it works.
The crux of this trick is that comparisons return boolean values but booleans can be cast to strings. That means that a statement like "1 > 0" returns "true" while "1 < 0" returns "false". We can then take a logical comparison’s output and wrap it with the string-length() function. That gives either 4 or 5 (for the lengths of "true" or "false"). We can then use those values to determine which value to return.
An example of how we’d handle conditional logic in most languages:

if (value1 > value2)

output = value1;

else

output = value2;

In InfoPath, we can instead do:
(5 - string-length(value1 > value2)) * value1 + (5 - string-length(value1 <= value2)) * value2

If the first string length will be 4 for "true" and 5 – 4 = 1, the first multiplication returns value1. If the second string length will be 5 for "false" and 5 – 5 = 0, the second multiplication will return value2.

Conditional logic in action

I applied this approach to the production form mentioned above. Employees would enter their hourly production and the latest hour’s data would be promoted to a promoted field for SharePoint reporting.

The code ended up like this:

../my:goodParts16 + (string-length(../my:goodParts16 > 0 or ../my:badParts16 > 0) - 4) *(../my:goodParts15 + (string-length(../my:goodParts15 > 0 or ../my:badParts15 > 0) - 4) *(../my:goodParts14 + (string-length(../my:goodParts14 > 0 or ../my:badParts14 > 0) - 4) *(../my:goodParts13 + (string-length(../my:goodParts13 > 0 or ../my:badParts13 > 0) - 4) *(../my:goodParts12 + (string-length(../my:goodParts12 > 0 or ../my:badParts12 > 0) - 4) *(../my:goodParts11 + (string-length(../my:goodParts11 > 0 or ../my:badParts11 > 0) - 4) *(../my:goodParts10 + (string-length(../my:goodParts10 > 0 or ../my:badParts10 > 0) - 4) *(../my:goodParts9 + (string-length(../my:goodParts9 > 0 or ../my:badParts9 > 0) - 4))))))))

As can be seen, the code piles up quickly but it works. If the user has entered data for the 4:00pm hour, that branch will show. Otherwise, it will check for 3:00pm, then 2:00pm, etc.

Attached is an example InfoPath form template demonstrating this approach. After downloading the file, remove the ".rename" extension from its name.

  • InfoPath form template with conditional logic

Leave a Reply