ServiceNow開発者の皆さん、GlideRecord を使ってテーブルから複数レコードを取得する際、配列(Array)に値を追加したはずなのに「出力してみると、すべて最後のレコードの値に書き換わっている」という謎のバグに遭遇したことはありませんか? これはフィールド値の取得方法の仕様による、非常によくある落とし穴です。ここでは、GlideRecordからフィールド値を安全かつ確実に取得する方法をコード例とともに解説します。
なぜ直接フィールドにアクセスすると危険なのか?
gr.short_descriptionのようにフィールドへ直接アクセス(ドット歩行)した場合、システムが返すのは単なるデータ値(String)ではなくGlideElementというオブジェクト(参照) になりますwhile(gr.next())などのループ内で、このオブジェクトをそのまま配列にpush()してしまうと、配列内のすべての要素が同じメモリポインタを参照し続け、配列の中身がすべて最後に読み込んだレコードの値になってしまうという現象が発生します
推奨される取得手段(ベストプラクティス)
値を取得する場合は、そのままドット歩行するのではなく、目的に応じて専用のメソッドを使用するのがSerivceNowの標準的なベストプラクティスです。
getValue('フィールド名')の利用- オブジェクト参照ではなく、データベースが保持している実際のデータ値(プリミティブな文字列)を安全に返します
getDisplayValue('フィールド名')の利用- ユーザー(User)やグループ(Group)などの参照フィールドの表示名や、選択肢(Choice)のラベルなど、人間の目に見えるテキストの形式で値を取得したい場合に使用します
実装コード例(アンチパターンと推奨策)
❌ アンチパターン(配列内の値がすべて同じになってしまう悪い例)
var arr = [];
var gr = new GlideRecord("incident");
gr.query();
while (gr.next()) {
// 警告:これは単なる文字列ではなく、GlideElement オブジェクトを配列に入れています
// その結果、ループ終了時には arr の全要素が最後のインシデント番号に上書きされます
arr.push(gr.number);
}✅ ベストプラクティス(getValue() を使った安全な取得例)
var arr = [];
var gr = new GlideRecord("incident");
gr.query();
while (gr.next()) {
// 安全:getValue() を使うことで、純粋な文字列(Primitive String)として取得・格納します
arr.push(gr.getValue("number"));
// ※どうしても直接アクセスを使いたい場合は、必ず .toString() で文字列へキャストしてください
// 例: arr.push(gr.number.toString());
}
まとめ
- GlideRecordのフィールドに直接アクセス(
gr.field_name)した値は、普通のテキストではなくオブジェクト参照であることに注意しましょう - 配列への格納時や他システムへの連携時は、予期せぬ値の上書きを防ぐために必ず
getValue("フィールド名")を使う習慣をつけましょう - スクリプトから通知や画面に表示するテキストを取得したい場合は、
getDisplayValue("フィールド名")が非常に便利です
一言まとめ: 👉 GlideRecordからの値の取得は、エラーを防ぐために常に getValue() を使おう!