ServiceNowで開発をしていると「親子関係にあるチケットのフォームにおいて子のフォーム/リストに親の項目を表示したい」という要望がよくあります。この要望について、要望のパターンごとの適切な実装方式を解説します。
要望のパターン
この種の要望は、どこに表示するかという観点で「フォーム上に表示したい」のか「リスト(関連リスト)に表示したい」のかで2パターン、次に、何を表示したいかという観点で「親テーブルの項目を表示したい」のか「親テーブルを拡張したテーブルの項目を表示したい」のかで2パターン、掛けて4パターンに分類できます。さらに、各パターンに対して親テーブルの項目を読み取り専用にするかどうか、親テーブル側の値が変わった場合にも同期が必要かどうか、というバリエーションが存在します。
各パターンに対する基本的な対応方法は下表の通りです。ただし、上述のバリエーションによって、最適な方法は変わります。
パターン | 表示したい場所 | 表示したい項目 | 具体例 | 基本的な対応方法 |
---|---|---|---|---|
1 | 子テーブルのフォーム | 親テーブルの項目 | 承認テーブルのフォームに承認対象のタスクレコードのAssigned to項目を表示したい | Form Layoutで設定可能 |
2 | 子テーブルのフォーム | 親テーブルを拡張したテーブルの項目 | 承認テーブルのフォームに承認対象のインシデントレコードのCaller項目を表示したい | 工夫が必要(後述) |
3 | 子テーブルのリスト(関連リスト) | 親テーブルの項目 | 承認テーブルのリストに承認対象のタスクレコードのAssigned to項目を表示したい | List Layoutで対応可能 |
4 | 子テーブルのリスト(関連リスト) | 親テーブルを拡張したテーブルの項目 | 承認テーブルのリストに承認対象のインシデントレコードのCaller項目を表示したい | List Layoutで対応可能 |
以下、それぞれの設定方法について説明します。Form Desiger(フォームデザイナー)やList Layout(リストレイアウト)と言われてピンとこない方は、まずは下記の記事を参照ください。
子テーブルのフォームに親テーブルの項目を表示(パターン1)
子テーブルのフォームに親テーブルの項目を表示させたい場合(パターン1)は、Form Layout(フォームレイアウト)で設定できます。フォームの設定はよりグラフィカルなForm Designer(フォームデザイナー)から行うのが一般的ですが、この設定はForm Layoutから行います。
Form Layoutのslushbucket(左から選んで右に移動させていくUI)で親テーブルへの参照項目を選択すると、slushbucket中央に階層のアイコンが表示されるので、それをクリックし参照先(親)テーブルの項目を表示させ、選択します。
子テーブルのフォームに親テーブルの拡張テーブルの項目を表示(パターン2)
子テーブルのフォームに親テーブルの拡張テーブルの項目を表示したい場合(パターン2)は、Form Layoutで設定しようとしても、slushbucketに親テーブルの拡張テーブルの項目が表示されません。そのため、少し工夫が必要です。いずれにしてもパターン1, 3, 4と比べ少し面倒になるので、まずは要望を落とせないか、リスト上だけの表示(パターン4)で妥協できないかを考えるべきです。その上でどうしても必要な場合、やり方はいくつか考えられるのですが、個人的には下記の2択から、後述のオプション要望の状況等を考慮し選択するのがよいと考えます。
方法① 子テーブルに親テーブルと同じ値を保持するための項目を作成
次の3つの設定を行うことで要望を実現します。
- 子テーブル側に親テーブルと同じ値を格納するための項目を作成
- 子テーブル作成時に親テーブルの項目を同期するために、Default valueまたはClient Scriptを設定
- 子テーブル作成後に親テーブルのフォーム側で値が変更されたときのために、値を同期するBusiness Ruleを設定
1は説明不要だと思うので、2,3についてもう少し詳しく説明します。
2. 子テーブル作成時に親テーブルの項目を同期するために、Default valueまたはClient Scriptを設定
子テーブルのレコードが親テーブルのフォームの関連リストから作成される想定の場合(レコードを作成する時点で親レコードが確定している場合)は、Default valueで次のように設定することで、値を同期できます。
一方、親レコードをユーザが自分で選択した際に同期させるためには、on ChangeのClient Scriptを設定する必要があります。この際、getReference()関数を使うと、親テーブルの項目しか取得できないため、親テーブルの拡張テーブルの項目を取得するためのScript Includeを作成した上で、GlideAjax経由で呼び出す必要があります(もっとスマートなやり方があれば是非コメントください)。こうなるとかなり面倒なので、関連リストから作成する想定でない場合は方法②がよいかもしれません。
3. 子テーブル作成後に親テーブルのフォーム側で値が変更されたときのために、値を同期するBusiness Ruleを設定
子テーブル作成後に親テーブルのフォーム側で値が変更されたときその変更を子テーブル側にも伝搬させる必要がある場合は、Business Ruleを作成するのがよいでしょう。要望によってはこの機能は落とせる場合もあります。
方法② 子テーブルに親テーブルの拡張テーブルへの参照(Reference)項目を作成
次の3つの設定を行うことで要望を実現します。
- 子テーブル側に親テーブルの拡張テーブルへの参照(Reference)項目を作成
- 手順1で作成した項目を必要に応じて自動導出するように設定
*設定方法は上述の方法①の手順1と同様です - パターン1と同様にForm Layoutで設定
子テーブルのリストに親テーブル/親テーブルの拡張テーブルの項目を表示(パターン3,4)
子テーブルのリストに親テーブル/親テーブルの拡張テーブルの項目を表示させたい場合(パターン3,4)は、リストの場合は、パターン1の時とほぼ同様にして、List Layoutで設定できます。
List Layoutの場合は、階層マークを押下した際、slushbucketに親テーブルの項目だけでなくその拡張テーブルの項目まで表示されます。そのため、親テーブルの項目の場合でも、親テーブルの拡張テーブルの項目の場合でも同様に設定ができます。
バリエーション: 親テーブルの項目は読み取り専用にする
親テーブルの項目を子テーブルのフォーム/リストに表示させた際に、子テーブルのレコードのフォーム/リスト上で、参照先の親テーブルの項目を変更させたくないという場合があります。参照フィールド自体を読み取り専用にするかどうかで対応が変わります。
参照項目自体も読み取り専用でよい場合
参照項目ごと読み取り専用でよい場合、具体的には「子レコードは親テーブルのフォームの関連リストから”New(新規)”ボタンを押下して作成するためユーザが指定する必要がない」といったパターンです。
この場合は、親テーブルへの参照項目を読み取り専用に設定しておくことで、参照項目や、自動導出した項目も全て読み取り専用となります。
参照項目は編集可能にしたい場合
参照項目は編集可能にしたい場合、具体的には「子レコード側でユーザが親レコードを指定する」といったパターンです。
この場合は、パターン②方法1のように子テーブル側に親テーブルと同じ値を格納するための項目を作成しているのであれば、その項目を読み取り専用にすればよいです。Form LayoutやList Layout上で項目を導出している場合は、UI Policyで導出した項目のみ読み取り専用に設定する必要があります。
バリエーション: 常に同期ではなくデフォルト値だけ同期したい
親レコードの項目の値を常に同期させるのではなく、子レコードを作成する際にデフォルト値として親レコードの値を使い、必要に応じて子レコードは親レコードとは異なる値を設定できるようにしたい場合があります。
この場合は、パターン1, 3, 4であっても、パターン2の方法①で紹介したように、子テーブル側に親テーブルと同じ値を格納するための項目を作成する方式がよいです。
以上です。
コメント