Excelのピボットテーブルに「タイムライン(Timeline)スライサー」をVBAで自動作成し、End Date(終了日)で期間絞り込みしたい――この要件は、フィールド名の一致や日付型の扱いでつまずきがちです。この記事では、SlicerCaches.Add2 と xlTimeline を使った基本マクロから、失敗原因の切り分け、実務で安定して動かすための工夫までまとめます。
VBAでタイムラインスライサーを作ると何が便利か
タイムラインスライサーは、日付フィールドを「年・四半期・月・日」の単位で直感的に絞り込めるUIです。プロジェクト管理、案件進捗、作業ログ、勤怠、タスク管理など、End Date(終了日)で「今月締めのものだけ」「今週中に終わるものだけ」といった分析をしたいケースで特に効果を発揮します。
ただし、手作業でタイムラインを追加していると、
- ピボットを作り直すたびにタイムラインを貼り直す
- 複数シート・複数ピボットで同じタイムラインを作り直す
- 担当者が変わると作り方が統一されない
といった運用コストが積み上がります。そこでVBAで自動生成できるようにしておくと、更新作業が一気に楽になります。
今回の前提となるピボット構成
質問の状況を整理すると、ピボットテーブルは次のような構成です。
| 領域 | フィールド | 目的 |
|---|---|---|
| Rows(行) | Activity / Stage / Person | 業務・工程・担当者での集計 |
| Values(値) | Start Date / End Date | 開始日・終了日の表示(例:最小/最大) |
このうち、End DateでフィルターできるタイムラインをVBAで作りたい、というのがゴールです。
タイムラインがEnd Dateで作れないことがある理由
結論から言うと、タイムラインは「日付フィールド(ディメンション)」に対して作られます。一方で、ピボットのValuesに置いた日付は、しばしば集計値(データフィールド)として扱われます。このズレが、VBAでの自動作成を難しくします。
| 見た目 | ピボット内部の扱い | タイムライン作成の可否 |
|---|---|---|
| End DateがRows/Columns/Filtersにある | PivotField(元フィールド) | 作成できる可能性が高い |
| End DateがValuesにだけある(例:Max of End Date) | DataField(集計結果) | 環境によっては作成できないことがある |
さらに、次の2点が重なると失敗率が上がります。
- フィールド名(キャプション)の不一致:VBAの文字列がピボットの表示名と完全一致していない(スペース、全角半角、表記揺れ)
- End Dateが文字列:元データでは日付に見えるが、実体が文字列でタイムラインが日付と認識できない
成功条件を先に確認するチェックリスト
マクロを疑う前に、まずは「タイムラインを作れる状態になっているか」を確認します。ここが整っていないと、どんなに正しいVBAを書いても失敗します。
| チェック項目 | OKの目安 | 確認方法 |
|---|---|---|
| Excelのバージョン | タイムライン対応(目安:Excel 2013以降、Microsoft 365) | Excelの「アカウント」または「バージョン情報」で確認 |
| End Dateが日付として認識 | セルの値が日付シリアル(数値) | 元データでセルの表示形式だけでなく、=ISNUMBER(EndDate)で判定 |
| ピボットにEnd Dateフィールドが存在 | PivotFieldsにEnd Dateがある | ピボットフィールド一覧で確認(フィールド名/キャプション) |
| フィールド名の完全一致 | VBAで指定する文字列がキャプションと同じ | 後述の「フィールド名を列挙するマクロ」で確認 |
基本の解決策はSlicerCaches.Add2でxlTimelineを指定する
VBAでタイムラインを作る基本形はとてもシンプルです。ポイントは、対象ピボットテーブルに対して SlicerCaches.Add2 を使い、スライサー種別を xlTimeline にすることです。
Sub CreateTimeline()
Dim wbk As Workbook
Dim wsh As Worksheet
Dim pvt As PivotTable
Dim fld As String
Dim slc As SlicerCache
Dim sli As Slicer
Set wbk = ActiveWorkbook
Set wsh = ActiveSheet
Set pvt = wsh.PivotTables(1)
fld = "End Date" ' ピボットのフィールド名(表示名/キャプション)
Set slc = wbk.SlicerCaches.Add2(pvt, fld, , xlTimeline)
Set sli = slc.Slicers.Add(wsh, , fld, fld)
End Sub
このマクロが通る環境では、これだけでEnd Date用のタイムラインが作成されます。逆に言えば、ここで失敗する場合は「VBAが間違っている」よりも、フィールド名や日付型の前提が崩れているケースが大半です。
つまずきやすいポイントを深掘りする
フィールド名は完全一致しか許されない
fldに指定するのは、ピボットのフィールド名(キャプション)です。たとえば元データの列名が「EndDate」でも、ピボット側の表示が「End Date」なら、VBAも「End Date」で指定する必要があります。逆も同様です。
スペース1つの違い、全角半角、末尾の空白、あるいはピボットで自動付与された名前の違いがあるだけで、Add2は失敗します。
End Dateが文字列だとタイムラインは作れない
「見た目は日付なのに作れない」場合、元データのEnd Dateが文字列である可能性が高いです。Excelでは表示形式で日付っぽく見せられるため、ぱっと見では気づけません。
対策はシンプルで、元データ側で日付型に直すことが先決です。後半で具体策を紹介します。
Valuesに入っているだけの日付は対象外になることがある
質問でも触れられている通り、End Dateが「値(Values)」にあるだけだと、タイムライン対象として扱われない環境があります。これは、ValuesのEnd Dateが「Max of End Date」「Min of End Date」といった集計値になり、タイムラインが求める「日付フィールド」と噛み合わないためです。
この場合は、End Dateを一度Filters(フィルター)やRows/Columns側に置くと通りやすくなります。表示が不要なら、作成後に非表示(xlHidden)に戻しても運用できることが多いです。
実務向けは失敗しにくい安定版マクロにしておく
実際の運用では「ピボットが複数ある」「同じタイムラインを再実行しても重複させたくない」「配置場所を固定したい」「フィールドがFiltersに無いときだけ一時的に移動したい」といった要件が出ます。そこで、次のような“安定版”にしておくと安心です。
Option Explicit
Public Sub CreateTimeline_EndDate()
Dim wb As Workbook
Dim ws As Worksheet
Dim pvt As PivotTable
Set wb = ActiveWorkbook
Set ws = ActiveSheet
If ws.PivotTables.Count = 0 Then
MsgBox "このシートにピボットテーブルが見つかりません。", vbExclamation
Exit Sub
End If
Set pvt = ws.PivotTables(1)
' End Date のタイムラインを作成(配置起点は H2)
EnsureTimeline wb, ws, pvt, "End Date", "tl_EndDate", ws.Range("H2")
End Sub
Private Sub EnsureTimeline(ByVal wb As Workbook, ByVal ws As Worksheet, ByVal pvt As PivotTable, _
ByVal fieldCaption As String, ByVal cacheName As String, ByVal anchor As Range)
Dim sc As SlicerCache
Dim sl As Slicer
Dim pf As PivotField
Dim moved As Boolean
Dim originalOrientation As XlPivotFieldOrientation
Dim errMsg As String
' 1) 既に同名のSlicerCacheがあれば再利用(重複作成を防ぐ)
On Error Resume Next
Set sc = wb.SlicerCaches(cacheName)
On Error GoTo 0
' 2) 無ければ新規作成
If sc Is Nothing Then
' フィールド存在チェック
On Error Resume Next
Set pf = pvt.PivotFields(fieldCaption)
On Error GoTo 0
If pf Is Nothing Then
MsgBox "ピボットフィールド '" & fieldCaption & "' が見つかりません。" & vbCrLf & _
"ピボット側のフィールド名(キャプション)と完全一致する文字列を指定してください。", vbExclamation
Exit Sub
End If
' 環境依存の回避策:Filtersに一時的に移動してから作成
originalOrientation = pf.Orientation
If originalOrientation = xlHidden Or originalOrientation = xlDataField Then
moved = True
pf.Orientation = xlPageField
pf.Position = 1
End If
' タイムライン作成
On Error Resume Next
Set sc = wb.SlicerCaches.Add2(pvt, fieldCaption, cacheName, xlTimeline)
errMsg = Err.Description
Err.Clear
On Error GoTo 0
' 元に戻す(必要なら xlHidden にする)
If moved Then
pf.Orientation = originalOrientation
End If
If sc Is Nothing Then
MsgBox "タイムラインの作成に失敗しました。" & vbCrLf & _
"原因の候補:" & vbCrLf & _
"・End Date が日付として認識されていない(文字列)" & vbCrLf & _
"・フィールド名が一致していない" & vbCrLf & _
"・Excelのバージョンがタイムラインに非対応" & vbCrLf & _
"詳細:" & errMsg, vbExclamation
Exit Sub
End If
Else
' 既存キャッシュを別ピボットに接続したい場合(必要に応じて)
On Error Resume Next
sc.PivotTables.AddPivotTable pvt
On Error GoTo 0
End If
' 3) シート上のSlicer(タイムライン)を作成/再利用
Set sl = Nothing
Dim s As Slicer
For Each s In sc.Slicers
If s.Shape.Parent.Name = ws.Name Then
Set sl = s
Exit For
End If
Next s
If sl Is Nothing Then
Set sl = sc.Slicers.Add(ws, , cacheName, fieldCaption)
End If
' 4) 配置とサイズ調整
With sl.Shape
.Top = anchor.Top
.Left = anchor.Left
.Width = 360
.Height = 180
End With
End Sub
この“安定版”がやっていることを要約すると次の通りです。
- 同じタイムラインを何度実行しても重複作成しない(SlicerCacheを再利用)
- フィールドが見つからないときは、メッセージで原因を明確化
- 環境によって作成に失敗する場合に備えて、End Dateを一時的にFiltersへ移動してから作成
- 作成後のタイムラインをセル(anchor)基準で配置し、見た目を揃える
ValuesにあるだけのEnd Dateをタイムライン対象にする実務のコツ
「End Dateを値としても表示したい。でもEnd Dateで絞り込みたい」というケースはよくあります。ここで重要なのは、
- Valuesに表示するEnd Date(例:Max of End Date)は集計値
- タイムラインで絞り込むEnd Dateは元フィールド
と、役割が違う点です。
実務では次のように整理すると迷いません。
| 目的 | ピボット上の置き場所 | 補足 |
|---|---|---|
| End Dateで期間フィルターしたい | Filters(またはRows/Columns) | タイムライン作成のための元フィールドとして扱う |
| End Date(最終日など)を表として表示したい | Values | Max/Minなどで集計して見せる |
上の安定版マクロのように、一時的にFiltersへ移してタイムラインを作り、必要なら元の状態に戻す、という運用が現実的です。
フィールド名のズレをなくす方法
「End Dateのはずなのに見つからない」問題は、目視での確認に限界があります。VBAでピボットのフィールド名を列挙して、実際に何という名前で存在しているかを確認するのが確実です。
Sub ListPivotFields()
Dim pvt As PivotTable
Dim pf As PivotField
Set pvt = ActiveSheet.PivotTables(1)
Debug.Print "----- PivotFields -----"
For Each pf In pvt.PivotFields
On Error Resume Next
Debug.Print "Name=" & pf.Name & " / Caption=" & pf.Caption & " / SourceName=" & pf.SourceName & _
" / Orientation=" & pf.Orientation
On Error GoTo 0
Next pf
End Sub
イミディエイトウィンドウ(VBEでCtrl+G)に出力される情報を見て、VBAで指定すべき文字列を確定させましょう。特に、列名に余計なスペースが入っている、PowerQueryで列名が変わっている、などのケースではこの確認が効きます。
元データが文字列日付になっている場合の直し方
タイムラインは日付フィールドであることが必須です。元データが文字列だと、たとえ表示形式で日付に見えても、タイムラインは作れなかったり、作れても期待通りに絞り込めなかったりします。
よくある文字列パターン
| 例 | 問題点 | 直し方の方向性 |
|---|---|---|
| 2026/01/10(実体が文字列) | 日付に見えるが数値ではない | DATEVALUEで変換、または区切り位置で日付に変換 |
| 2026-01-10 | 環境によって文字列扱いになりやすい | PowerQueryで型を日付に、または日付シリアルへ変換 |
| 10 Jan 2026 | ロケール依存で変換失敗することがある | 年/月/日を分解してDATE関数で組み立て |
手早い方法
- データ範囲をテーブル化している場合は、列全体を日付形式にするだけで直らないことがあります(表示形式は型変換ではないため)。
- 確実なのは、別列に =DATEVALUE([@End Date]) を作り、値貼り付けで置き換える方法です。
- PowerQueryを使っているなら、列のデータ型を日付に設定してから読み込み直すのが最も安定します。
タイムラインをVBAで初期化して特定期間を表示する
「作るだけ」ではなく、たとえば直近30日や今月を初期表示にしたいことがあります。Excelのバージョン・環境によっては、作成したSlicerCacheの TimelineState を使って日付範囲を指定できます。
Sub SetTimelineRange()
Dim sc As SlicerCache
Set sc = ActiveWorkbook.SlicerCaches("tl_EndDate")
' 例:2026年1月1日~2026年1月31日に絞り込み
sc.TimelineState.SetFilterDateRange DateSerial(2026, 1, 1), DateSerial(2026, 1, 31)
End Sub
絞り込みを解除したい場合は、次のようにSlicerCache側のフィルターをクリアします。
Sub ClearTimelineFilter()
ActiveWorkbook.SlicerCaches("tl_EndDate").ClearManualFilter
End Sub
運用としては「ブックを開いたら今月に絞る」「更新ボタンで直近N日をセットする」など、定型操作の自動化に向いています。
同じタイムラインを複数のピボットに接続する
部署別・担当別でピボットが複数ある場合、End Dateのタイムラインを1つ作って、全部のピボットに効かせたいという要望が出ます。SlicerCacheは複数ピボットに接続できるので、次のように追加します。
Sub ConnectTimelineToAnotherPivot()
Dim sc As SlicerCache
Dim pvt2 As PivotTable
Set sc = ActiveWorkbook.SlicerCaches("tl_EndDate")
Set pvt2 = Worksheets("Sheet2").PivotTables(1)
sc.PivotTables.AddPivotTable pvt2
End Sub
注意点として、接続先のピボットも同じデータソース(同じPivotCache、または互換のあるデータモデル)である必要があります。ソースが違う場合は接続できません。
よくあるエラーと原因の切り分け
タイムライン作成で出やすい症状を、原因と対処に落とし込みます。
| 症状 | 主な原因 | 対処 |
|---|---|---|
| 実行時エラー 1004 が出る | フィールド名不一致、日付として認識されていない、タイムライン非対応 | フィールド列挙で名称確認、元データを日付型へ、Excelバージョン確認 |
| タイムラインは作れたが絞り込みが効かない | End Dateが文字列/空白混在、ピボット更新未実施 | データ型を統一し、PivotTable.RefreshTableで更新 |
| End DateがValuesにあると失敗する | 集計値(DataField)扱いで元フィールドとして認識されない | 一時的にFiltersへ置いてから作成し、必要なら非表示に戻す |
| 同じマクロを何度も実行するとタイムラインが増える | SlicerCacheの再利用をしていない | キャッシュ名を固定し、既存があれば再利用する |
実務でさらに安定させる小技
- ピボットテーブル名で指定する:PivotTables(1)ではなく、PivotTables(“PivotTable1”)のように名前指定にすると誤爆が減ります。
- 配置位置はセル基準にする:Range(“H2”)などを起点にすれば、行高さや列幅が変わっても整列しやすくなります。
- ピボット更新を挟む:元データを直した直後は、pvt.RefreshTableやPivotCache.Refreshを入れると反映漏れを防げます。
- 列名は最初に固める:End Dateのスペース有無などは後から変更すると保守コストが跳ね上がるため、命名規則を統一するのがおすすめです。
まとめ
VBAでピボットテーブル用のタイムラインスライサーを作り、End Date(終了日)で絞り込むには、SlicerCaches.Add2 と xlTimeline を使うのが基本です。一方で、失敗の多くはVBAの文法ではなく、
- フィールド名(キャプション)の不一致
- End Dateが文字列で日付扱いされていない
- End DateがValuesにあるだけで元フィールドとして扱われていない
といった前提条件の崩れに起因します。安定版マクロで「一時的にFiltersへ移動してから作成」「既存キャッシュの再利用」「配置の固定」まで組み込んでおけば、運用で困る場面が大幅に減ります。

コメント