ServiceNowにおいて、レコードの自動採番を行うための仕組みであるauto-numbering(自動採番)、もしくはNumber Maintenance(番号メンテナンス)機能について解説します。
Auto-numbering(自動採番)機能の基本
概要
Auto-numbering(自動採番)機能を使用すると、レコードに「接頭辞 + 0埋め連番」の形式で番号を自動的に付与できます。例えば、Incident(インシデント)テーブルには「INC」という接頭辞と7桁の0埋め連番が設定されています。
自動採番の設定はServiceNow上の各テーブル単位で行われます。例えば、Request(要求)テーブルであれば、依頼や要求の種別にかかわらず、共通の接頭辞と連番で番号が設定されます。
また、システムによっては「番号の上2桁を西暦にする」といった有意コードが採用されることがありますが、ServiceNowでは、接頭辞による最低限の意味付けはあるものの、それ以上の意味は持たない無意コードが採用されています。
構成要素
Auto-numbering(自動採番)は、次の要素で構成されています。
- Number(番号)テーブル … 各種テーブルの採番ルール(接頭辞、桁数、最初の番号)を管理
- Number Counter(数カウンタ)テーブル … 各テーブルの自動採番における連番部分の現在の値を管理
- 採番ロジック … Numberテーブルの定義とCounterテーブルのカウンターの値を用いて自動採番を行うロジック
Incident(インシデント)テーブルを例に、番号処理ロジックの動作を図示すると、次のようになります。
Auto-numbering(自動採番)の設定方法
ServiceNowでは、Incident(インシデント)やRequest(要求)などの主にトランザクションデータを格納する多くのテーブルには標準で自動採番が設定されています。しかし、マスタデータを格納するテーブルや新規に作成したカスタムテーブルには、標準で自動採番が設定されていません。ここでは、既存テーブルおよび新規テーブルに自動採番を設定する方法を説明します。
既存テーブルへの自動採番設定
既存のテーブルに自動採番を設定するには、以下の手順を実行します。
自動採番の設定
- メニュー > System Definition > Number Maintenanceを開き、”New”ボタンをクリックして新しい設定を作成します
- 対象テーブル、接頭辞、連番の最初の値、連番の桁数を設定します
- 接頭辞は空白にして、接頭辞無しの連番で設定することも可能です
- 連番の最初の値の初期値は1,000です。これは、連番が小さい場合に0が多く連続することを避け、可読性を高めるためだと思われます(例:7桁の場合、初期値が1だと”0000001″のように0が続く)
番号フィールドの作成(自動)
Number(番号)の設定が正常に送信されると、次のメッセージが表示され、対象テーブルにNumber[u_number]フィールドが作成されます。
Default Valueに設定されているスクリプトが、採番ロジックを呼び出す設定です。
動作の確認
Numberフィールドをフォームに表示し、メニュー > Organization > Companiesを開いて”New”をクリックして新しいレコードを作成します。これにより、Numberフィールドに採番されたことを確認できます。
新規テーブル作成時の自動採番設定
新規テーブルの場合は、テーブル作成画面のControlsタブでAuto-numberを設定します。これにより、テーブル作成と同時に自動採番の設定が行われます。
フィールド名のカスタマイズ
前述の設定方法では、自動でNumber[u_number]フィールドが作成されます。フィールド名を自分で定義したい場合は、Number(番号)テーブルの設定を行う前に、採番ロジックを呼び出す設定をしたフィールドを作成しておきます。
javascript:global.getNextObjNumberPadded();
(補足1) global.getNextObjNumberPadded();は、この記事で紹介している過去の遺物であるGlobal Business Ruleの”getNextObjNumberPadded”内で定義されています。
(補足2) コードを書かずに次のように設定することもできます。Task(タスク)テーブルのNumber[number]フィールドはこのような設定になっています。
必要に応じて:設定後に連番の値を直接変更する
自動採番の設定後に現在の番号を変更したい場合は、Number Counter(数カウンタ)テーブルを直接変更します。このテーブルへのアクセスは、Number(番号)レコードのフォーム画面下部にあるリンクから行えます。
必要に応じて:レコード作成画面を開いた時点ではなく送信時に採番を行う(欠番防止)
標準ではレコード作成画面を開いた時点で採番が行われますが、レコードが保存されなかった場合は欠番が生じます。
System Properties(システムプロパティ)で”glide.itil.assign.number.on.insert”を”true”に設定することで、送信時にのみ採番されるようにすることが可能です。システムプロパティの設定方法は下記の記事を参照ください。
また、このプロパティを設定する際には、以下の点に注意が必要です。
- フィールドの編集制限
標準の自動フィールドは、編集可能な設定になっていることが多く、フォームを開いた際にフィールドが空白だと、ユーザーが独自に番号を入力してしまう可能性が高まります。そのため、この設定を行う場合は、フィールドを読み取り専用に設定することも検討する必要があります - 全テーブルへの影響
標準・非標準問わず全ての自動採番フィールドでフォームを開いたときではなく送信時に採番されるようになります。既に業務で利用されている他の機能がある場合は、プロパティ設定前に影響を確認しておきましょう
Tips
連番の値が設定した桁数を超えた場合は桁数を超えてカウントされる
連番の値が設定した桁数を超えると、カウントはそのまま続行され、リセットは行われません。たとえば、桁数を3桁に設定した場合、999の次は1000とカウントされ、4桁となります。
ただし、番号の桁数が揃っていないと次のような問題が発生する可能性があるため、レコード数を事前に見積もり適切な桁数を設定しておくことを推奨します。
- ソート時に期待しない順序でレコードが並ぶ可能性がある
- 番号を格納するフィールドや外部システムとの連携で桁数制限に引っかかる可能性がある
標準のNumberフィールドは重複を許容
標準のNumberフィールドには一意性制約(ユニーク制約)が無く、重複が許容されています。これについてはCommunityでも疑問が上がっていますが、Documentation:Enforcing unique numberingによると、Numberフィールドに一意性制約(ユニーク制約)を設定した場合、予期せぬエラーが発生する可能性があるため、代わりにBusiness Ruleの設定が推奨されています。
個人的にはNumberフィールドの一意性制約については、次の対応方針が良いと考えます。
- 重複が発生しても深刻な影響がない場合は、特に対応を行わない
- 重複を確実に防ぎたく、かつ万が一重複した場合に画面上にエラーが表示されても業務影響が少ない場合は、NumberフィールドにUnique設定を適用する
- 重複を確実に防ぎたく、かつ万が一重複した場合に画面上にエラーが表示された場合に業務影響がある場合は、Documentationで紹介されているBusiness Ruleを設定する
資源移送時にNumber Counter(番号カウンタ)は移送されないため注意
Number(番号)テーブルは採番の設定を管理するため、開発資源として扱われ、Update Set(更新セット)などを使って移送することが可能です。しかし、Number Counter(番号カウンタ)テーブルは、連番の現在の値を格納するデータテーブルであるため、開発資源としては扱われず、移送されません。
多くの場合は特に問題になりませんが、マスタ系のテーブルやKnowledge(ナレッジ)テーブルに開発環境でデータを作成し、本番環境で利用するためにXML移送するような場合は、データ移行後に本番環境でNumber Counterの値を適切に設定しておかないと、本番環境で番号の重複が発生する可能性があります。
上述した通り、一意性制約がないため、気づきにくい点も厄介です。
連番の最大桁数は15桁
標準では、Number(番号)テーブルのDigit(桁数)フィールドの値、つまり連番の桁数は、15桁以下に制御されています。この制御はBusiness Rule “Validate Number”によって行われています。
なお、Prefix(プレフィックス)項目は、項目の最大桁数通りの40文字まで設定可能でした。
どちらの制約も、実務上はまず引っかかることは無いと思います。
接頭辞 + 0埋め連番以外の採番ルールについて
推奨はしませんが、「接頭辞 + 0埋め連番」以外のルールを適用することも可能です。設計と開発方針について以下に示します:
標準テーブルの採番
標準テーブルの場合、拡張テーブルも含め整合性が取れるように複雑な採番ロジックが設定されており、さらにその一部はブラックボックスなので、手を入れることは避けたほうがよいでしょう。代わりに、以下の方法を検討できます。
- 標準の採番ロジックは変更せず、採番後に番号を上書きする処理(Business Ruleなど)を追加する
- Number Counter(数カウンタ)テーブルを条件に応じて変更する処理を追加する
例:上位2桁を西暦にしたい場合、毎年の初めにカウンタの上位2桁を設定
カスタムテーブルの採番
標準のテーブルとは無関係のカスタムテーブルであれば、採番ロジックを自作しても特に問題はないです。この場合、Global Business Rule “getNextObjNumberPadded”やScript Include “NumberManager”を参考にしつつ、必要な個所を変更するのがよいでしょう。
以上です。
コメント