Zoho CRMのクライアントスクリプトによる氏名の自動入力とは、CRMの画面で「姓」と「名」を入れると、レコード名の「氏名」が決まった形で自動的に入る仕組みです。この記事では、中小の人材紹介企業のZoho CRM構築で当社が設計した仕組みをもとに、構成案と手順、コードを紹介します。一部の挙動は、執筆時点では実機での確認が済んでいません。該当する箇所には、確かめ方を添えています。

この会社では、人材を管理するカスタムモジュールのレコード名を「氏名」にしています。選考や請求のレコードから人を選ぶとき、選択欄にレコード名が表示されるためです。一方で、氏名を手入力にすると「姓と名の間のスペースの有無」「姓・名を直したのに氏名が古いまま」といった表記ゆれが起きます。そこで、氏名は姓・名から自動で組み立て、手では書き換えられないようにする設計にしました。

結論(先に要点)

  • 画面の入力はクライアントスクリプトで制御する(姓・名の変更で氏名を入力、氏名は編集不可。動作は環境で確認)
  • 画面を通らない登録(インポート・API・Webフォーム)はDelugeの関数で保存後に直す
  • 共通の処理は静的リソースにまとめ、各ページのスクリプトは呼び出し1行にする

なぜ二段構えが必要か

CRMの画面からの登録はクライアントスクリプトがその場で氏名を入れ、インポートやAPIなど画面以外の登録はワークフローとDelugeの関数が保存後に補正する二段構えを示した図

クライアントスクリプトとは、Zoho CRMの画面上で動くJavaScriptです。項目の値を入れたり、項目を編集不可にしたりできます。

ただし、クライアントスクリプトは画面の操作にしか反応しません。公式ドキュメントのFAQでは、実行できるページとして作成・編集・複製・詳細・一覧・ウィザードの各画面が挙げられています(FAQs of Client Script)。インポートやAPI、Webフォームからの登録は画面を通らないため、当社はこれらの入口では動かない前提で設計しています。人材の登録には、CSVのインポートや外部フォームからの登録も使います。画面だけ制御しても、それ以外の入口から入った氏名はそろいません。

そこで、役割を次のように分けます。

入口 担当する仕組み タイミング
CRMの画面(作成・編集・複製・詳細) クライアントスクリプト 姓・名を変えた瞬間
インポート・API・Webフォーム・ポータル ワークフロー+Delugeの関数 保存した後

画面の入力はその場で氏名が入るので、入力する人が結果をすぐ確かめられます。Delugeの関数は、画面以外から入ったデータの保険です。

全体の構成

部品は3種類です。この記事では、モジュールのAPI名を Talents、姓を Last_Name、名を First_Name、レコード名(氏名)を Name とします。

部品 数 役割
静的リソース NameUtils 1 氏名を組み立てる・項目を編集不可にする共通関数
クライアントスクリプト 10 各ページで氏名を編集不可(4本)、姓・名の変更で氏名を入力(6本)
Deluge関数 SetFullName+ワークフロー 関数1・ワークフロー2 画面以外から登録・更新されたときに、保存後に氏名を直す

クライアントスクリプトが10本になるのは、作成・編集・複製・詳細が別のページとして扱われるためです。公式ドキュメントでも、作成ページと複製ページは別のページとして並んでいます。作成ページに登録したスクリプトは、複製では動きません。

ページ 開いたとき(onLoad) 姓を変えたとき(onChange) 名を変えたとき(onChange)
作成ページ 氏名を編集不可 氏名を入力 氏名を入力
編集ページ 氏名を編集不可 氏名を入力 氏名を入力
複製ページ 氏名を編集不可 氏名を入力 氏名を入力
詳細ページ 氏名を編集不可 − −

STEP 1. 静的リソースを用意する

静的リソースとは、複数のクライアントスクリプトから呼び出せる共通のJavaScriptファイルです。10本のスクリプトに同じ処理を書くと、直すときに10か所を直すことになります。処理の本体は静的リソースにまとめます。

公式ドキュメントに書かれている主な制約は次のとおりです(Static Resources)。

  • 登録できるのはJSファイルのみ。1ファイル5MBまで、全体で200ファイルまで
  • 1ページで読み込めるのは5つまで
  • 圧縮(minify)したファイルを登録する
  • window と document は使えない

静的リソースの関数はグローバルに公開され、名前で直接呼び出します。ほかの静的リソースと名前がぶつからないよう、接頭辞を付けておきます(ここでは nu)。

/* NameUtils.js(圧縮して NameUtils.min.js として登録する) */

// 姓・名から氏名を組み立てる。形式は「姓 名」(半角スペース区切り)
// 姓がなければ名のみ、名がなければ姓のみ
function nuBuildFullName(lastName, firstName) {
    var last = String(lastName || '').trim();
    var first = String(firstName || '').trim();
    if (last !== '' && first !== '') {
        return last + ' ' + first;
    }
    if (last === '') {
        return first;
    }
    return last;
}

// 画面上の姓・名から氏名を組み立て、氏名の項目に入れる(引数は各項目のAPI名)
function nuSyncFullName(lastNameApi, firstNameApi, nameApi) {
    try {
        var lastName = ZDK.Page.getField(lastNameApi).getValue();
        var firstName = ZDK.Page.getField(firstNameApi).getValue();
        var fullName = nuBuildFullName(lastName, firstName);
        ZDK.Page.getField(nameApi).setValue(fullName);
        return fullName;
    } catch (error) {
        console.error('[氏名の自動入力] エラー:', error);
        return null;
    }
}

// 画面上の項目を編集不可にする(値は表示したまま)。引数はAPI名の配列
function nuLockFields(apiNames) {
    for (var i = 0; i < apiNames.length; i++) {
        try {
            ZDK.Page.getField(apiNames[i]).setReadOnly(true);
        } catch (error) {
            console.error('[項目の編集不可] エラー:', apiNames[i], error);
        }
    }
}

登録の手順です。

  1. 設定(歯車)→ 開発者スペース → クライアントスクリプト を開く
  2. 画面上部の 静的リソース タブで 新しいリソース をクリックする
  3. 名前に NameUtils と入れ、圧縮したファイル(NameUtils.min.js)を選んで保存する

圧縮前のファイルは、修正用として手元に残しておきます。修正したら圧縮し直し、静的リソースを差し替えます。

STEP 2. クライアントスクリプトを登録する

各ページのスクリプトは、静的リソースの関数を呼ぶ1行だけです。

// 作成・編集・複製・詳細ページの onLoad(4本とも同じ)
nuLockFields(['Name']);
// 作成・編集・複製ページの「姓」「名」の onChange(6本とも同じ)
nuSyncFullName('Last_Name', 'First_Name', 'Name');

1本ずつの登録手順は次のとおりです。

  1. 設定 → 開発者スペース → クライアントスクリプト → スクリプト タブ → 新しいスクリプト
  2. カテゴリは モジュール、モジュールは人材のモジュール、レイアウトは対象のレイアウトを選ぶ
  3. ページ(作成・編集・複製・詳細)と、イベントの種類を選ぶ
    • 編集不可にするスクリプト:ページのイベント → onLoad
    • 氏名を入れるスクリプト:項目のイベント → 項目に「姓」または「名」 → onChange
  4. コードエディター右側の 静的リソース から NameUtils を追加する(10本すべてで追加する)
  5. 上のコードを貼り付けて保存する

スクリプト名は「モジュール_ページ_内容」の形にそろえると、一覧で探しやすくなります(例:「人材_複製_姓の変更で氏名を入力」)。

最初に作成ページの2本(onLoadと姓のonChange)だけ登録し、動作を確かめてから残りを登録してください。 確かめるのは次の2点です。

  1. 作成画面を開いたとき、氏名が編集不可になっているか
  2. 姓を入れたとき、編集不可の氏名に値が入るか

動かない場合は、ブラウザの開発者ツールのコンソールでエラーを見ます。静的リソースの関数から ZDK を呼べない場合に備えて、スクリプト側に直接書く形も用意しておくと切り替えが早くなります。

// 静的リソースから ZDK を呼べなかった場合の書き方(姓・名の onChange)
var fullName = nuBuildFullName(
    ZDK.Page.getField('Last_Name').getValue(),
    ZDK.Page.getField('First_Name').getValue()
);
ZDK.Page.getField('Name').setValue(fullName);

複製ページと詳細ページの注意

  • 複製ページ:開いた直後は、複製元の人の氏名が入っています。姓・名を書き換えた時点で氏名が更新されます
  • 詳細ページ:詳細画面で値をクリックしてその場で直す操作(インライン編集)を、onLoadの編集不可で止める狙いです。ただし、インライン編集を止められるかは環境で確かめてください。止められない場合は、保存後にSTEP 3の関数が氏名を直します。詳細画面で姓・名をインライン編集した場合も、保存後にSTEP 3の関数が氏名を直します。反映は画面を再読み込みすると確認できます

STEP 3. Delugeの関数で画面以外の入口を補う

インポート・API・Webフォームから登録された人材は、クライアントスクリプトを通りません。保存後にワークフローから関数を動かし、氏名を「姓 名」にそろえます。

関数のコード

設定 → 開発者スペース → 関数 で新しい関数を作ります。カテゴリは 自動化、引数は recordId(文字列)です。connection には、人材モジュールを読み書きできる接続(スコープ ZohoCRM.modules.ALL など)を指定します。URLの zohoapis.jp は、お使いのデータセンターに合わせて変えてください。

void automation.SetFullName(string recordId)
{
	apiBase = "https://www.zohoapis.jp/crm/v8/";
	if(recordId == null || recordId == "")
	{
		info "対象IDが空のため終了します";
		return;
	}
	try
	{
		// 1. レコードを取得する
		getResp = invokeurl
		[
			url: apiBase + "Talents/" + recordId + "?fields=Name,Last_Name,First_Name"
			type: GET
			connection: "crm_conn"
		];
		if(getResp == null || getResp.get("data") == null)
		{
			info "レコードが取得できませんでした";
			return;
		}
		rec = getResp.get("data").get(0);
		lastName = ifnull(rec.get("Last_Name"),"").toString().trim();
		firstName = ifnull(rec.get("First_Name"),"").toString().trim();
		currentName = ifnull(rec.get("Name"),"").toString();

		// 2. 姓・名から氏名を組み立てる(姓がなければ名のみ、名がなければ姓のみ)
		fullName = lastName;
		if(lastName != "" && firstName != "")
		{
			fullName = lastName + " " + firstName;
		}
		else if(lastName == "")
		{
			fullName = firstName;
		}
		if(fullName == "" || fullName == currentName)
		{
			info "更新は不要です: " + currentName;
			return;
		}

		// 3. 氏名を更新する(trigger を空にしてワークフローを再実行させない)
		row = Map();
		row.put("id",recordId);
		row.put("Name",fullName);
		rows = List();
		rows.add(row);
		body = Map();
		body.put("data",rows);
		body.put("trigger",List());
		updResp = invokeurl
		[
			url: apiBase + "Talents"
			type: PUT
			parameters: body.toString()
			connection: "crm_conn"
		];
		info "氏名を更新しました: " + currentName + " → " + fullName + " / " + updResp;
	}
	catch (e)
	{
		info "氏名の自動入力でエラー: " + e;
	}
}

ポイントは2つです。

  • 値が同じなら更新しません。 画面から登録した人はクライアントスクリプトですでに正しい氏名が入っているため、ほとんどの場合はここで終わります
  • 更新時は trigger を空の配列にします。 関数の更新でワークフローがまた動き、同じ処理が繰り返されるのを防ぐためです。公式ドキュメントでは、レコード作成APIの trigger に空の配列を渡すとワークフローが実行されないと説明されています(Insert Records API)。また更新APIの説明には、同じレコードの作成・更新で動いたワークフローから関数経由で更新した場合、ワークフローは実行されないとあります(Update Records API)。仕様に頼り切らず、値が同じなら更新しない処理と合わせて二重に防いでおきます

ワークフローを2本作る

関数を動かす場面を絞るため、作成時と編集時でワークフローを分けます。

  1. 設定 → 自動化 → ワークフロー → ルールを作成
  2. 作成時のルール
    • 実行条件:データの操作 → 作成
    • 条件:すべてのデータ
    • 処理:すぐに実行する処理 → 関数 → SetFullName。引数 recordId に、人材モジュールの データID を挿入する
  3. 編集時のルール
    • 実行条件:データの操作 → 編集 → 特定の項目が変更されたとき で「姓」「名」を指定する(いずれかが変わったとき)
    • 繰り返し実行する にチェックを入れる(入れないと、2回目以降の姓・名の変更で動きません)
    • 条件・処理は作成時と同じ
  4. 2本とも一覧で 有効 になっていることを確かめる

編集時のルールを「姓・名が変わったとき」に絞っておくと、ほかの項目を直しただけでは関数が動きません。関数の実行回数を抑えられます。

STEP 4. 動作を確かめる

サンドボックス(本番と切り離した検証用の環境)で、次の6点を確かめてから本番へ反映します。本番へ反映するときの注意点は「Zoho CRM Sandbox(サンドボックス)から本番へ反映する落とし穴」にまとめています。

# 確かめること 方法
1 作成画面で氏名が編集不可になり、姓・名を入れると「姓 名」が入る 画面
2 編集画面で氏名が編集不可になり、姓を変えると氏名も変わる 画面
3 複製画面で氏名が編集不可になり、姓・名を変えると氏名が変わる 画面
4 詳細画面で氏名をインライン編集できない 画面
5 氏名を「仮」にしてAPIで作った人が、保存後に「姓 名」へ直る API
6 APIで姓を変えると、氏名も直る API

5と6は、検証用のデータに目印(例:「【検証】」)を付けて作り、終わったら削除します。あわせて、姓・名以外の項目だけをAPIで変えたときに関数が動かないことも見ておくと、ワークフローの絞り込みが効いているかを確かめられます。

レコード名は氏名と自動番号のどちらにするか:設計で決めておくこと

仕組みを作る前に、次の3点を決めておくと手戻りが減ります。

  1. レコード名を氏名にするか、自動番号にするか。 ルックアップの選択欄に名前を出したいなら氏名、重複や入力の手間を避けたいなら自動番号です
  2. 氏名の形式。 「姓 名」の順番、区切りを半角スペースにするか全角にするかを決め、クライアントスクリプトとDelugeで同じ形にします
  3. 姓・名のどちらを必須にするか。 外国籍の方には姓がない場合もあります。レコード名は必須なので、姓か名のどちらかが入っていれば保存できる形にしておくと、登録できない人が出ません

まとめ

  • 画面はクライアントスクリプトでその場で氏名を入れ、氏名は編集不可にする(編集不可の項目に値が入るか、インライン編集が止まるかは環境で確かめる)
  • 画面を通らない入口は、ワークフロー+Delugeの関数で保存後に直す
  • 共通の処理は静的リソースにまとめ、ページごとのスクリプトは1行にする
  • 作成・編集・複製・詳細は別のページ。登録漏れがないよう、一覧表で管理する

氏名に限らず「ほかの項目から自動で決まる値」は、同じ考え方で守れます。画面の制御と保存後の補正を組み合わせると、どの入口から入ったデータも同じ形にそろいます。クライアントスクリプトで外部のAPIを呼んで項目を埋める例は「郵便番号検索APIでZoho CRMに住所を自動入力」、Delugeの基本は「はじめてのDeluge(デリュージ)」で紹介しています。

CRMサポートセンターでは、Zoho CRMカスタマイズ・設定代行サービスで、Zoho CRMのクライアントスクリプト・Delugeの開発や、データ構造の設計をお手伝いしています。入力ルールの整備でお困りの際は、お気軽にご相談ください。

よくある質問

Zoho CRMのクライアントスクリプトとは何ですか?

Zoho CRMの画面上で動くJavaScriptです。作成・編集・詳細などのページを開いたときや、項目の値を変えたときに動き、項目に値を入れたり、項目を編集不可にしたりできます。画面の操作にしか反応しないため、インポートやAPIからの登録には別の仕組みが要ります。

連絡先(Contacts)でも同じ仕組みが必要ですか?

連絡先や見込み客には、標準で姓・名と氏名の項目が用意されています。この記事の仕組みが役に立つのは、カスタムモジュールでレコード名を1行テキストの「氏名」にしている場合です。

レコード名を自動番号にすれば、この仕組みは要らないのでは?

自動番号にすると入力の手間はなくなりますが、他のモジュールのルックアップで人を選ぶ欄に番号が表示されます。名前で選びたい場合は、レコード名を氏名のままにして自動入力する方が使いやすくなります。

姓がない人はどうなりますか?

本記事のコードは、姓がなければ名だけ、名がなければ姓だけを氏名に入れます。名前の構成が国によって異なる人材を扱う場合は、姓を必須にしないかどうかも合わせて決めてください。

クライアントスクリプトはどのエディションで使えますか?

当社が確認した時点(2026年10月)の公式ドキュメント(Client Scriptの概要ページ)では、EnterpriseとUltimateで使えるとされています。設定するユーザーのプロファイルでは、開発者権限(Developer Permissions)を有効にする必要があります。契約前に最新の公式ドキュメントでも確認してください。