Working with optional NAV table fields

Now that we have entered the Extension era we must take into account that some extensions may or may not be installed at the time of code execution.

You might even have two Extensions that you would like to share data.

Let’s give an example.

In Iceland we add a new field to the Customer table (18).  That field is named “Registration No.” and is being used for a 10 digit number that is unique for the individual or the company we add as a customer to your system.

My Example Extension can support Icelandic Registration No. if it exists.

Using Codeunit 701, “Data Type Management”, Record Reference and Field Reference we can form the following code.

LOCAL PROCEDURE GetCustomerRegistrationNo@10(Customer@1000 : Record 18) RegistrationNo : Text;
VAR
  DataTypeMgt@1001 : Codeunit 701;
  RecRef@1002 : RecordRef;
  FldRef@1003 : FieldRef;
BEGIN
  IF NOT DataTypeMgt.GetRecordRef(Customer,RecRef) THEN EXIT('');
  IF NOT DataTypeMgt.FindFieldByName(RecRef,FldRef,'Registration No.') THEN EXIT('');
  RegistrationNo := FldRef.VALUE;
END;

Let’s walk through this code…

GetRecordRef will populate the record reference (RecRef) for the given table and return TRUE if successful.
FindFieldByName will populate the field reference (FltRef) for the given record reference and field name and return TRUE if successful.

Call this function with a code like this.

Customer.GET('MYCUSTOMER');
RegistrationNo := GetCustomerRegistrationNo(Customer);

We could create a more generic function.

LOCAL PROCEDURE GetFieldValueAsText@103(RecVariant@1000 : Variant;FieldName@1004 : Text) FieldValue : Text;
VAR
  DataTypeMgt@1001 : Codeunit 701;
  RecRef@1002 : RecordRef;
  FldRef@1003 : FieldRef;
BEGIN
  IF NOT DataTypeMgt.GetRecordRef(RecVariant,RecRef) THEN EXIT('');
  IF NOT DataTypeMgt.FindFieldByName(RecRef,FldRef,'Registration No.') THEN EXIT('');
  FieldValue := FldRef.VALUE;
END;

This function can be used in more generic ways, like

Customer.GET('MYCUSTOMER');
RegistrationNo := GetFieldValueAsText(Customer,'Registration No');

Vendor.GET('MYVENDOR');
RegistrationNo := GetFieldValueAsText(Vendor,'Registration No');

See where I am going with this?

So the other way around…

LOCAL PROCEDURE SetCustomerRegistrationNo@21(VAR Customer@1000 : Record 18;RegistrationNo@1004 : Text) : Boolean;
VAR
  DataTypeMgt@1001 : Codeunit 701;
  RecRef@1002 : RecordRef;
  FldRef@1003 : FieldRef;
BEGIN
  IF NOT DataTypeMgt.GetRecordRef(Customer,RecRef) THEN EXIT(FALSE);
  IF NOT DataTypeMgt.FindFieldByName(RecRef,FldRef,'Registration No.') THEN EXIT(FALSE);
  FldRef.VALUE := RegistrationNo;
  RecRef.SETTABLE(Customer);
  EXIT(TRUE);
END;

And using this with

Customer.GET('MYCUSTOMER');
SetCustomerRegistrationNo(Customer,'1234567890');

More generic versions can be something like this.

PROCEDURE PopulateOptionalField@25(VAR RecordVariant@1000 : Variant;FieldName@1001 : Text;FieldValue@1002 : Variant) : Boolean;
VAR
  RecRef@1004 : RecordRef;
  FldRef@1003 : FieldRef;
BEGIN
  IF NOT GetRecordRef(RecordVariant,RecRef) THEN EXIT;
  IF NOT FindFieldByName(RecRef,FldRef,FieldName) THEN EXIT;
  FldRef.VALUE := FieldValue;
  RecRef.SETTABLE(RecordVariant);
  EXIT(TRUE);
END;

PROCEDURE ValidateOptionalField@26(VAR RecordVariant@1000 : Variant;FieldName@1001 : Text;FieldValue@1002 : Variant) : Boolean;
VAR
  RecRef@1004 : RecordRef;
  FldRef@1003 : FieldRef;
BEGIN
  IF NOT GetRecordRef(RecordVariant,RecRef) THEN EXIT;
  IF NOT FindFieldByName(RecRef,FldRef,FieldName) THEN EXIT;
  FldRef.VALIDATE(FieldValue);
  RecRef.SETTABLE(RecordVariant);
  EXIT(TRUE);
END;

To use these functions we first need to copy our record to a variant variable and then back to the record after the function completes.

RecordVariant := Customer;
PopulateOptionalField(RecordVariant,'Registration No.','1102713369');
Customer := RecordVariant;

Or

RecordVariant := Customer;
ValidateOptionalField(RecordVariant,'Registration No.','1102713369');
Customer := RecordVariant;

I have requested Microsoft to add more generic functions to Codeunit 701, “Data Type Management”.  I trust that they will deliver as usual.

That NAV Codeunit is one of my favorite ones delivered by Microsoft.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.