02. 構造

タスクをツリーに組み、依存関係を正しく張る。TaskJuggler で最初につまずくのは
たいてい依存の参照記法なので、ここを固めておく。

生成されたレポート

ファイル 内容
structure.html タスクツリーとガントチャート
workload.html リソース別の負荷

実行結果

要件定義    2026-08-03 → 08-12  Effort 8.0   ← 3.0 + 5.0 の集計
  ヒアリング  2026-08-03 → 08-05  Effort 3.0
  仕様書作成  2026-08-06 → 08-12  Effort 5.0
開発        2026-08-13 → 08-26  Effort 18.0
  API 実装   2026-08-13 → 08-26  Effort 10.0
  UI 実装    2026-08-13 → 08-24  Effort 8.0
テスト       2026-08-31 → 09-04  Effort 5.0
リリース     2026-09-04           ← milestone

コンテナ「要件定義」は自分で工数を持たず、期間は子の範囲、工数は子の合計になる。
「開発」が 08-13 始まりなのは、depends spec が「要件定義の配下すべての完了」を
待つため。

ソース

structure.tjp
/*
 * 02: タスク階層 / 依存関係の参照記法 / マイルストーン
 *
 * 実行: bundle exec tj3 -o 02-structure/out 02-structure/structure.tjp
 */

project webapp "Web アプリ開発" 2026-08-03 +3m {
  timezone "Asia/Tokyo"
  timeformat "%Y-%m-%d"
  now 2026-07-29
}

resource alice "Alice"
resource bob   "Bob"

/*
 * task を入れ子にすると「コンテナタスク」になる。
 * コンテナ自身は effort を持たず、子タスクの範囲がそのまま期間になる。
 */
task spec "要件定義" {
  task interview "ヒアリング" {
    effort 3d
    allocate alice
  }
  task doc "仕様書作成" {
    // ! = 1つ上の階層 (= 親) を起点にする。つまり spec.interview のこと
    depends !interview
    effort 5d
    allocate alice
  }
}

task dev "開発" {
  // 起点なしの ID はルートからの絶対パス。
  // コンテナに依存すると「その配下が全部終わってから」の意味になる
  depends spec

  task api "API 実装" {
    effort 10d
    allocate bob
  }
  task ui "UI 実装" {
    // !! = 2つ上の階層 (= ルート) を起点に spec.doc を指す。
    // 絶対パスで spec.doc と書いても同じ
    depends !!spec.doc
    effort 8d
    allocate alice
  }
}

task qa "テスト" {
  /*
   * gapduration = 暦時間で間隔を空ける (休日も数える)
   * gaplength   = 稼働時間で間隔を空ける (休日は数えない)
   *
   * 依存元の完了が 2026-08-26 18:00 のときの実測差:
   *   gapduration 5d -> テスト開始 2026-09-01 (48h*... 暦で5日進み、週末を消費)
   *   gaplength   5d -> テスト開始 2026-09-03 (稼働5日ぶん進むので週末のぶん後ろへ)
   */
  depends dev { gapduration 2d }
  effort 5d
  allocate bob
}

/*
 * milestone は「期間ゼロの時点」。task の属性として宣言する。
 * effort / duration とは併用できない。
 */
task release "リリース" {
  milestone
  depends !qa
}

// ---- レポート ----

taskreport structure "structure" {
  formats html
  headline "タスク階層とスケジュール"
  columns name, start, end, effort, duration, chart
}

// リソース視点。誰がいつ何をやるか
resourcereport workload "workload" {
  formats html
  headline "リソース別の負荷"
  columns name, effort, chart
  // リソース配下に担当タスクをぶら下げて表示する
  loadunit days
}

学ぶ内容

依存の参照記法

記法 意味
!interview ! 1つで親を起点。つまり兄弟タスクを指す
!!spec.doc !! で2階層上を起点にパス解決
spec 起点記号なしはルートからの絶対パス

コンテナを depends に指定すると「その配下が全部終わってから」の意味になる。

gapduration と gaplength

依存元の完了 2026-08-26 18:00 を起点に、同じ 5d でも結果が変わる (実測)。

指定 テスト開始日 理由
gapduration 5d 2026-09-01 暦時間。土日も消費して進む
gaplength 5d 2026-09-03 稼働時間。土日を数えないので後ろにずれる

01 で見た duration と length の対比が、依存の間隔にもそのまま出てくる。

ハマりどころ

  1. ! の数は「何階層上を起点にするか」であって「何個上の兄弟か」ではない。
    ここを取り違えると依存が意図しないタスクに張られる
  2. コンテナタスクに effort は書けない。期間も工数も子から決まる
  3. 依存先のタスクは定義済みでなくてもよい (前方参照できる) が、
    ID を間違えるとエラーになる。パスは常にツリー構造を意識して書く
  4. milestone は task の属性。effort / duration とは併用できない

得られるもの

実プロジェクトの WBS をそのまま tjp のツリーに落とせるようになる。
依存の参照記法は 08 の論理式フィルタでも同じ考え方で使うので、
ここで身につけておくと後半が読みやすい。