エラーの収集

完了

AL コードでは複数のエラーをキャプチャし、ユーザー インターフェイスに表示できます。 この機能は収集可能なエラーと呼ばれ、検証シナリオを簡素化できます。 具体的には、修正すべきエラーのリストがユーザーに表示されるシナリオを簡素化できます。

通常、プロシージャでエラーが発生した場合は、発生した最初のエラーでプロシージャが停止します。 収集可能なエラーを使用すると、基本的にエラー処理はプロシージャ コールの最後まで延期されます。 AL コードの実装はエラーで停止しません。 代わりに、最後まで続行し、発生したエラーが収集されます。

AL には、収集可能なエラー機能専用に設計されたいくつかのメソッド、プロパティ、および属性が含まれています。

AddAction メソッドは次の 3 つのパラメーターを受け取ります。

  • Caption: エラーの UI でアクションのキャプションとして表示されるテキスト文字列。

  • CodeunitID: アクションがエラーの UI から開始された際に実行される Codeunit の ID。 Codeunit には、エラー アクションによって呼び出されるグローバル メソッドを少なくとも 1 つ含める必要があります。 グローバル メソッドには、ErrorInfo オブジェクトを受け取るために、ErrorInfo データ型のパラメーターを指定する必要があります。

  • Method Name: アクションで実行する Codeunit のメソッドの名前。 CodeunitID パラメーターを使用して指定します。

収集されたエラーを処理するために、システム データ型で次のメソッドを利用できます。 これらのメソッドを呼び出すには、プロパティ アクセスの構文を使用します。

収集されたエラーのリストをクリアしても、データベースに加えた変更はロールバックされません。 したがって、ほとんどの場合、クリア操作を if Codeunit.Run then ... ステートメントと組み合わせることは理にかなっています。

ErrorBehavior attribute では、メソッド スコープ内の収集可能なエラーの動作を指定します。 [ErrorBehavior(ErrorBehavior.Collect)] をプロシージャに追加すると、プロシージャのスコープで発生するエラーを収集して処理できます。

次のコード例は、収集可能なエラーの使用方法を示しています。 これは、テーブル フィールドに何を含めることができる (または含めることができない) かについて基本的な基準を設定する、DoPost codeunit を基に構築されます。 このプロシージャは、エラーが発生すると停止します。

PostWithErrorCollect ()プロシージャとPostWithErrorCollectCustomUI () プロシージャは、ErrorBehavior(ErrorBehavior::Collect)属性を適用してこれらのエラーを収集して表示する方法を示します。

pageextension 50100 CollectingErrorsExt extends "Customer List"
{
    actions
    {
        addfirst(processing)
        {
            // This action doesn't collect errors. Any procedure will stop on the first error that occurs,
            // and return the error.
            action(Post)
            {
                ApplicationArea = All;
                trigger OnAction()
                var
                    i: Record Integer;
                begin
                    i.Number := -9;
                    Codeunit.Run(Codeunit::DoPost, i);
                end;
            }

            // This action collects errors. The PostWithErrorCollect procedure continues on errors,
            // and displays the errors in a dialog to the user done.
            action(PostWithErrorCollect)
            {
                ApplicationArea = All;
                trigger OnAction()
                begin
                    PostWithErrorCollect();
                end;
            }

            // This action collects errors. The PostWithErrorCollectCustomUI procedure continues on errors,
            // and displays error details in a list page when done.
            // This implementation illustrates how you could design your own UI for displaying and
            // troubleshooting errors.
            action(PostWithErrorCollectCustomUI)
            {
                ApplicationArea = All;
                trigger OnAction()
                begin
                    PostWithErrorCollectCustomUI();
                end;
            }
        }
    }

    [ErrorBehavior(ErrorBehavior::Collect)]
    procedure PostWithErrorCollect()
    var
        i: Record Integer;
    begin
        i.Number := -9;
        Codeunit.Run(Codeunit::DoPost, i);
        // After executing the codeunit, there will be collected errors,
        // and therefore an error dialog will be shown when exiting this procedure.
    end;

    [ErrorBehavior(ErrorBehavior::Collect)]
    procedure PostWithErrorCollectCustomUI()
    var
        errors: Record "Error Message" temporary;
        error: ErrorInfo;
        i: Record Integer;
    begin
        i.Number := -9;
        // By using Codeunit.Run, you ensure any changes to the database within
        // Codeunit::DoPost are rolled back in case of errors.
        if not Codeunit.Run(Codeunit::DoPost, i) then begin
            // If Codeunit.Run fails, a non-collectible error was encountered,
            // add this to the list of errors.
            errors.ID := errors.ID + 1;
            errors.Description := GetLastErrorText();
            errors.Insert();
        end;

        // If there are collected errors, iterate through each of them and
        // add them to "Error Message" record.
        if HasCollectedErrors then
            foreach error in system.GetCollectedErrors() do begin
                errors.ID := errors.ID + 1;
                errors.Description := error.Message;
                errors.Validate("Record ID", error.RecordId);
                errors.Insert();
            end;

        // Clearing the collected errors will ensure the built-in error dialog
        // will not show, but instead show our own custom "Error Messages" page.
        ClearCollectedErrors();

        page.RunModal(page::"Error Messages", errors);
    end;
}


codeunit 50100 DoPost
{
    TableNo = Integer;

    trigger OnRun()
    begin
        if Number mod 2 <> 0 then
            Error(ErrorInfo.Create('Number should be equal', true, Rec, Rec.FieldNo(Number)));

        if Number <= 0 then
            Error(ErrorInfo.Create('Number should be larger than 0', true, Rec, Rec.FieldNo(Number)));

        if Number mod 3 = 0 then
            Error(ErrorInfo.Create('Number should not be divisible by 10', true, Rec, Rec.FieldNo(Number)));

        // Everything was valid, do the actual posting.
    end;
}