From 3661c16c806de9cbc358e9a7a06c7882dc6be143 Mon Sep 17 00:00:00 2001 From: Christoph Krieg Date: Mon, 27 Jun 2022 19:17:15 +0200 Subject: [PATCH 1/2] if not then exit --- .../if-not-find-then-exit/index.md | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 content/docs/BestPractices/if-not-find-then-exit/index.md diff --git a/content/docs/BestPractices/if-not-find-then-exit/index.md b/content/docs/BestPractices/if-not-find-then-exit/index.md new file mode 100644 index 00000000..0ca77802 --- /dev/null +++ b/content/docs/BestPractices/if-not-find-then-exit/index.md @@ -0,0 +1,99 @@ +--- +title: "if not then exit" +tags: ["AL"] +categories: ["Best Practice"] +--- + +_Created by sirhc101, Described by sirhc101_ + +## Description + +In general when we are working with tables we want to make sure, the filtered dataset includes records and does not result in a runtime error, so we use `if` to handle the result of `Find()`, `FindSet()`, `Get()`, etc. +This automatically causes on indent in source code and often the source code does not just contain one but two or more tables involved which leads to multi-level indentation. + +Basically this is a result of bad coding structure but maybe sometimes necessary. On the other hand this causes multiple `end;` usages and leads to the usage of colorization and other helpers to see which `begin` belongs to which `end;`. + +Instead of using `if (Record.FindSet()) then` to fetch records from a database it's good practice to use `if (not Record.FindSet()) then` following by an `exit();` to not further process the source code and make it clear for other developers where they can stop reading in certain cases. + +Furthermore, this more or less automatically leads to smaller and better structured procedures and reduces the complexity of the source code. + +## Bad code + +```al + SalesHeader.Reset(); + SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::Order); + SalesHeader.SetRange(Status, SalesHeader.Status::Open); + if (SalesHeader.FindSet(false)) then begin + repeat + SalesLine.Reset(); + SalesLine.SetRange("Document Type", SalesHeader."Document Type"::Order); + SalesLine.SetRange("Document No.", SalesHeader."No."); + if (SalesLine.FindSet(true)) then begin + repeat + DoSomething(); + until SalesLine.Next() = 0; + end; + until SalesHeader.Next() = 0; + + DoSomethingElse(); + end; +``` + +or + +```al + SalesLine.Reset(); + SalesLine.SetRange("Document Type", SalesHeader."Document Type"::Order); + if (SalesLine.FindSet(true)) then begin + repeat + case SalesLine."Type" of + SalesLine."Type"::Item: + DoSomethingItem(); + SalesLine."Type"::Resource: + DoSomethingResource(); + end; + until SalesLine.Next() = 0; + end; +``` + +## Good code + +```al + SalesHeader.Reset(); + SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::Order); + SalesHeader.SetRange(Status, SalesHeader.Status::Open); + if (not SalesHeader.FindSet(false)) then + exit; + + repeat + SalesLine.Reset(); + SalesLine.SetRange("Document Type", SalesHeader."Document Type"::Order); + SalesLine.SetRange("Document No.", SalesHeader."No."); + if (SalesLine.FindSet(true)) then begin + repeat + DoSomething(); + until SalesLine.Next() = 0; + end; + until SalesHeader.Next() = 0; + + DoSomethingElse(); +end; +``` + +or + +```al + SalesLine.Reset(); + SalesLine.SetRange("Document Type", SalesHeader."Document Type"::Order); + if (not SalesLine.FindSet(true)) then + exit; + + repeat + case SalesLine."Type" of + SalesLine."Type"::Item: + DoSomethingItem(); + SalesLine."Type"::Resource: + DoSomethingResource(); + end; + until SalesLine.Next() = 0; +``` \ No newline at end of file From 2c4e2cc99181d7959d8faf081ac4c18fdad086d0 Mon Sep 17 00:00:00 2001 From: Christoph Krieg Date: Mon, 27 Jun 2022 19:22:33 +0200 Subject: [PATCH 2/2] Update examples --- .../if-not-find-then-exit/index.md | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/content/docs/BestPractices/if-not-find-then-exit/index.md b/content/docs/BestPractices/if-not-find-then-exit/index.md index 0ca77802..ee1fe1f9 100644 --- a/content/docs/BestPractices/if-not-find-then-exit/index.md +++ b/content/docs/BestPractices/if-not-find-then-exit/index.md @@ -59,25 +59,37 @@ or ## Good code ```al - SalesHeader.Reset(); - SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::Order); - SalesHeader.SetRange(Status, SalesHeader.Status::Open); - if (not SalesHeader.FindSet(false)) then - exit; + procedure DoSomethingSalesOrder() + var + SalesHeader: Record "Sales Header"; + begin + SalesHeader.Reset(); + SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::Order); + SalesHeader.SetRange(Status, SalesHeader.Status::Open); + if (not SalesHeader.FindSet(false)) then + exit; - repeat + repeat + DoSomethingSalesLine(SalesHeader); + until SalesHeader.Next() = 0; + + DoSomethingElse(); + end; + + procedure DoSomethingSalesLine(var SalesHeader: Record "Sales Header") + var + SalesLine: Record "Sales Line"; + begin SalesLine.Reset(); SalesLine.SetRange("Document Type", SalesHeader."Document Type"::Order); SalesLine.SetRange("Document No.", SalesHeader."No."); - if (SalesLine.FindSet(true)) then begin - repeat - DoSomething(); - until SalesLine.Next() = 0; - end; - until SalesHeader.Next() = 0; + if (not SalesLine.FindSet(true)) then + exit; - DoSomethingElse(); -end; + repeat + DoSomething(); + until SalesLine.Next() = 0; + end; ``` or