エラーの収集
AL コードでは複数のエラーをキャプチャし、ユーザー インターフェイスに表示できます。 この機能は収集可能なエラーと呼ばれ、検証シナリオを簡素化できます。 具体的には、修正すべきエラーのリストがユーザーに表示されるシナリオを簡素化できます。
通常、プロシージャでエラーが発生した場合は、発生した最初のエラーでプロシージャが停止します。 収集可能なエラーを使用すると、基本的にエラー処理はプロシージャ コールの最後まで延期されます。 AL コードの実装はエラーで停止しません。 代わりに、最後まで続行し、発生したエラーが収集されます。
AL には、収集可能なエラー機能専用に設計されたいくつかのメソッド、プロパティ、および属性が含まれています。
ErrorInfo.Create(String [, Boolean] [, var Record] [, Integer] [, Integer] [, String] [, Verbosity] [, DataClassification] [, Dictionary of [Text, Text]]) - 新しい ErrorInfo オブジェクトを作成します。
ErrorInfo.Callstack() - ErrorInfo オブジェクトが収集されたコール スタックを指定します。
ErrorInfo.Collectible([Boolean]) - ErrorBehavior.Collect を使用してエラーを収集可能かどうかを指定します。
ErrorInfo.CustomDimensions([Dictionary of [Text, Text]]) - エラーに関連する辞書として指定された一連の分析コード。
ErrorInfo.FieldNo([Integer]) - エラーが関連するフィールド ID を指定します。
ErrorInfo.PageNo([Integer]) - エラーが関連するページ番号を指定します。
ErrorInfo.RecordId([RecordId]) - エラーが関連するレコードのレコード ID を指定します。
ErrorInfo.SystemId([Guid]) - エラーが関連するレコードのシステム ID を指定します。
ErrorInfo.TableId([Integer]) - エラーが関連するテーブル ID を指定します。
ErrorInfo.AddAction(Text, Integer, Text) - エラーのアクションを指定します。
AddAction メソッドは次の 3 つのパラメーターを受け取ります。
Caption: エラーの UI でアクションのキャプションとして表示されるテキスト文字列。
CodeunitID: アクションがエラーの UI から開始された際に実行される Codeunit の ID。 Codeunit には、エラー アクションによって呼び出されるグローバル メソッドを少なくとも 1 つ含める必要があります。 グローバル メソッドには、ErrorInfo オブジェクトを受け取るために、ErrorInfo データ型のパラメーターを指定する必要があります。
Method Name: アクションで実行する Codeunit のメソッドの名前。 CodeunitID パラメーターを使用して指定します。
収集されたエラーを処理するために、システム データ型で次のメソッドを利用できます。 これらのメソッドを呼び出すには、プロパティ アクセスの構文を使用します。
System.HasCollectedErrors() - 現在のエラー収集スコープでエラーが収集されたかどうかを示す値を取得します。
System.GetCollectedErrors([Boolean]) - 現在の収集スコープで収集されたエラーをすべて取得します。
System.ClearCollectedErrors() - 現在の収集スコープから収集されたエラーをすべてクリアします。
収集されたエラーのリストをクリアしても、データベースに加えた変更はロールバックされません。 したがって、ほとんどの場合、クリア操作を 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;
}