How to write customized code

Writing customized code is easy; customized code should look like standard code. How to write customized code? Like standard code! You have to keep in mind that any code you write today will probably be maintained by others in the future. If you follow your own programming conventions, we are pretty sure you'll find them easier to write and read. Unfortunately, others may not be used to your conventions, so you'll be making their work harder.

Like it or not, all Dynamics NAV developers are used to reading code from the standard application. If everyone writes customized code like the standard application does, everybody will only be able to read their own code. To make it easy to maintain an application, it is important to follow a few strict guidelines while writing C/AL code. This chapter will cover these guidelines. The information found in this section is taken from C/AL Programming Guide.

Language

In the standard application, all C/AL code is entered in English (United States). If all code is in the same language, it is easier to maintain the applications, including add-ons for several countries.

Spacing and alignment

There must be exactly one space character on each side of binary operators such as assignment or plus, as shown in the following example:

y := (a + b) / 100;

There must not be any space between a unary operator and its argument, as shown in the following example:

y := -x;

In general, use an indentation of two character spaces, as shown in following the example:

IF a <> '' THEN
  Record.TESTFIELD(b);

When you split a C/AL statement into two or more lines, indent the continuation line by two characters, as shown in the following example:

MyVariable := 
  Variable1 + Variable2 * 2 + Variable3 * 3;

MyFunction(
  Expression1,Expression2,
  Expression3,Expression4);

Comments

Always start comments with // followed by one character space. Never use curly brackets ({ and }). To emphasize a comment, put it on a separate line and insert one empty line before it, as shown in the following example:

// Comment 
x := x * 2;

If the comment is on the same line as the C/AL code, add one character space before the comment sign, as shown in the following example:

x := '....'; // Comment

Text constants


Error messages and other message strings must be entered as text constants. That way, the message can be easily translated and the users can see the same message in their own language.

Text constants will automatically be assigned unique IDs by C/SIDE. You can see the ID by opening the C/AL Globals window, selecting the text constant, and navigating to its Properties window.

When you are working in the C/AL Editor window, place the cursor on a text constant and the content of the text constant will be shown in the message line.

C/AL statements

The IF and THEN statements should normally be on the same line. The ELSE statement should be on a separate line as shown in the following example:

IF x = y THEN
  x := x + 1 
ELSE 
  x := -x - 1;

If the last statement in the THEN part of an IF-THEN-ELSE statement string is an EXIT command or an ERROR command, do not continue with an ELSE statement, as shown in the following code snippet:

IF x <> y THEN 
  EXIT(TRUE);
x := x * 2;

When the BEGIN statement follows the THEN, ELSE, or DO statement, it should be on the same line, preceded by one character space as shown in the following snippet:

IF (x = y) AND (a = b) THEN BEGIN 
  x := a; 
  y := b; 
END;

REPEAT should always be alone on a line. Indentation of REPEAT statements is shown in the following example snippet:

REPEAT
  <Statement>;
UNTIL <expr>;

REPEAT
  <Statement>;
UNTIL <expr> AND
        <expr>;

When you use a CASE statement, indent the possibilities by two character spaces. Two or more possibilities on the same line are separated by commas (with no spaces), and the last possibility on a line is immediately followed by a colon (with no preceding space).

The action starts on the line after the possibility, further indented by two character spaces. If there is a BEGIN statement, it should be placed on a separate line unless it follows the ELSE statement. In this case, it should be on the same line as the ELSE statement.

CASE Field OF
  Field::A:
    BEGIN
      x := x + 1;
      y := -y - 1;
    END;
  Field::B:
    x := y;
  Field::C,Field::D:
    y := x; 
  ELSE BEGIN 
    y := x;
    a := b;
  END;
END;

If there are more than two alternatives, use a CASE statement; otherwise, use an IF statement.

Naming conventions

Precise and consistent terminology helps the end user work with the application. Rules for naming and abbreviating everything will also help programmers gain an understanding of the base application and develop new features faster.

Remember that the user will see the value of the caption property but not the name property. But you, as a developer, must follow the naming convention in this section both for the name in English (United States) and for the caption in your local language.

Naming objects

Two objects of the same type must not have the same name. In general, each object must be named in a way that leaves no doubt as to what it is concerned with (for example, an object can be specifically related to customers, items, or resources). Do not give a table the name Status, for example, because the word is too general and could refer to something in almost every table.

Table objects

The names of table objects are always singular. That is, the table name corresponds to what one record in the table is called.

Page objects

The name of a page depends on the page type. A card page has the singular form of the table name and a list page has the plural form of the table name. This gives the users an idea of the type of page they have selected or that which will be presented. If a table can be accessed by both a card page and a list page, the page names should explicitly describe the page types (for example, item card and item list). This tells the user that there is more than one way to access the table. Other page types (for example, statistics) are given names that are as descriptive as possible.

Report objects

The naming of reports is as important as that of pages and tables. For example, users see the caption of a report object when they need to identify a sales invoice, or when they modify or create reports. The caption is also shown in the request page. This is why the caption (and the name in English) should be as descriptive as possible and not include abbreviations. Whenever possible, the caption should be the same as the heading in the actual report.

Table fields

The name and caption of a field should be as descriptive as possible and should be able to stand alone, that is, the user should not need to see the caption in the context of other fields in order to understand what it is.

The field contents and the field type should be described in the caption. For example, include Date while you name a date field (for instance, Posting Date). If the field contains a percentage, include it. This is displayed with the percentage sign, for example, Profit %. Include Quantity (or Qty.) when you name a quantity field, for example, Quantity Shipped. Replace Quantity with No. while referring to the number of entries, for example, No. Printed and No. of New Records. Include Amount (or Amt.) while you name an amount field, for example, Debit Amount.

Codeunit objects

A codeunit is named almost like a report, except that the name begins with the object that the codeunit processes, followed by a dash. The object is normally a record abbreviated as a variable (see rules for this in the next section). The description of the codeunit is written in the imperative (without abbreviations, if possible), for example, Purch-Explode BOM.

Variables

Use the existing terminology whenever possible; for instance, the standard application usually names variables that refer to the General Journal Line table as GenJnlLine. Blanks, periods, and other characters (such as parentheses) that would make quotation marks around a variable necessary, must be omitted. For example, the periods and blanks are omitted in the GenJnlBatch variable. In addition, currency unit signs, such as $, should be replaced by the corresponding currency unit code, for example, AmountUSD.

User-defined functions

While naming user-defined functions, if possible start with a verb in the imperative, for example, ApplyCustLedgEntry. Usage of function name prefixes are shown in the following examples:

  • If the code posts something, use Post as a prefix
  • If the code makes something, use Make as a prefix
  • If the code inserts something, use Insert as a prefix
  • If something is checked, use Check as a prefix

Using small functions

Every Dynamics NAV object allows you to create functions inside itself. Instead of writing all your code in an existing trigger, break up your code into small steps. Write each small step's code in a separate function, give the function a name so that it explains what it does, and call your function from where you need it. This will ensure that you do not not write the same thing twice.

If the functions you are creating are to be called from one single object, create them on the object. If the functions are to be called from many objects, create them in a codeunit to group them all, or create them on a table if the function refers to a record of a table.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset