There are different ways to do this, depending on whether you have to use the column's required validation expression or have the license to do it different ways.
Design Considerations
Is this going to be a freestyle datawindow where you only need to validate the rule once for the screen, or a tabular style where users can mass enter sets of data and the rule needs to be applied to each row?
Do you want to require the users to enter the correct values each time a required field gets focus or do you want to let them freely navigate the screen and validate at save time?
You'll get some different responses here, I expect, but I prefer to use the column specification expressions only for simple checks because:
- Complicated logic in there tends to get hard to read and maintain
- If you have multiple error conditions you're checking for, that can lead to some unwieldy messages if you use the column specification's built-in error message field
However, I'll grant that dw expressions are generally really fast.
Using a Computed Field for Validation Rules
One alternative technique is also a fast performer and can be used in most versions of PB.
- Have a computed field on the datawindow that has a meaningful name such as
cf_amount_rule
and something like this in the expression: if (debit + credit = amount, 0, 1)
- Make that field invisible to the user if you want
- Add another computed field in the footer to sum
cf_amount_rule
and you now have a handy reference point that quickly tells you when there is an error
- At save time (or the pfc_validation event for PFC users) you can check for sum > 0 and post an error message
OO purists might suggest that it's wrong to put logic in the datawindow and if you find yourself putting in the same rule in multiple datawindows that's certainly a code smell. But for simple rules that are unlikely to change I have found time and again that the datawindow is very efficient at running these rules and saving you from having to write lots of code elsewhere.
Optional Goodies
- You can make the error message more robust by using the find() functionality to identify specific rows with the error
- You provide useful visual cues to your users by changing the row or a field's background color via property expressions that reference
cf_amount_rule
.