メインコンテンツへスキップ

Documentation Index

Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt

Use this file to discover all available pages before exploring further.

以下の JavaScript サンプルでは、Advanced Script Rules でよく使われるパターンを紹介します。具体的には、field の有無の確認、数値の比較、条件付き検証の適用、テーブルデータの検証です。コピーして、ご自身の field 名や業務ルールに合わせて調整してください。

field が存在することを確認する

例えば、MyField field が検出され、値が設定されていることを確認します:
var field = Context.GetField("MyField");

if (!field) {
  Context.CheckSucceeded = false;
  Context.ErrorMessage = 'MyField fieldが見つかりません';
} else if (!field.Value) {
  Context.CheckSucceeded = false;
  Context.ErrorMessage = 'MyField fieldが空です';
}

浮動小数点数を比較する

浮動小数点数を直接比較すると、予期しない結果になることがあります。数値、特に金額を確実に比較するには、組み込みのMathオブジェクトのメソッドを使用してください。
// 2つの浮動小数点数を比較
var floatField1 = Context.GetField("Number Field 1");
var floatField2 = Context.GetField("Number Field 2");
var floatVal1 = floatField1.Value;
var floatVal2 = floatField2.Value;

if (Math.round(floatVal1) === Math.round(floatVal2)) {
    return;
} else {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = 'The values are different';
}

// 2つの金額値を比較
var moneyField1 = Context.GetField("Money Field 1");
var moneyField2 = Context.GetField("Money Field 2");
var value1 = moneyField1.Value.Amount;
var value2 = moneyField2.Value.Amount;

if (Math.abs(value1 - value2) <= 0.0001) {
    return;
} else {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = 'The values are different';
}

別のfieldに応じて、空でない値を必須にする

任意のfieldは、別のfieldの値によって必須になる場合があります。たとえば、MaritalStatusMarried の場合は、配偶者の姓と名のfieldを入力する必要があります。 このスクリプトルールは、MaritalStatusMarried のときに、SpouseFirstNameSpouseLastName の両方が入力されていることを検証します:
function checkFieldValuePresence(field) {
    if (!field.Value) {
        Context.ErrorMessage = field.Name + ' fieldの値を入力してください';
        return false;
    }
    return true;
}

var conditionField = Context.GetField("MaritalStatus");

if (conditionField === null) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = 'MaritalStatus fieldが見つかりません';
} else if (checkFieldValuePresence(conditionField)) {
    var lastName = Context.GetField("SpouseLastName");
    var firstName = Context.GetField("SpouseFirstName");
    if (conditionField.Text === "Married") {
        if (lastName === null || firstName === null) {
            Context.CheckSucceeded = false;
            Context.ErrorMessage = '配偶者名fieldが見つかりません';
        } else if (!checkFieldValuePresence(lastName) || !checkFieldValuePresence(firstName)) {
            Context.CheckSucceeded = false;
        }
    }
} else { // 婚姻状況が入力されていない場合、チェック失敗
    Context.CheckSucceeded = false;
}

field がドキュメント上にあることを確認する

ルールは、値が実際にドキュメントに印字されていない場合でも、field の値を補完することもできます。たとえば、複数の税が適用される場合、合計税額は自動的に計算できます。ただし、国によっては、合計税額をドキュメントに印字することが求められます。 このスクリプト ルールは、ドイツのレシートについて、合計税が画像上に実在することを確認します。他の国では、合計税の field に対して Required field フラグが有効になっているため、追加のチェックは不要です:
function checkFieldRegion(field) {
    if (!field || !field.HasRegion) {
        Context.ErrorMessage = '(' + field.Name + ') fieldが文書画像上に存在しません';
        return false;
    }
    return true;
}

var conditionField = Context.GetField("CountryOfOrigin");

if (!conditionField.Value) {
    Context.ErrorMessage = '原産国が不明のため、税金をチェックできません';
    Context.CheckSucceeded = false;
} else {
    var totalTaxField = Context.GetField("TotalTax");
    if (conditionField.Text === "DE" && !checkFieldRegion(totalTaxField)) {
        Context.CheckSucceeded = false;
    }
}

特定のケースでデータを検証する

合計税額がすべての税の合計に等しいことは、事前定義されたルール (Check Sum) で確認できます。ただし、国によっては税の1つが負の値になる場合があるため、すべての税を合算する場合と、返還税を加減算する場合の両方に対応できるのはスクリプトルールのみです。どちらの処理にするかは、原産国によって決まります。 このスクリプトは、2つの税の合計が合計税額に等しいことを検証します。例外として、スペインのレシートでは、2つの税の合計または差が合計税額に等しければ有効とみなします。
var conditionField = Context.GetField("CountryOfOrigin");
var totalTaxField = Context.GetField("TotalTax");
var tax1Field = Context.GetField("Tax1");
var tax2Field = Context.GetField("Tax2");

if (!conditionField.Value || !totalTaxField.Value || !tax1Field.Value || !tax2Field.Value) {
    Context.ErrorMessage = '税額を確認できません';
    Context.CheckSucceeded = false;
} else {
    if (conditionField.Text === "ES") {
        Context.CheckSucceeded = ((Math.round(tax1Field.Value - tax2Field.Value) === Math.round(totalTaxField.Value))
            || (Math.round(tax1Field.Value + tax2Field.Value) === Math.round(totalTaxField.Value)));
    } else {
        Context.CheckSucceeded = (Math.round(tax1Field.Value + tax2Field.Value) === Math.round(totalTaxField.Value));
    }
}

列の合計を外部の field と比較する

スクリプトは、通常の field だけでなく、テーブル内の値も参照できます。ルールチェックを高速化するため、テーブルを変数に保存し、テーブルを再取得する代わりにその変数を参照してください。変数にテーブル全体が含まれている場合は、Instances プロパティを使用して行にアクセスし、次に GetChild を使用して行内の特定のセルを取得します。 以下のサンプルでは、Total Price 列のすべての値を合計し、その結果を Total field と比較します。
var totalField = Context.GetField("Total");
var tableField = Context.GetField("MyTable");

if (!totalField) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "合計金額fieldが見つかりません";
    return;
}

if (!tableField) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "MyTable fieldが見つかりません";
    return;
}

var sum = 0;

for (var i = 0; i < tableField.Instances.length; i++) {
    var tableTotalField = tableField.Instances[i].GetChild("MyTable/Total Price");
    sum += tableTotalField.Value.Amount;
}

if (Math.abs(sum - totalField.Value.Amount) > 0.02) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "テーブル内の合計価格の合計が合計金額と一致しません";
}

列セルを外部の field と比較し、検証に失敗した行を一覧表示する

Context.GetFields を使用してテーブル列を参照すると、列内のすべてのセルを取得でき、ループ処理に役立ちます。 以下のサンプルでは、各行の税率を全体の税率と比較します。値が一致しない場合でも、スクリプトはただちに失敗せずに処理を続行し、不一致のある行番号を収集してエラーメッセージに表示します:
var taxRateFields = Context.GetFields("MyTable/TaxRate");
var taxRateField = Context.GetField("TaxRate");

if (!taxRateFields || !taxRateField)
    return;

var taxRate = taxRateField.Value ? taxRateField.Value : 0;
var wrongLines = [];
for (var i = 0; i < taxRateFields.length; i++) {
    if (taxRateFields[i].Value != taxRate)
        wrongLines.push(i + 1);
}

if (wrongLines.length > 0) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "以下の行で税率が正しくありません: " + wrongLines.join(", ");
}

行の値の積を別の行の値と比較する

テーブルの異なる列に対して、明示的なループを使わずに行単位で処理を実行できます。各列は Context.GetField を使って参照します。これにより、各行に対して自動的に実行される繰り返しルールが作成されます。なお、この方法で参照する列はすべて同一テーブル内のものに限ります。 以下のサンプルでは、各行で数量に単価を掛け、その結果を明細行の合計金額と比較します。
var quantityField = Context.GetField("MyTable/Quantity");
var unitPriceField = Context.GetField("MyTable/Unit Price");
var totalField = Context.GetField("MyTable/Total Price");

if (!quantityField || !unitPriceField || !totalField)
    return;

var quantity = quantityField.Value ? quantityField.Value : 0;
var unitPrice = unitPriceField.Value?.Amount ? unitPriceField.Value.Amount : 0;
var total = totalField.Value?.Amount ? totalField.Value.Amount : 0;

var result = quantity * unitPrice;

if (Math.abs(result - total) > 0.01) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "Quantity * Unit price is not equal to Total";
}

ビジネス ルールの自動化

Document skill にスクリプト ルールを追加し、読み取り/書き込み可能な field を設定して、テーブル列を参照します。

オブジェクト モデル

Advanced Script Rules で使用する完全な JavaScript オブジェクト リファレンスです。

Context

Context グローバル オブジェクト — ルール内から document、field、skill parameters にアクセスします。

Field

Field オブジェクト — ルールの実行中にドキュメントの field を確認し、変更します。