Validating Data #3: Cascading VALIDATEs

In my post Validating Data #2: Using VALIDATE I addressed the issue of how to validate code entered data by using the field method VALIDATE. In my notes, however, I mentioned that a VALIDATE call comes with a price. This is what this post is about and how to make the cost as low as possible by smart programming your VALIDATE calls.

Changing the Posting Date – An Example

Let’s say, for what ever reason, you need to populate and validate the Posting Date field of a Gen. Journal Line record. Now before you start programming it take some time to investigate the implication of this VALIDATE call.

For me the simplest way to do this is to use the debugger when manually populating that field. So I …

  1. open the General Journal window
  2. activate the debugger (with Breakpoint on Triggers on)
  3. change the Posting Date
  4. validate the change, for example by leaving the field pressing TAB

Immediately the debugger will pop up and, yes unfortunately, it stops in codeunit 1 (ApplicationManagement). So I have to jump through some code, pressing F5 a couple of times, before I arrive where I want to be, i.e. the OnValidate trigger of the Posting Date field.

The fortunate thing now is that I immediately stumble upon a (next) VALIDATE and when I continue to step through the code with the debugger (pressing F8) I come across even more. The following list shows what field validations are being executed, one after the other:

“Posting Date”
  “Document Date”
  “Payment Terms Code”
“Currency Code”
  “Currency Factor”
    Amount
      “VAT %”
      “Bal. VAT %”

[Note: the indentation of a field indicates a hierarchical relationship between the indented field and its predecessor, i.e. the VALIDATE for the indented field is called in the OnValidate trigger of the previous field.]

Start NAV and give it a try yourself.

So the implication of validating the Posting Date field is that a cascade of VALIDATEs is brought about. ‘Big deal!’, you might think as activating the Posting Date OnValidate is the only way to enforce the business logic regarding this field. You are fully right. But guess what would happen if the next action would be to validate the Currency Code field? [:^)]

Yep, the second part of the cascade above would be executed again:

“Currency Code”
  “Currency Factor”
    Amount
      “VAT %”
      “Bal. VAT %”

That’s the price that comes with the use of VALIDATEs: re-execution of the same code multiple times and thus performance degradation.

Smart Programming

Nevertheless, by smart programming our VALIDATEs, i.e. use as little as possible of them, we can make the cost as low as possible.

Using our current example populating and validating both the Posting Date and Currency Code field the code could become something like this:

GenJnlLine.”Currency Code” := Cust.”Currency Code”;
GenJnlLine.VALIDATE(“Posting Date”, WORKDATE);

and this minimizing the amount of code executed. So do NOT use two VALIDATEs:

GenJnlLine.VALIDATE(“Posting Date”, WORKDATE);
GenJnlLine.VALIDATE(“Currency Code”, Cust.”Currency Code”);

Importing Transaction Data – A Second Example

Let’s take a second example where we need to import daily transaction data into the general journal from an external system through a file, e.g. a .csv file, having the following columns:

(1) g/l account number, (2) transaction description, (3) transaction amount (positive = debit/negative = credit)

Using the debugger we can draw the VALIDATE cascades for populating and validating the (1) Account No. and (2) Amount fields of a Gen. Journal Line record:

Account No.

“Job No.”
“Account No.”
  “Currency Code”
    “Currency Factor”
      Amount
        “VAT %”
        “Bal. VAT %”
  “VAT Prod. Posting Group”
    “VAT %”

Amount

Amount
  “VAT %”
  “Bal. VAT %”

As Amount is validated implicitly when validating Account No. there is no need to call the VALIDATE for this field explicitly. Therefore we can do with these lines of code:

GenJnlLine.Amount := Amnt_from_Import_Line;
GenJnlLine.VALIDATE(“Account No.”, AccntNo_from_Import_Line);

[where Amnt_from_Import_Line and AccntNo_from_Import_Line are two variables that contain the amount and g/l/ account number of the current line being imported]

Now this second example shows even more dramatically the need to be smart in programming VALIDATEs:

  • calling the Account No. validation will fires twice the validation of the VAT % field; separately calling the Amount validation would fire the VAT % validation a third time!
  • if you would run the debugger yourself you could also witness that local function GetCurrency will be called multiple times, i.e. from
    • “Currency Code” – OnValidate
    • Amount – OnValidate
    • “VAT %” – OnValidate
    • “Bal. VAT %” – OnValidate

With smart programming we strive to diminish the multi fold calls to the same code as much possible. Be smart, program smart! [I]

Note

In this post I did not argue populating a field by means of a VALIDATE. Look out for one of my next post on this issue. [;)]

Leave a Reply

Your email address will not be published.