Zoho CRMで他モジュールの項目を自動連携する方法【Deluge実装手順】

2026年05月26日

はじめに

Zoho CRMを運用していると、「商談モジュールの項目を更新したら、関連する仕入先モジュールの項目にも自動で反映させたい」というニーズが出てきます。 たとえば、商談で「仕入金額」を入力したら、その仕入先の管理レコードにも金額を転記したい、といったケースです。 この記事では、カスタム関数(Deluge)とワークフロールールを使って、モジュール間のフィールド値を自動連携する手順を、実装中にハマったポイントも含めて解説します。

やりたいこと

- 商談の「仕入金額」を入力/更新したら、対応する仕入先レコードの「仕入金額」に自動で転記する
- 仕入先は「仕入先名」のテキスト値を使って特定する
シンプルなクロスモジュール同期ですが、Zoho特有の落とし穴がいくつかあるので、最後まで読んでから実装することをおすすめします。

全体の流れ

1. 連携元・連携先のフィールドを準備する
2. 各フィールドのAPI名を確認する
3. カスタム関数(Deluge)を作成する
4. ワークフロールールを作成する
5. 引数マッピングを設定する
6. 動作確認

ステップ1: フィールドの準備

連携元と連携先の両方に、対応するフィールドを用意します。

今回の例では以下を準備しました。

  • 商談モジュールに「仕入金額」フィールド(数値型)
  • 仕入先モジュールに「仕入金額」フィールド(数値型)
  • 商談モジュールに「仕入先名」フィールド(1行テキスト、連携先を特定するためのキー)

ポイント: 両モジュールのフィールドは同じデータ型に揃えてください。型が違うと更新時にエラーになります。

ステップ2: API名の確認

設定 → 開発者向け情報 → APIとSDK → API名 から、フィルター基準を切り替えて該当モジュールのフィールドのAPI名を確認します。

今回の例だと以下のような構成でした。

  • 商談(Deals)
  • 仕入先名: Vender_syodan
  • 仕入金額: Purchase_Amount
  • 仕入先(Vendors)
  • 仕入先名: Vendor_Name
  • 仕入金額: Purchase_Amount

注意: 日本語ラベルから自動生成されるAPI名は、入力者の英語スペル次第で Vender のような綴りで作られていることがあります。必ず実物を確認しましょう。

ステップ3: カスタム関数の作成

設定 → 開発者向け情報 → 関数 → 新規作成

基本情報を入力します。

  • 表示名: 仕入金額同期
  • 関数名: sync_purchase_amount
  • カテゴリー: automation

コード本体は以下のとおりです。

void automation.sync_purchase_amount(String dealId)
{
    // 1. 商談レコードを取得
    query_data = Collection();
    query_data.insert("fields":"Vender_syodan,Purchase_Amount");
    sourceDeal = zoho.crm.v8.getRecordById("Deals", dealId.toLong(), query_data);

    vendorName = sourceDeal.get("Vender_syodan");
    purchaseAmount = sourceDeal.get("Purchase_Amount");

    // 2. 値の存在チェック
    if(isnull(vendorName) || isnull(purchaseAmount))
    {
        info "値が不足。終了。";
        return;
    }

    // 3. 仕入先モジュールから全レコードを取得
    page_num = 1;
    per_page_num = 200;
    options = Collection();
    options.insert("fields":"Vendor_Name");

    allVendors = zoho.crm.v8.getRecords("Vendors", page_num, per_page_num, options);

    // 4. ループで一致する仕入先を探す
    vendorId = "";
    for each vendor in allVendors.get("data")
    {
        if(vendor.get("Vendor_Name") == vendorName)
        {
            vendorId = vendor.get("id");
            break;
        }
    }

    if(vendorId == "")
    {
        info "一致する仕入先なし。終了。";
        return;
    }

    // 5. 仕入先の仕入金額を更新
    updateData = Collection();
    updateData.insert("Purchase_Amount":purchaseAmount);

    response = zoho.crm.v8.updateRecord("Vendors", vendorId.toLong(), updateData);
    info response;
}

ステップ4: ワークフロールールの作成

設定 → 自動化 → ワークフロールール → ルールを作成する

以下のように設定します。

  • モジュール: 商談
  • ルール名: 仕入金額同期
  • 実行条件: データの操作 → 作成または編集
  • 対象項目: 「特定の項目が更新されたとき」で「仕入金額」を選択
  • 適用範囲: すべての商談

ステップ5: アクションと引数マッピング

「すぐに実行する処理」→「+処理」→「関数」を選び、ステップ3で作成した関数を選択します。

ここで一番ハマりやすいのが引数マッピングです。

名前
dealId# を入力 → 商談モジュール → 「商談ID」を選択

値欄が空欄のままだと、関数に null が渡されて何も処理されません。設定後に必ず ${Deals.商談ID} のような表示が入っていることを確認してください。

完了する → 保存する → ワークフロー全体も保存。

ステップ6: 動作確認

  1. 商談を開いて「仕入金額」を変更して保存
  2. 対応する仕入先レコードを開く
  3. 「仕入金額」に同じ値が転記されていればOK

うまく動かないときは、設定 → 自動化 → アクションログ → 関数タブ から、該当関数の実行履歴を確認できます。info の出力内容を見れば、どこで止まっているかわかります。

ハマりポイントと解決策

実装中に何度か詰まったポイントを共有します。同じ落とし穴を避けるために、参考にしてください。

1. searchRecords がインデックス遅延で動かない

最初は仕入先を特定するのに zoho.crm.v8.searchRecords を使っていましたが、新規作成直後の仕入先レコードが見つからない問題に当たりました。

これはZoho公式の仕様で、「レコードを作成・編集してすぐに検索すると、インデックスの遅延により取得できないことがある(30〜60秒待つ必要がある)」とドキュメントに明記されています。

解決策として、getRecords で全件取得してループで一致を探す方法に切り替えました。レコード数が数百件程度ならパフォーマンス的にも問題ありません。

2. V8 API の構文ミス

V7と V8 で API の挙動が変わっている部分があります。特に注意すべきは以下です。

// ❌ V7のクセで書きがち(V8では動かない)
dealResponse.get("data").get(0).get("Test_1")

// ✅ V8では直接アクセス
dealResponse.get("Test_1")

V8の getRecordById は単一レコードを返すため、data でラップされていません。

3. getRecords の引数の型エラー

getRecords の引数を Map で渡そうとするとエラーになります。

// ❌ エラーになる
params = Map();
params.put("fields", "Vendor_Name");
params.put("per_page", 200);
allVendors = zoho.crm.v8.getRecords("Vendors", params);

// ✅ 正しい構文
options = Collection();
options.insert("fields":"Vendor_Name");
allVendors = zoho.crm.v8.getRecords("Vendors", 1, 200, options);

V8 の getRecords(モジュール名, ページ番号, 件数, オプション) の4引数構造です。

また、page と per_page を数値リテラルで直接書くと型エラーになることがあるので、変数経由で渡すのが安全です。

4. 引数マッピングの値が空になっている

ワークフロー側で関数を呼び出すときの引数マッピングは、保存途中で値だけ消えてしまうことがあります。「成功してるのに動かない」という現象が出たら、まず引数マッピング画面を再確認してください。

info dealId; を関数の冒頭に入れて、ログで null になっていないか見るのが一番確実です。

5. API名のタイプミス

「ラベルが日本語だから大丈夫」と思いきや、自動生成されるAPI名が予期せぬ綴りになっていることがあります。

今回も Vendor のつもりが Vender になっていたフィールドがあり、コードと一致せずに値が取れない事態が発生しました。

API名6. 無限ループの心配は不要

「商談を更新 → 仕入先を更新 → そのトリガーでまた商談を更新」のような無限ループを心配する人もいますが、Zoho公式仕様で「Delugeから更新したレコードはデフォルトではワークフローを再発火させない」ことになっています。

なので、双方向の同期を組んでも基本的にループは発生しません。は必ず「設定 → APIとSDK」で実物を確認するクセをつけましょう。

6. 無限ループの心配は不要

「商談を更新 → 仕入先を更新 → そのトリガーでまた商談を更新」のような無限ループを心配する人もいますが、Zoho公式仕様で「Delugeから更新したレコードはデフォルトではワークフローを再発火させない」ことになっています。

なので、双方向の同期を組んでも基本的にループは発生しません。

まとめ

Zoho CRMでモジュール間のフィールド連携を実装する流れは、以下の通りでした。

  1. 連携元と連携先のフィールドを揃える
  2. API名を正確に把握する
  3. カスタム関数で「取得 → 検索 → 更新」のロジックを書く
  4. ワークフロールールでトリガーを設定する
  5. 引数マッピングを丁寧に行う

特に重要なのは、searchRecords のインデックス遅延と引数マッピングの空欄問題です。この2つさえ押さえておけば、大抵のクロスモジュール連携は実装できるはずです。

同じような連携を組みたい方の参考になれば幸いです。

Zoho CRMで他モジュールの項目を自動連携する方法【Deluge実装手順】 | Zoho CRMを活用した中小企業へのDX支援は【And So株式会社】。全ての企業にDXを!