
右クリックメニューは86件のレコードでできている(sys_ui_context_menu)
ServiceNow のリストを右クリックすると、小さなメニューがふわっと開きます。列ヘッダーなら「Sort」「Configure」「Export」、行の上なら「Copy sys_id」「Show Matching」。毎日のように使うのに、あの一覧がどこで定義されているかは、あまり知られていません。
正体は sys_ui_context_menu という1枚のテーブルです。右クリックで出る項目は、ここに1行ずつ登録されています。どこを右クリックしたか、どのテーブルの一覧か、いまのユーザーに権限があるか。その条件で、出す項目と出さない項目が選り分けられる仕組みです。
この記事では、その定義テーブルを PDI で開き、86件の中身を1つずつ数えてみました。仕組みが分かると、「なぜこの項目はここに出るのか」が腑に落ちます。「自分でメニューを1つ足すにはどこを触るのか」も見えてくるはずです。地味な機能ですが、リスト操作の裏側がよく見えます。
この記事は、ServiceNow の PDI(Personal Developer Instance、無料の個人検証環境)Zurich リリース・OOTB(初期設定)で確認した実測メモです。件数・項目は REST と実画面で確認しました(確認日 2026-07-20)。本番環境では設定が異なります。
まずは、実際に右クリックした瞬間の画面を見てください。Incident の一覧で「Number」列のヘッダーを右クリックすると、Sort・Group By・Bar Chart・Configure・Export … といった項目がずらりと開きます。この一覧の一つひとつが、これから読む sys_ui_context_menu の1レコードに対応しています。

コンテキストメニューとは:右クリックメニューの置き場所
コンテキストメニューは、右クリックした場所に応じて開く小さなメニューです。ServiceNow では、その項目の定義を sys_ui_context_menu にまとめて持っています。1つのメニュー項目が、このテーブルの1レコードに対応する。とても素直な作りです。
PDI で sys_ui_context_menu の一覧を type 順に並べたのが次の画面です。1行ずつが、メニューに現れる項目に対応しています。

実測した総件数は 86件でした。しかも86件すべてが active=true、つまり全部が有効です。無効化された項目は0件でした。初期状態では、ここに並ぶ項目がそのままリストの右クリックメニューを形づくります。この「テーブルで管理する」という発想は、ServiceNow のあちこちに共通します。画面のUI部品さえ、コードではなくレコードとして持ち、条件で出し分ける。だから管理者は、プログラムを書かずにメニューを増減できます。先ほどの一覧を type で並べ替えると、同じ種類の項目がかたまって見えます。定義の全体像をつかむときは、この type 順が便利でした。
1つ押さえておきたいのは、この86件が「リスト(一覧画面)の右クリック」に関する定義だという点です。OOTB で選べるメニュー位置は、リストの3か所だけでした。フォーム上の右クリックは別の仕組みが担います。この記事は、一番よく使うリストの右クリックを取り上げます。
右クリックからメニューが出るまで
はじめに、右クリックしてからメニューが描画されるまでの流れを図にします。定義テーブルのどの列が、どの段階で効くのかが分かります。

順番はこうです。最初に「どこを右クリックしたか」で候補を絞り込みます。次は「その一覧はどのテーブルか」の判定。全テーブル共通の項目と、特定テーブルだけの項目を、ここで合流させます。さらに condition(表示条件)を評価し、権限やリストの状態に合わない項目を落とします。最後に残った項目を order の順で並べ、type に従って描画する。この4段階を毎回くぐって、あの小さなメニューが組み上がります。
つまり sys_ui_context_menu の主要な列は、この解決の各段階に対応します。menu は位置。table は対象。condition は出し分け。order は並び順。そして type が見た目と動きを決めます。1件の定義は、この5列の組み合わせで「いつ・どこで・どう出るか」が決まる仕組みです。以降のセクションで、5つの列を1つずつ実測します。
type:メニュー項目の5つの種類
まずは type を見ます。type は、その項目がメニュー上で何になるかを決める列です。選択肢は Action / Menu / Separator / Label / Dynamic actions の5つがありました。

実測の件数はこうでした。Action が44件で最多。次いで Dynamic actions が25件、Menu が9件、Separator が8件と続きます。Label は選択肢としてはあるものの、OOTB では使われている行が0件でした。合計すると 44+25+9+8 で86件。ちょうど総数と一致します。
役割はそれぞれ違います。Action はクリックすると動く普通の項目。Separator は区切り線で、名前を持たず、項目のグループを視覚的に分けます。Menu はサブメニューで、その中に子項目をぶら下げる箱です。少し特殊なのが Dynamic actions で、メニューを開くたびにスクリプトで項目を組み立てます。静的に決まった項目と、開くたびに中身が変わる項目が同居する。この4種類を並べ替えるだけで、単純なリストから階層の深いメニューまで作れます。
menu:どこを右クリックしたか
次は menu 列です。これは「リストのどこを右クリックしたか」という位置を表します。OOTB の選択肢は3つだけでした。
List header(列ヘッダー) … 58件。列名の上を右クリックしたときのメニュー
List row(行) … 17件。データ行の上を右クリックしたときのメニュー
List title(タイトル) … 11件。一覧のタイトル部分を右クリックしたときのメニュー
件数の偏りが、そのまま機能の重さを表します。列ヘッダーの58件が飛び抜けて多い。ソートやグループ化、列の設定、エクスポートや Configure サブメニュー。「一覧そのものを操作する」機能が、ここに集中しています。行の17件は、その1レコードに対する操作でした。タイトルの11件は、表示ビューやフィルタの切り替えといった全体設定です。実際に View・Filters・Group By・Show といったサブメニューが、ここに並びます。
この3つが分かれているおかげで、右クリックする場所ごとに出るメニューが変わります。列ヘッダーで開けば列の操作。行で開けばレコードの操作。同じ右クリックでも、狙った場所に応じて違う道具箱が開きます。普段は意識せず使い分けていますが、裏では menu 列がこの切り替えを担っています。
table:global と 特定テーブル
table 列は、その項目がどのテーブルの一覧で出るかを決めます。実測すると、はっきりした偏りがありました。
global … 78件。どのテーブルの一覧でも共通して出る
特定テーブル … 8件。そのテーブルの一覧でだけ出る
内訳はこうでした。特定テーブルの8件のうち、最多は wf_history の3件です。残りは sys_flow_context・sys_hub_flow・sys_atf_test など5テーブルに、各1件ずつ付いていました。wf_history(ワークフロー履歴)には「Workflow Debug」というサブメニューが、その一覧だけに足されています。ほかは Flow Designer やテスト関連の、専用テーブルばかりです。
ここが便利なところです。ほとんどの項目は global で全テーブルに効かせます。そのうえで、特別な操作が要るテーブルにだけ専用項目を足せます。Flow Designer の一覧に「Copy Flow URL to Clipboard」が出るのも、この仕組みでした。共通のメニューを土台にして、テーブルごとの追加を上乗せする。global と特定テーブルの二層構造が、無駄なくメニューを組み立てています。自作でも、まず global にするか特定テーブルに絞るかを最初に決めます。
order と parent:並び順とサブメニューの入れ子
メニューの並びは order 列で決まります。数値が小さいほど上に来る、素直なルールです。既定値は1000で、標準項目には10・20・30と小刻みに番号が振られていました。間に自作項目を割り込ませたいなら、たとえば15を指定します。すると10と20の間に入ります。番号に余白があるのは、後から差し込む余地を残すためです。
もう1つ大事なのが parent 列です。これは同じ sys_ui_context_menu 自身への参照で、「どのサブメニューの子か」を指します。実測では、86件のうち40件が parent を持っていました。半分近くが、どこかのサブメニューの中に入れ子で収まっている計算です。type=menu の親は、Configure のほかに Export や Data Management もありました。どれも列ヘッダーの整理棚として働きます。
代表例が、列ヘッダーの「Configure」サブメニューです。type=menu の親「Configure」の下を開いてみます。List Layout・List Calculations・List Control は Action。そこに区切り線(Separator)が挟まります。さらに Business Rules・Client Scripts・UI Policies といった Dynamic actions がぶら下がっていました。親が1つ、子が十数個。Menu 型が箱になり、その中に Action や Dynamic を詰める。この入れ子で、深い階層のメニューが表現されます。見慣れたあの多段メニューは、parent のリンクをたどって組み立てられていました。
condition:出す・出さないを決める
condition 列は、その項目を表示するかどうかの条件式です。空なら常に表示、式があればそれが真のときだけ表示されます。実測したサンプルを並べると、条件の使い方の幅が見えてきます。
List Layout … gs.hasRightsTo('ui/configure.personalize_list/write', null)(個人設定の書込権限がある人だけ)
Delete All with preview... … gs.hasRole('admin')(管理者だけ、かつ関連リストでないなどの複数条件)
Show Matching … ListProperties.hasFilter() || ListProperties.hasSearch()(絞り込み中のときだけ)
Copy URL to Clipboard … !RP.isPortal()(ポータル画面でないとき)
ここから読み取れるのは、出し分けの軸が複数あることです。ロールや権限で分ける(hasRole / hasRightsTo)。いまのリストの状態で分ける(ListProperties)。画面環境で分ける(RP.isPortal)。管理者にしか見えない項目や、フィルタ中だけ現れる項目。同じ86件の定義でも、見る人と状況によって実際のメニューは変わります。だから権限の弱いユーザーの画面には、危険な操作がそもそも出てきません。これは安全の作り込みでもあります。逆にいえば「あの人には出るのに自分には出ない」という現象も、多くはこの condition で説明できます。条件が空なら、その項目は誰の画面にも必ず出る仕組みです。逆に1行スクリプトを入れるだけで、見せる相手を細かく選べます。
action_script と dynamic:クリックで動くもの、開くたび作るもの
最後に、項目が実際に何をするのかを見ます。ここは type によって2つの道に分かれます。
Action 型は、action_script というクライアント側スクリプトを持ちます。実測で「Copy sys_id」の中身を開くと、選んだ行の g_sysId を copyToClipboard() に渡すだけの短いスクリプトでした。スクリプトからは g_sysId のほか、g_list(リスト本体)や g_fieldName(対象列)といった変数が使えます。押した瞬間に、その場の情報を受け取って動く。これが Action の基本形です。g_sysId は、右クリックした行のレコードを指します。選んだ行ごとに、違う対象へ同じ処理が働きます。開発中に sys_id をさっとコピーできるのも、この1件の定義のおかげでした。
一方、Dynamic actions 型は dynamic_actions_script というサーバー側スクリプトを持ちます。開くたびに、項目そのものを生成する仕組みです。g_contextMenu.addAction() を呼び、id・ラベル・スクリプト・order を渡して項目を足します。Configure の中の「Business Rules」などは、その一覧のテーブルに紐づく設定を動的に並べたものです。固定の項目では表せない「対象しだいで変わる中身」を、開いた瞬間に組み立てられます。

表に代表サンプルをまとめました。同じメニューの中で、4種類の部品が同居しています。動くだけの Action。区切りの Separator。箱になる Menu。開くたびに変わる Dynamic。1つのリストの右クリックが、これだけ性格の違う部品でできています。そう分かると、メニューの見え方が少し変わってきます。
onShow script:表示直前の最終調整
定義テーブルには、もう1つ onShow script という列もありました。run onShow script にチェックを入れると、メニューを表示する直前にこのスクリプトが走ります。すでに並んだ項目を、その場で書き換えたり隠したりできる仕組みです。condition が「出すか出さないか」の判定なら、onShow は表示直前の最終調整にあたります。OOTB で使う場面は限られますが、細かい制御が要るときの逃げ道として用意されています。
自分でメニューを足すときの勘所
仕組みが分かると、自作の勘所も見えてきます。「特定テーブルの行を右クリックしたら独自の操作を出したい」としましょう。menu は list_row、table はそのテーブル、type は action。order は既存の隙間の数値にします。必要に応じて condition で表示を絞る。action_script に g_sysId を使った処理を書けば、その1行への操作が1つ増えます。
逆に、既存の Configure のような箱に足したいなら parent を使います。親のサブメニューを指定して子として登録すれば、階層の中にきれいに収まります。global にするか特定テーブルにするか。常に出すか condition で絞るか。この記事で見た列の意味を1つずつ選ぶだけです。右クリックメニューは、思いのほか素直にカスタマイズできます。標準の86件が、そのままお手本になってくれます。
触る前に知っておきたい注意点
便利な反面、気をつけたい点もあります。まず、global の項目はすべてのテーブルの一覧に効きます。軽い気持ちで global に足すと、想定しない画面にも同じ項目が現れてしまう。特定のテーブルだけで使いたいなら、table を指定して範囲を絞りましょう。
次に、標準で入っている86件は、原則そのままが無難です。OOTB のレコードを書き換えると、アップグレードで上書きされたり、スキップ扱いになったりします。すると挙動が読みにくくなります。何かを足すときは、既存を編集せず、新しいレコードを1件追加する。この作法だけで、後々のトラブルはぐっと減ります。最後に、condition へ重い処理を書くのは禁物です。メニューを開くたびに評価され、表示が遅くなります。条件はできるだけ軽く保つ、という配慮も効いてきます。
その他、実機で確認した記録
用語
コンテキストメニュー … 右クリックで開く、状況に応じたメニュー。定義は sys_ui_context_menu
type … 項目の種類。Action / Menu / Separator / Label / Dynamic actions
menu … 右クリックの位置。List title / List header / List row の3つ
Dynamic actions … 開くたびにスクリプトで項目を生成する型
parent … サブメニューへの入れ子を表す、自テーブルへの参照
condition … その項目を表示する条件式(空なら常に表示)
調べるときの入口URL(先頭に自分のインスタンスを付ける)
/sys_ui_context_menu_list.do(定義の一覧)
/sys_ui_context_menu_list.do?sysparm_query=ORDERBYtype(type 順に並べる)
/sys_ui_context_menu_list.do?sysparm_query=menu=list_row(行の右クリック分だけ)
/sys_ui_context_menu_list.do?sysparm_query=table!=global(特定テーブル専用の項目)
実測の要点(再掲)
総件数86件、すべて active=true
type: Action 44 / Dynamic 25 / Menu 9 / Separator 8 / Label 0
menu 位置: List header 58 / List row 17 / List title 11
table: global 78 / 特定テーブル 8(wf_history が3件ほか)
parent 保持は40件(半数近くがサブメニューの子)
関連記事
ServiceNow 画面・フォーム完全ガイド:どこを直せば見た目が変わるのか — 右クリックメニュー以外の画面要素(フォームや一覧)をどこで直すかをまとめた記事です
検証範囲とおことわり
件数・type・menu・table・parent は PDI(Zurich / OOTB)の REST 実測です。
実際に一覧で右クリックしてメニューが描画される様子(実クリック)は今回の範囲外で、定義テーブルの構造の解説に留めています。
フォーム上の右クリックは OOTB の menu 選択肢に無く、この記事はリストの右クリックメニューを対象にしています。
action_script / dynamic_actions_script は代表例のみ確認しました。全項目の挙動は検証していません。
本番環境では、プラグインやカスタマイズで定義の件数・内容が変わります。
まとめ
右クリックメニューの正体は、sys_ui_context_menu という1枚のテーブルでした。PDI の初期状態では86件、すべて有効。その1件ずつが、type・menu・table・order・condition の組み合わせで「いつ・どこで・どう出るか」を表します。
読み解きの軸は5つです。項目の性格は type。右クリックの場所は menu。効かせる範囲は table。並びと入れ子は order と parent。出し分けは condition。この5列さえ押さえれば、標準メニューがなぜそう並ぶのかが読めます。自分で1項目を足すときの設計図にもなります。普段なにげなく開く右クリックの裏に、これだけ整理された定義がある。そう知っておくと、リストまわりのカスタマイズがぐっと近く感じられます。