> ## 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.

# カスタムルール作成用のサンプルスクリプト

> カスタム FlexiCapture ルール用の VBScript、JScript、C# コードのサンプル。テーブルデータチェック、値リスト検索、チェックマークグループ、住所解析を扱います。

この記事では、ABBYY FlexiCapture における一般的なカスタムルールのユースケース向けサンプルスクリプトを紹介します。該当する例には、VBScript 版と JScript 版の両方が含まれています。

<div id="automation-rule">
  ## 自動化ルール
</div>

この例では、テーブルデータのチェックを示します。このルールは、テーブルデータが集計結果のfieldの値と一致するかどうかを確認します。テーブルには、商品の価格と数量のカラムがあります。このルールは、テーブルと集計結果のfieldを含むセクションレベルで記述されています。

<CodeGroup>
  ```vb VBScript theme={null}
  dim autoRule
  set autoRule = CreateObject( "AutomationRule.CheckDoc" )
  autoRule.CheckResult me.FIELD("cost"), me.FIELD("number"), me.FIELD("Result"), me
  ```

  ```javascript JScript theme={null}
  var autoRule = new ActiveXObject( "AutomationRule.CheckDoc" );
  autoRule.CheckResult( Field("cost"), Field("number"),
      Field("Result"), this );
  ```
</CodeGroup>

<div id="code-of-an-activex-component">
  ### ActiveX コンポーネントのコード
</div>

以下のコードは、上記のスクリプトで使用されている `AutomationRule` プロジェクトの `CheckDoc` クラスのコードです。

```vb theme={null}
Option Explicit

' テーブルデータが結果と一致するかどうかを確認する
' column1 - 価格列
' column2 - 数量列
' resultField - 結果フィールド（<Total> または同等のもの）
' docObj - チェック対象のドキュメントノード
Public Sub CheckResult(ByRef column1 As Object, ByRef column2 As Object, _
ByRef resultField As Object, ByRef docObj As Object)
On Error GoTo err_h
Dim costItems AsObject, numItems AsObject
Dim curCost AsDouble, curNum AsLong, sum AsDouble
Dim result AsDouble
Dim i AsLong
Set costItems = column1.Items
Set numItems = column2.Items
' テーブルデータを合計する
    sum = 0
For i = 0 To costItems.Count - 1
        curCost = costItems.Item(i).Value
        curNum = numItems.Item(i).Value
        sum = sum + curNum * curCost
Next
   ' 比較結果を小数点以下第2位に丸める
    result = resultField.Value
If (Round(result, 2) = Round(sum, 2)) Then
        docObj.CheckSucceeded = True
Else
        docObj.CheckSucceeded = False
docObj.ErrorMessage = "Table data does not match the resulting value"
        resultField.Suggest sum
   End If
Exit Sub
err_h:
docObj.ErrorMessage = Err.Description
    docObj.CheckSucceeded = False
End Sub
```

<div id="search-in-the-variants-list">
  ## 候補リストでの検索
</div>

このルールでは、field の値がリスト内のいずれかの値に一致するかどうかを確認します。一致しない場合は、ルールエラーフラグが表示され、その field には推奨値のリストが設定されます。チェック結果に応じて、その field は確信ありまたは確信なしで認識されたものとしてマークされます。

<CodeGroup>
  ```vb VBScript theme={null}
  'field の値を保存
  Dim fieldValue
  fieldValue = me.Field("Field6").Value
  'チェック用の値リストを作成
  Dim list(5)
  dim i
  for i = 0 to 4
      list(i) = "2" & i
  next
  dim success
  success = false
  'field の値がリスト内の値と一致するかどうかをチェック
  for i = 0 to 4
  if list(i) = fieldValue Then
          success = true
          exit for
  end if
  next
  'チェック結果に応じて、field の認識確信状態を設定
  me.Field("Field6").IsVerified = success
  'field の推奨値リストを設定。推奨値には以下の
  '適切な値を指定できます
  if success = false then
      for i = 0 to 4
  me.Field("Field6").Suggest( list(i) )
      next
  end if
  'エラーフラグを設定
  me.CheckSucceeded = success
  ```

  ```javascript JScript theme={null}
  // field の値を保存
  var fieldValue = Field("Field6").Value;
  // チェック用の値リストを作成
  var list = new Array(5);
  for( i = 0; i < 5; i++ ) {
      list[i] = "2" + i
  }
  var success = false;
  // field の値がリスト内の値と一致するかどうかをチェック
  for( i = 0; i < 5; i++ ) {
  if( list[i] == fieldValue ) {
          success = true;
          break;
  }
  }
  // チェック結果に応じて、field の認識確信状態を設定
  Field("Field6").IsVerified = success;
  // field の推奨値リストを設定。推奨値には以下の
  // 適切な値を指定できます
  if( !success ) {
  for( i = 0; i < 5; i++ ) {
          Field("Field6").Suggest( list[i] );
      }
  }
  // エラーフラグを設定
  CheckSucceeded = success;
  ```
</CodeGroup>

<div id="field-match-check">
  ## Field の一致チェック
</div>

このルールは、field が一致しているかどうかを確認します。

<CodeGroup>
  ```vb VBScript theme={null}
  if me.Field("InvoiceNumber").IsMatched then
   me.CheckSucceeded = true
  else
   me.CheckSucceeded = false
   me.ErrorMessage = "Field InvoiceNumber is not matched"
  end if
  ```

  ```javascript JScript theme={null}
  if( Field("InvoiceNumber ").IsMatched ) {
   CheckSucceeded = true;
  } else {
  CheckSucceeded = false;
   ErrorMessage = "Field InvoiceNumber is not matched";
  }
  ```
</CodeGroup>

<div id="checkmark-check">
  ## チェックマーク のチェック
</div>

このルールは、チェックマーク が選択されているかどうかを確認します。

<CodeGroup>
  ```vb VBScript theme={null}
  if me.Field("Page status").Value then
      me.CheckSucceeded = true
  else
      me.CheckSucceeded = false
      me.ErrorMessage = "Page status is not checked"
    me.FocusedField = me.Field(Page status)  ""
  end if
  ```

  ```javascript JScript theme={null}
  if( Field("Page status").Value ) {
      CheckSucceeded = true;
  } else {
  CheckSucceeded = false;
      ErrorMessage = "Page status is not checked";
      FocusedField = Field("Page status");
  }
  ```
</CodeGroup>

<div id="checkmark-group-check">
  ## チェックマークグループのチェック
</div>

このルールは、グループ内のすべてのチェックマークを順に調べ、どれも選択されていない場合は先頭のチェックマークを選択します。このルールは、チェックマークグループレベルで記述されています。グループ内のすべてのチェックマークは、ルールに含まれる field のリストに追加されており、グループ自体はそのリストから除外されています。既定のチェックマーク (先頭のもの) では、ReadOnly フラグが無効になっています。グループ内にチェックマークがない場合は、ルールエラーフラグが有効になります。

このサンプルは、ルールに含まれるすべての field を順に処理します。field 名は指定されていないため、このコードは任意のチェックマークグループで使用できます。

<CodeGroup>
  ```vb VBScript theme={null}
  if me.Fields.Count = 0 then
      me.CheckSucceeded = false
      me.ErrorMessage = "There are no checkmarks in the group"
  else
      dim isChosen, i
      isChosen = false
  for i = 0 to me.Fields.Count - 1
         if me.Fields.Item( i ).Value then
              isChosen = true
              exit for
  end if
  next
  if Not isChosen then
          me.Fields.Item(0).Value = true
      end if
  me.CheckSucceeded = true
  end if
  ```

  ```javascript JScript theme={null}
  if( Fields.Count == 0 ) {
      CheckSucceeded = false;
      ErrorMessage = "There are no checkmarks in the group";
  } else {
      var isChosen = false;
      var i;
  for( i = 0; i < Fields.Count; i++ ) {
          if( Fields.Item( i ).Value ) {
              isChosen = true;
              break;
  }
  }
  if( !isChosen ) {
          Fields.Item(0).Value = true;
      }
  CheckSucceeded = true;
  }
  ```
</CodeGroup>

<div id="field-reliability-check">
  ## field の信頼性チェック
</div>

このルールは、field 内の疑わしい文字数をチェックし、その数が 3 つ以上の場合は field をクリアします。これは自動補正スクリプトです。

<CodeGroup>
  ```vb VBScript theme={null}
  Dim totQty, suspQty
  Dim i
  totQty = me.Symbols.Count
  suspQty = 0
  for i = 0 to totQty - 1
    if me.Symbols.Item(i).IsSuspicious = true then
      suspQty = suspQty + 1
    end if
  next
  if suspQty >= 3 then
    me.Text = ""
  end if
  ```

  ```javascript JScript theme={null}
  var susp, qty, strpos, i, SC, strposPrev
  strposPrev = 1
  qty = 0
  SC = "1"
  susp = SuspiciousSymbols
  for ( i = 0; i < susp.length; i++) {
      strpos = susp.indexOf (SC,i)
  if ((strpos != strposPrev) && (strpos != -1)) {
        qty = qty + 1
        strposPrev = strpos
      }
  }
  if (qty >= 3) {
    text = ""
  }
  ```
</CodeGroup>

<div id="character-replacement-without-losing-regions-and-verification-flags">
  ## RegionとVerificationフラグを失わない文字置換
</div>

このスクリプトは、RegionおよびVerificationフラグに関する情報を失うことなく、`+`を`&`に置き換えます。これは自動補正スクリプトです。

```vb theme={null}
Dim totQty
Dim i
totQty = me.Symbols.Count
for i = 0 to totQty - 1
if me.Symbols(i).Symbol = "+" then
    me.Symbols(i).Symbol = "&"
end if
next
```

<div id="batch-integrity-check">
  ## バッチ整合性チェック
</div>

コントロールページで指定されたドキュメント数が、バッチインベントリ上の数および実際に処理されたドキュメント数と一致するかどうかを確認します。一致しない場合は、エラーが返されます。

<CodeGroup>
  ```vb VBScript theme={null}
  dim DQty
  dim i
  for i = 0 to me.Batch.Documents.Count - 1
    if me.Batch.Documents.Item(i).DefinitionName = "Inv" then
      DQty = me.Batch.Documents.Item(i).IndexedItemValue("DocQty")
      exit for
  end if
  next
  dim AcQty
  AcQty = me.Batch.Documents.Count
  if acqty <> DQty then
    me.CheckSucceeded = false
    me.ErrorMessage = "Incorrect number of documents in the batch:" & " " & AcQty& ". " & "Expected number:" & " " & DQty & "!"
  end if
  ```

  ```javascript JScript theme={null}
  for ( i = 0; i < [Batch.Documents.Count - 1]; i++ ) {
  var TemplName = Batch.Documents.Item(0).DefinitionName;
    if (TemplName = "Inv") {
      var DQty = Batch.Documents.Item(i).IndexedItemValue("DocQty");
      break ;
  }
  }
  var AcQty = Batch.Documents.Count -1
  if (AcQty != DQty) {
      CheckSucceeded = false;
      ErrorMessage = "Incorrect number of documents in the batch:" + " " + AcQty + "." + "Expected number:" + " " + DQty +"!" ;
  }
  ```
</CodeGroup>

<div id="counting-the-number-of-documents-and-pages-in-a-document-set">
  ## ドキュメントセット内のドキュメント数とページ数をカウントする
</div>

このスクリプトは、ドキュメントセット内のドキュメント数とページ数をカウントし、セットに不明な型の要素が含まれている場合はエラーをスローします。

```csharp theme={null}
int subDocumentsCount = 0;
int pagesCount = 0;
IBatchItem asBatchItem = Context.Document.AsBatchItem;
IBatchItems items = asBatchItem.ChildItems;
foreach (IBatchItem item in items)
{
if ( item.Type == TBatchItemType.BIT_Page )
{   pagesCount ++;  }
else if( item.Type == TBatchItemType.BIT_Document )
{   subDocumentsCount ++; }
else
{
Context.CheckSucceeded = false;
Context.ErrorMessage = "Unknown type of element in set";
}
}
Context.Field("Field").Text = subDocumentsCount.ToString() + " " + pagesCount.ToString();
```

<div id="address-parsing">
  ## 住所解析
</div>

このスクリプトは、住所を次の要素 (郵便番号、国、市区町村、住所) に分割します。ソース field の一部に対して呼び出されます。

```csharp theme={null}
//-----------------------------------------
var collectionName = "";
IFieldExtractor extractor = Context.GetFieldExtractor();
extractor.ParseAddress();
var city = extractor.ExtractedObjects( collectionName, "NerCity" );
var country = extractor.ExtractedObjects( collectionName, "NerCountry" );
var zip = extractor.ExtractedObjects( collectionName, "NerZipCode" );
var street = extractor.ExtractedObjects( collectionName, "NerStreet" );
for( var i = 0; i < city.Count; i++ ) {
extractor.PutSpanToField( city.Item(i).Span, Context.Field("City") );
}
for( var i = 0; i < country.Count; i++ ) {
extractor.PutSpanToField( country.Item(i).Span, Context.Field("Country") );
}
for( var i = 0; i < zip.Count; i++ ) {
extractor.PutSpanToField( zip.Item(i).Span, Context.Field("ZIP") );
}
for( var i = 0; i < street.Count; i++ ) {
extractor.PutSpanToField( street.Item(i).Span, Context.Field("Street") );
}
//-------------------------------------
```
