メインコンテンツへスキップ

作業時間明細(task_time_worked)は継承でなく参照


    Incident や Change のフォームを下までスクロールすると、「Time Worked(作業時間)」という関連リストや、ストップウォッチのようなタイマーを見かけます。あの「このチケットに何時間かけたか」を1件ずつ記録しているのが、task_time_worked というテーブルです。

    この記事は、ITSM の各プロセス画面には慣れてきて、その裏でどう作業時間が貯まっているのかを確認したい管理者・開発者を想定しています。PDI(Zurich / OOTB)で task_time_worked を実際に開き、実機の全8件のデータとともに次の3点を確認します。1点目は、task_time_worked が task を「継承」した子テーブルではなく、task を「参照」してぶら下がる明細テーブルだという点です。2点目は、1つのタスクに対して「誰が・何時間」を複数行で積み上げる構造である点です。3点目は、time_worked が duration(HH:MM:SS)型で持たれる点です。

    この記事で分かること

    • task_time_worked が、task 系レコードに「誰が・何時間」作業したかを1件ずつ積む作業時間明細テーブルであること

    • これは テーブル継承の子ではなく、task フィールドで task を参照する 1対多の明細であること(継承との違い)

    • 主要フィールド task / user / time_worked / time_in_seconds / comments の役割(PDI 実測)

    • time_worked が glide_duration 型で「HH:MM:SS」、その秒数を time_in_seconds が別に持つこと

    • PDI 実機の 全8件が、3つの incident に「誰がどれだけ」で積まれている実際の分布(合計38時間)

    この記事の内容は ServiceNow の PDI(Personal Developer Instance)Zurich(ズーリッヒ)リリースの OOTB(初期設定)で確認した個人メモです。本番環境やカスタマイズ済み環境では、フィールド構成・レコード件数・分布が異なります。


    task_time_worked とは

    task_time_worked(ラベルは Time Worked)は、「あるタスクに対して、誰が・どれだけの時間、作業したか」を1件ずつ記録するテーブルです。下の画面は、PDI(Zurich / OOTB)の task_time_worked を Task でグループ化したものです。INC0000009・INC0000012・INC0000013 という incident ごとに、作業時間のレコードがぶら下がっているのが分かります。


    画像

    ポイントは、task_time_worked のレコードには番号(INCxxxxx のような採番)が無いことです。実機でテーブル定義(sys_db_object)を見ると number_ref は空で、これらの明細は採番されず、識別は sys_id だけで行われます。あくまで「親タスクにぶら下がる明細」だからです。


    画像

    つまり task_time_worked は、タスク1件に対する作業時間のタイムシート明細にあたります。


    「継承」ではなく「参照」でぶら下がる

    ここが一番の勘所です。「task 系のテーブル」と聞くと、Incident や Problem のように task を継承(テーブル拡張)した子テーブルをイメージする人が多いはずです。しかし task_time_worked は継承の子ではありません。

    実機で sys_db_object を確認すると、task_time_worked の super_class(継承元)は空でした。task を継承しておらず、代わりに task という参照(reference)フィールドで task テーブルを指しているだけです。これは「1つのタスク : 複数の作業時間明細」という 1対多のリレーション(外部キー)であって、テーブル継承とはまったく別の繋がり方です。


    画像
    • 継承(incident など) … task の構造を引き継いで「task の一種」になる。詳しくは「ServiceNow の task テーブルを実機で読み解く」で検証しています。incident / problem / change が task を継承する仕組みを扱った記事です。

    • 参照(task_time_worked) … task の構造は引き継がず、task フィールドで特定の1件を指して明細として付随する。

    この違いを押さえると、フォーム上の「Time Worked 関連リスト」が、なぜ別テーブルのレコードとして表示されるのかが腑に落ちます。


    主要フィールド:task / user / time_worked

    task_time_worked が自分自身に持つフィールドはシンプルです。PDI 実測の主要フィールドは次のとおりでした。


    画像


    画像

    中心になるのは task(どのタスクの作業か)・user(誰が作業したか)・time_worked(どれだけ作業したか)の3つです。

    • task … 作業対象のタスクへの参照(reference → task)。incident でも change でも、task 系なら何でも指せます。

    • user … 作業者(reference → sys_user)。「誰が」を表します。

    • time_worked … 所要時間。glide_duration 型で持たれます。

    • time_in_seconds … time_worked を秒数(整数)で持つフィールド。集計・レポート用です。

    • comments … 補足コメント(最大1000文字)。

    なお、当初「category(区分)」フィールドがあると想定していました。しかし OOTB Zurich の task_time_worked に category フィールドは存在しませんでした(dict 実測で確認)。事実は実機優先で記録しています。

    下は task_time_worked のレコードを1件フォームで開いたものです。Task=INC0000012、User=Beth Anglin、Time worked=10 Hours が入っているのが分かります。


    画像

    time_worked は duration、秒は time_in_seconds が持つ

    時間の持ち方にも特徴があります。time_worked は glide_duration 型で、内部的には「1970-01-01 を起点とした経過時間」として保持されます。たとえば6時間の作業は、値としては 1970-01-01 06:00:00、表示は 6 Hours(= 06:00:00)になります。

    duration のままだと合計や平均が取りにくいので、ServiceNow は同じ時間を秒数で持つ time_in_seconds(整数)を併せて用意しています。6時間なら 21,600 という具合です。レポートやスクリプトで集計するときは、この time_in_seconds を合計するのが扱いやすくなっています。

    区分    フィールド       型              6時間の例
    --------------------------------------------------
    表示用  time_worked      glide_duration  06:00:00(6 Hours)
    集計用  time_in_seconds  integer         21,600

    ちなみに、task テーブル自身にも time_worked という同名フィールドがあります。そちらは type=timer(実行中のストップウォッチ)で、明細テーブルの time_worked(duration)とは別物です。実機では INC0000012 が17時間ぶんの明細を持っていました。一方、incident 側の time_worked(Timer)フィールドは空でした。つまり明細の合計が自動でタスク本体のタイマー欄に書き戻されるわけではありません。誰が何時間の履歴の正本は、あくまで task_time_worked 側にあると読み取れます(タイマー UI の内部挙動自体は検証範囲外です)。


    フォームのタイマーから明細が1件ずつ積まれる

    実運用での流れはシンプルです。担当者が作業し、フォーム下部の Time Worked タイマーを停止するか、関連リストから手動で1件追加すると、task_time_worked のレコードが1件作られます。これが関連リストに積み上がっていきます。


    画像

    実際に incident(INC0000012)のフォームを開くと、Time Worked 関連リストに複数の作業時間明細が並びます。1つの incident に対して、複数の作業ログが時系列で積まれている様子が確認できます。


    画像

    このように、1タスク : N 明細で積んでいくのが task_time_worked の基本動作です。


    実機の8件はどう積まれていたか

    PDI(Zurich / OOTB)の task_time_worked は、全部で 8件でした。その内訳は、3つの incident にきれいに分かれています。


    画像


    画像
    • INC0000009 … Joe Employee が 6時間 + 5時間 = 計11時間(2件)

    • INC0000012 … Beth Anglin が 10時間 + 5時間 + 2時間 = 計17時間(3件)

    • INC0000013 … Sam Sorokin が 2時間 + 4時間 + 4時間 = 計10時間(3件)

    • 合計 8件・38時間(136,800秒)

    このデモデータでは、各 incident の作業時間がすべて単一の作業者に紐づいていました(一般には、1つのタスクに複数ユーザーが工数を積めます)。「誰が・どのタスクに・何時間」という3点が、明細1行ずつに正確に残っているのが分かります。これらの incident そのものの構造は「Incident テーブルの構造を実機で読み解く」で検証しています。あわせて読むと、「チケット本体」と「その作業時間明細」の関係が立体的に見えてきます。


    実機で確認するときに見るべきURL

    最後に、今回見た画面を自分のインスタンスで開くためのURLをまとめます(<YourInstance> は置き換えてください)。

    # task_time_worked を Task でグループ化(タスク別に明細が積まれる)
    https://<YourInstance>/task_time_worked_list.do?sysparm_query=GROUPBYtask
    
    # task_time_worked を User でグループ化(作業者別)
    https://<YourInstance>/task_time_worked_list.do?sysparm_query=GROUPBYuser
    
    # task_time_worked のフィールド定義
    https://<YourInstance>/sys_dictionary_list.do?sysparm_query=name=task_time_worked^elementISNOTEMPTY

    まとめ

    • task_time_worked(Time Worked)は、task 系レコードに「誰が・何時間」作業したかを1件ずつ積む作業時間明細テーブル。番号は付かず(採番なし)、sys_id で識別。

    • これは テーブル継承の子ではなく、task 参照フィールドでぶら下がる 1対多の明細。継承(incident 等)とは繋がり方が違う。

    • 主役フィールドは task(どのタスク)/ user(誰が)/ time_worked(どれだけ)。time_worked は glide_duration(HH:MM:SS)、集計用の秒数を time_in_seconds が別に持つ。OOTB に category フィールドは無い。

    • フォームの Time Worked 関連リスト/タイマーから1件ずつ生成され、タスクに積み上がる。タスク本体の time_worked(Timer)とは別物。

    • PDI 実機は 全8件、3つの incident に 38時間ぶんが「誰が・何時間」で記録されていた。

    作業時間の正体が「タスクにぶら下がる明細テーブル」だと分かると、SLA やレポートで出てくる工数の数字が、どのレコードから来ているのかを自分で辿れるようになります。まずは土台である「task テーブルの基底と継承」とあわせて読むのがおすすめです。

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ