【Excel VBA】ピボットテーブルを自動生成する方法(コピペOK)

【VBA】ピボットテーブルをVBAで自動生成する方法の解説用アイキャッチ画像 VBA
  1. ピボット自動化でここまでできる
  2. この自動化が効く場面・効かない場面
    1. 逆に、VBA化しないほうがいい場面
  3. 毎月8分の手作業が数秒になる(Before / After)
  4. 「作り直し」か「更新だけ」か:コードを書く前に決める
  5. 実行前に確認しておく2点
    1. 出力先シートの中身は消える:コピーを取ってから
    2. シート構成を確認する(実務版で使用)
  6. STEP1:空のピボットテーブルをコードで作る(基本版)
    1. 基本版で書き換える5つの変数
    2. 基本版コードがやっていること
  7. STEP2:フィールド配置と集計方法を自動化する(応用版)
    1. フィールド設定で書き換える変数
    2. 集計方法の定数一覧(xlSum以外も使える)
    3. 応用版の処理順
  8. STEP3:月次売上レポートを自動で仕上げる(実務版・グラフ連動)
    1. 実務版を自分のレポートに合わせる
    2. データシートの例
    3. 実務版の処理の全体像
  9. 実際にハマった失敗5つと、現場での直し方
    1. 1. ソースデータ範囲を固定で指定して集計漏れ
    2. 2. 同名のピボットテーブルが既にあってエラー
    3. 3. フィールド名がヘッダーと一致しなくてエラー
    4. 4. ソースデータに空行があって範囲が途中で切れた
    5. 5. ピボットテーブルを削除したのに「名前が重複しています」エラー
    6. 実行時エラー1004が出たら、この順番で確認する
    7. VBAでピボットテーブルのフィールド名が見つからないときの対処法
    8. VBAでピボットテーブルのデータが更新されないときの対処法
  10. よくある質問(更新・総計・複数値フィールド・削除)
    1. Q1: 既存のピボットテーブルをVBAで更新(リフレッシュ)するには?
    2. Q2: ピボットテーブルの総計(行・列)を非表示にしたい
    3. Q3: 複数の値フィールドを追加したい
    4. Q4: VBAで作ったピボットテーブルを削除したい
    5. Q5: ピボットテーブルのソース範囲を変更したい
    6. Q6: SUMIFS関数で足りる集計に、わざわざピボットを使う意味はある?
  11. まとめ:覚えるのは PivotCaches.Create と CreatePivotTable
    1. ピボット集計とセットで使う関連記事
  12. 次のステップ:元データの整備も自動化する
  13. 本番データで動かす前のチェックリスト

ピボット自動化でここまでできる

  • VBAでピボットテーブルを自動作成できる(PivotCaches.Create / CreatePivotTable)
  • フィールド配置(行・列・値・フィルタ)や集計方法をVBAで制御できる
  • 月次データから部署別売上ピボットテーブルとグラフを自動生成できる

この自動化が効く場面・効かない場面

まず、この記事の自動化が向いているのは次のような場面だ。

  • 毎月届く売上データから部署別・商品別のクロス集計を自動で作りたい
  • ピボットテーブルのフィールド配置を毎回手作業でドラッグするのが面倒なとき
  • データ更新のたびにピボットテーブルとグラフを再作成して報告書に使いたい
  • 集計軸や集計方法(合計・平均・個数)を切り替えた複数パターンを一度に作りたい

逆に、VBA化しないほうがいい場面

一方で、次のケースではマクロを書かないほうが早く終わる。自分の状況がこちらに当てはまるなら、この記事のコードは不要だ。

  • 一度きりの集計:手動ピボットなら数分で終わる。マクロを書いてテストする時間のほうが長くつく。
  • レイアウトは毎回同じで、データの数字だけ差し替わる:ピボットを作り直す必要はなく、更新(Refresh)だけで足りる。ピボットテーブルの更新をVBAで自動化する方法 のほうが短いコードで済む。
  • 元データの形式が毎月バラバラ:列の並びや見出しが安定しないデータでは、ピボット自動化の前に元データの整形を安定させるのが先。フィールド名の不一致で毎月エラーになる。
  • 集計軸を試行錯誤したい:分析の初期段階で「どの軸で見るか」を探っているうちは、手動でドラッグして試すほうが速い。軸が固まってからコード化する。

毎月8分の手作業が数秒になる(Before / After)

VBAで自動生成した部署別商品別のピボットテーブル
VBAで部署別・商品別の売上を自動集計したピボットテーブルの完成例

Before(手作業でピボットテーブルを作成):

操作 所要時間
データ範囲を選択してピボット挿入 約1分
行・列・値・フィルタのフィールド配置 約2分
書式設定・グラフ作成 約5分
毎月繰り返し 毎回約8分

After(VBAで自動生成):

操作 所要時間
データを貼り付け 数分
マクロ実行でピボット+グラフ生成 数秒
配置ミス・集計漏れ ゼロ

自分も以前、毎月届く売上データを受け取るたびに、ピボットテーブルを手作業で作り直していた。行フィールドに部署を入れて、列フィールドに月を入れて、値に売上金額を入れて……毎回同じ操作なのに、うっかりフィールドの配置を間違えることがあった。VBAで自動生成するようにしてからは、データを貼り付けてマクロを実行するだけで同じ形式のピボットテーブルとグラフが一瞬で完成するようになった。配置ミスもゼロ。同じようにピボットテーブルの手作業に時間を取られている人に、この記事で自動化を体験してほしい。

ピボットテーブルの作成は手作業だと毎回同じ操作の繰り返し。VBAで自動化すれば速くて正確。

なお、ピボットの元データを条件付きで抽出してから集計したい場合は 複数条件でデータを抽出してまとめる方法 を参照。

「作り直し」か「更新だけ」か:コードを書く前に決める

ピボットテーブルの自動化には「毎回作り直す」と「既存のものを更新する」の2通りがあり、どちらが必要かで書くコードの量がまったく違う。自分は最初この区別を意識せず、更新だけで済む場面でも毎回テーブルごと作り直すマクロを書いていた。動くには動くが、ピボットのセルを参照していた別シートの数式が作り直しのたびに壊れるという副作用があり、結局あとから更新方式に書き直すはめになった。先に自分の状況を確認してほしい。

状況 やること 必要なコード量
レイアウトは固定で、数字だけ毎月変わる 既存ピボットの更新 RefreshTable 1行
数字に加えてデータの行数も増減する ソース範囲を差し替えて更新 ChangePivotCacheRefreshTable の数行
レイアウトごと毎回作る/集計パターンを複数量産する/他の人のPCでも同じ表を再現する ピボットの自動生成 この記事のコード
集計軸をその場で試行錯誤したい 手動ピボット なし(手動のほうが速い)

上2つに当てはまる人は、ピボットテーブルの更新をVBAで自動化する方法 だけで足りる。ここから先は「毎回作り直す」必要がある人向けの内容だ。

実行前に確認しておく2点

出力先シートの中身は消える:コピーを取ってから

ピボットテーブルの作成先シートにデータがある場合、上書きされる可能性がある。 必ずファイルのコピーを別フォルダに保存してから実行する。

シート構成を確認する(実務版で使用)

実務版コードは以下のシート構成を前提としている:

  • データシート: シート名「売上データ」— A列:日付、B列:部署、C列:商品、D列:売上金額(1行目はヘッダー)
  • 集計シート: シート名「集計」— ピボットテーブルとグラフの出力先(自動作成される)

基本版・応用版はシート構成を問わない。

STEP1:空のピボットテーブルをコードで作る(基本版)

まずはピボットテーブルを1つ作る基本。PivotCaches.Create でキャッシュを作り、CreatePivotTable でテーブルを配置する。


'============================================================
' ■ ピボットテーブルを作成する(基本版)
'   → 指定したデータ範囲からピボットテーブルを自動生成
'============================================================
Sub CreatePivotTableBasic()

    '--- ★書き換えポイント ---
    Dim srcSheet As String
    srcSheet = "Sheet1"                '← データがあるシート名

    Dim srcRange As String
    srcRange = "A1:D100"               '← データ範囲(ヘッダー含む)

    Dim dstSheet As String
    dstSheet = "Sheet2"                '← ピボットの出力先シート名

    Dim dstCell As String
    dstCell = "A3"                     '← ピボットの配置先セル

    Dim ptName As String
    ptName = "売上集計"                '← ピボットテーブルの名前
    '--- ★ここまで ---

    '--- 出力先シートが存在しなければ作成
    Dim wsDst As Worksheet
    On Error Resume Next
    Set wsDst = ThisWorkbook.Worksheets(dstSheet)
    On Error GoTo 0

    If wsDst Is Nothing Then
        Set wsDst = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
        wsDst.Name = dstSheet
    End If

    '--- 同名のピボットテーブルがあれば削除
    Dim ptDel As PivotTable
    On Error Resume Next
    Set ptDel = wsDst.PivotTables(ptName)
    On Error GoTo 0

    If Not ptDel Is Nothing Then
        ptDel.TableRange2.Clear
    End If

    '--- ピボットキャッシュを作成
    Dim srcData As String
    srcData = srcSheet & "!" & srcRange

    Dim pc As PivotCache
    Set pc = ThisWorkbook.PivotCaches.Create( _
        SourceType:=xlDatabase, _
        SourceData:=srcData)

    '--- ピボットテーブルを作成
    Dim pt As PivotTable
    Set pt = pc.CreatePivotTable( _
        TableDestination:=wsDst.Range(dstCell), _
        TableName:=ptName)

    MsgBox "ピボットテーブル「" & ptName & "」を作成しました。" & vbCrLf & _
           "フィールドエリアにドラッグしてご利用ください。", vbInformation

End Sub

基本版で書き換える5つの変数

変数 説明 初期値
srcSheet データがあるシート名 "Sheet1"
srcRange データ範囲(ヘッダー含む) "A1:D100"
dstSheet ピボットの出力先シート名 "Sheet2"
dstCell ピボットの配置先セル "A3"
ptName ピボットテーブルの名前 "売上集計"

基本版コードがやっていること

  1. 出力先シートが存在しなければ新規作成
  2. 同名のピボットテーブルが既にあれば TableRange2.Clear で削除
  3. PivotCaches.Create でソースデータのキャッシュを作成
  4. CreatePivotTable でピボットテーブルを配置

ポイント: この段階ではフィールドが未配置の空のピボットテーブルが作られる。「テーブルの箱だけ自動で作って、フィールドは手でドラッグしたい」という使い方なら基本版で完成だ。フィールド配置までコードで固定したい場合はSTEP2に進む。

STEP2:フィールド配置と集計方法を自動化する(応用版)

手作業でフィールドをドラッグする操作をすべてコードで制御する。ここは基本版のコードに貼り足す差分だけを載せる。基本版の末尾にある MsgBox の2行(vbInformation まで)を削除し、代わりに次のブロックを貼り付ければ、フィールド配置済みのピボットテーブルが一発で完成する。


    '============================================
    ' ▼ 基本版のMsgBoxを削除して、ここから貼り付け
    '============================================

    '--- フィールド設定(★書き換えポイント) ---
    Dim rowFieldName As String
    rowFieldName = "部署"              '← 行フィールドに入れる列名

    Dim colFieldName As String
    colFieldName = "商品"              '← 列フィールドに入れる列名

    Dim valFieldName As String
    valFieldName = "売上金額"          '← 値フィールドに入れる列名

    Dim filterFieldName As String
    filterFieldName = ""               '← フィルタに入れる列名(不要なら空文字)

    Dim aggFunc As XlConsolidationFunction
    aggFunc = xlSum                    '← 集計方法(xlSum/xlCount/xlAverage/xlMax/xlMin)
    '--- ★ここまで ---

    '--- 行フィールドを配置
    With pt.PivotFields(rowFieldName)
        .Orientation = xlRowField
        .Position = 1
    End With

    '--- 列フィールドを配置
    If colFieldName <> "" Then
        With pt.PivotFields(colFieldName)
            .Orientation = xlColumnField
            .Position = 1
        End With
    End If

    '--- 値フィールドを配置(集計方法を指定)
    pt.AddDataField pt.PivotFields(valFieldName), _
        "集計_" & valFieldName, aggFunc

    '--- フィルタフィールドを配置
    If filterFieldName <> "" Then
        With pt.PivotFields(filterFieldName)
            .Orientation = xlPageField
            .Position = 1
        End With
    End If

    MsgBox "ピボットテーブル「" & ptName & "」を作成し、" & vbCrLf & _
           "行: " & rowFieldName & " / 値: " & valFieldName & " を配置しました。", vbInformation

貼り付け位置さえ守れば、Sub名はそのままで動く(気になる場合は CreatePivotTableWithFields などに変えてよい)。行・列・フィルタは空文字を入れるとスキップされるので、「行と値だけ」のシンプルな集計にも使える。

フィールド設定で書き換える変数

変数 説明 初期値
rowFieldName 行フィールドに入れる列名 "部署"
colFieldName 列フィールドに入れる列名 "商品"
valFieldName 値フィールドに入れる列名 "売上金額"
filterFieldName フィルタに入れる列名(不要なら空文字) ""
aggFunc 集計方法 xlSum(合計)

集計方法の定数一覧(xlSum以外も使える)

定数 集計方法
xlSum 合計
xlCount 個数
xlAverage 平均
xlMax 最大値
xlMin 最小値

応用版の処理順

  1. 基本版と同じくピボットキャッシュとテーブルを作成
  2. PivotFields("列名").Orientation = xlRowField で行フィールドに配置
  3. 列フィールド・フィルタフィールドも同様に配置(空文字ならスキップ)
  4. AddDataField で値フィールドを追加し、集計方法を指定

ポイント: PivotFields に指定する名前は、ソースデータの ヘッダー行の文字列と完全一致 させる必要がある。大文字・小文字・全角・半角が違うとエラーになる。

ソースデータの範囲を動的に取得する方法については データの最終行・最終列を正確に取得する方法 も参考になる。

STEP3:月次売上レポートを自動で仕上げる(実務版・グラフ連動)

VBAで作成したピボット集計結果の棒グラフ
ピボットテーブルの集計結果から同じシートにグラフを自動作成した例

実務で最もニーズが高いパターン。月次の売上データから部署別ピボットテーブルを自動生成し、集計グラフも連動して作成する。データ範囲は最終行を動的に取得するので、行数が変わっても集計漏れがない。

月次報告のピボットテーブルとグラフが自動で揃うようになってからは、報告書の作成時間が半分以下になった。フォーマットも毎回統一されるので見栄えも良くなった。

検証環境: Microsoft 365(Windows 11)で、約3,000行×4列の売上データを使って動作確認している。この規模ならマクロ実行からピボットとグラフの完成まで2〜3秒程度(PCスペックとデータ量で変わる)。数万行を超えるデータではキャッシュ作成に時間がかかるようになるが、月次の売上明細くらいの規模なら特別な高速化は必要ない。


'============================================================
' ■ 月次売上データから部署別ピボット+グラフを自動生成(実務版)
'   → 「売上データ」シートからピボットテーブルを作成
'   → 「集計」シートにピボットテーブル+棒グラフを配置
'   → データ範囲は最終行を動的取得
'============================================================
Sub CreateMonthlySalesPivot()

    '--- ★書き換えポイント ---
    Dim dataSheetName As String
    dataSheetName = "売上データ"        '← データシート名

    Dim summarySheetName As String
    summarySheetName = "集計"           '← 集計シート名(なければ自動作成)

    Dim ptName As String
    ptName = "部署別売上集計"           '← ピボットテーブル名

    Dim chartTitle As String
    chartTitle = "部署別売上集計グラフ" '← グラフのタイトル

    '--- フィールド設定 ---
    Dim rowField As String
    rowField = "部署"                  '← 行フィールド

    Dim colField As String
    colField = "商品"                  '← 列フィールド(不要なら空文字)

    Dim valField As String
    valField = "売上金額"              '← 値フィールド

    Dim filterField As String
    filterField = ""                   '← フィルタ(不要なら空文字)
    '--- ★ここまで ---

    '--- データシートの参照を取得
    Dim wsData As Worksheet
    On Error Resume Next
    Set wsData = ThisWorkbook.Worksheets(dataSheetName)
    On Error GoTo 0

    If wsData Is Nothing Then
        MsgBox "シート「" & dataSheetName & "」が見つかりません。", vbExclamation
        Exit Sub
    End If

    '--- データ範囲を動的に取得(最終行・最終列)
    Dim lastRow As Long
    lastRow = wsData.Cells(wsData.Rows.Count, 1).End(xlUp).Row

    Dim lastCol As Long
    lastCol = wsData.Cells(1, wsData.Columns.Count).End(xlToLeft).Column

    If lastRow < 2 Then
        MsgBox "データがありません(2行目以降にデータが必要です)。", vbExclamation
        Exit Sub
    End If

    Dim srcData As String
    srcData = dataSheetName & "!" & wsData.Range( _
        wsData.Cells(1, 1), wsData.Cells(lastRow, lastCol)).Address(False, False)

    '--- 集計シートが存在しなければ作成、あればクリア
    Dim wsSummary As Worksheet
    On Error Resume Next
    Set wsSummary = ThisWorkbook.Worksheets(summarySheetName)
    On Error GoTo 0

    If wsSummary Is Nothing Then
        Set wsSummary = ThisWorkbook.Worksheets.Add( _
            After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
        wsSummary.Name = summarySheetName
    Else
        '--- 既存のピボットテーブルを削除
        Dim ptDel As PivotTable
        On Error Resume Next
        Set ptDel = wsSummary.PivotTables(ptName)
        On Error GoTo 0

        If Not ptDel Is Nothing Then
            ptDel.TableRange2.Clear
        End If

        '--- 既存のグラフを削除
        Dim co As ChartObject
        For Each co In wsSummary.ChartObjects
            co.Delete
        Next co
    End If

    '--- タイトル行を出力
    wsSummary.Range("A1").Value = chartTitle
    wsSummary.Range("A1").Font.Size = 14
    wsSummary.Range("A1").Font.Bold = True

    '--- ピボットキャッシュを作成
    Dim pc As PivotCache
    Set pc = ThisWorkbook.PivotCaches.Create( _
        SourceType:=xlDatabase, _
        SourceData:=srcData)

    '--- ピボットテーブルを作成
    Dim pt As PivotTable
    Set pt = pc.CreatePivotTable( _
        TableDestination:=wsSummary.Range("A3"), _
        TableName:=ptName)

    '--- 行フィールドを配置
    With pt.PivotFields(rowField)
        .Orientation = xlRowField
        .Position = 1
    End With

    '--- 列フィールドを配置
    If colField <> "" Then
        With pt.PivotFields(colField)
            .Orientation = xlColumnField
            .Position = 1
        End With
    End If

    '--- 値フィールドを配置(合計)
    pt.AddDataField pt.PivotFields(valField), _
        "合計_" & valField, xlSum

    '--- フィルタフィールドを配置
    If filterField <> "" Then
        With pt.PivotFields(filterField)
            .Orientation = xlPageField
            .Position = 1
        End With
    End If

    '--- ピボットテーブルの書式設定
    pt.ShowTableStyleRowStripes = True
    pt.TableStyle2 = "PivotStyleMedium9"

    '--- ピボットグラフを作成(集計シートに埋め込み)
    Dim ptRange As Range
    Set ptRange = pt.TableRange1

    '--- グラフの配置位置を計算(ピボットテーブルの右側)
    Dim chartLeft As Double
    chartLeft = wsSummary.Cells(3, pt.TableRange2.Columns.Count + 2).Left

    Dim chtObj As ChartObject
    Set chtObj = wsSummary.ChartObjects.Add( _
        Left:=chartLeft, _
        Top:=wsSummary.Range("A3").Top, _
        Width:=450, _
        Height:=300)

    With chtObj.Chart
        .SetSourceData Source:=ptRange
        .ChartType = xlColumnClustered
        .HasTitle = True
        .ChartTitle.Text = chartTitle
        .HasLegend = True
        .Legend.Position = xlLegendPositionBottom
    End With

    '--- 列幅を自動調整
    wsSummary.Cells.EntireColumn.AutoFit

    MsgBox "部署別売上ピボットテーブルとグラフを作成しました。" & vbCrLf & vbCrLf & _
           "データ範囲: " & srcData & vbCrLf & _
           "データ件数: " & (lastRow - 1) & " 行" & vbCrLf & _
           "出力先: " & summarySheetName & " シート", vbInformation

End Sub

実務版を自分のレポートに合わせる

変数 説明 初期値
dataSheetName データシート名 "売上データ"
summarySheetName 集計シート名 "集計"
ptName ピボットテーブル名 "部署別売上集計"
chartTitle グラフのタイトル "部署別売上集計グラフ"
rowField 行フィールド "部署"
colField 列フィールド "商品"
valField 値フィールド "売上金額"
filterField フィルタフィールド ""(なし)

データシートの例

VBAでピボットテーブルを作成する前の売上データ例
部署・商品・金額の見出しをそろえた、ピボットテーブル作成前の元データ例

「売上データ」シートに以下のように記入する:

A列(日付) B列(部署) C列(商品) D列(売上金額)
2026/01/05 営業部 商品A 150000
2026/01/10 開発部 商品B 230000
2026/01/15 営業部 商品C 180000
2026/02/03 総務部 商品A 95000
2026/02/12 営業部 商品B 310000

実務版の処理の全体像

  1. データシートの最終行・最終列を動的に取得し、ソース範囲を組み立て
  2. 集計シートがなければ新規作成、あれば既存のピボットテーブルとグラフを削除
  3. タイトル行を出力し、ピボットキャッシュとテーブルを作成
  4. 行・列・値・フィルタのフィールドを配置
  5. テーブルスタイルを設定
  6. ピボットテーブルの右側に棒グラフを自動作成
  7. 列幅を自動調整し、結果をメッセージボックスで表示

ポイント: ソースデータの範囲を最終行で動的に取得しているので、データの行数が増えても集計漏れが発生しない。

ピボットの元データを条件付きで抽出してから集計したい場合は 複数条件でデータを抽出してまとめる方法 を参照。

実際にハマった失敗5つと、現場での直し方

1. ソースデータ範囲を固定で指定して集計漏れ

自分もこれで上司に指摘された。ソースデータ範囲を "A1:D100" と固定で書いたら、データが101行以上になった月に集計漏れが発生した。厄介なのは、エラーが出ずに「それらしい集計表」が完成してしまうことだ。100行分だけの合計でも見た目はまったく正常なので、提出するまで誰も気づかなかった。

対策: 実務版コードのように最終行を動的に取得する。詳しくは データの最終行・最終列を正確に取得する方法 を参照。

再発防止の検算: 集計漏れは目視レビューでは見つからないので、この件以降、ピボットの総計と元データの合計を突き合わせる検算を習慣にしている。元データの金額列を =SUM(D:D) で合計し、ピボットの総計と一致するかを見るだけ。1分で終わるが、この検算を入れてから集計漏れは一度も再発していない。

2. 同名のピボットテーブルが既にあってエラー

原因: CreatePivotTable は同名のピボットテーブルが既にあるとエラーになる。Names.Add のように上書きはされない。

対策: 作成前に同名のピボットテーブルを TableRange2.Clear で削除する。基本版・応用版・実務版のコードにはこの処理を入れてある。

3. フィールド名がヘッダーと一致しなくてエラー

原因: PivotFields("部署") のように指定する名前が、ソースデータの1行目(ヘッダー)と完全一致しないとエラーになる。全角・半角・スペースの有無も区別される。

対策: ヘッダー行の文字列をコピペして変数に設定する。手入力すると全角・半角のミスが起きやすい。

4. ソースデータに空行があって範囲が途中で切れた

原因: Excelはデータ範囲を自動認識するとき、空行があるとそこでデータが終わったと判断する場合がある。

対策: ソースデータに空行を作らない。最終行の取得は Cells(Rows.Count, 1).End(xlUp).Row で行う。

5. ピボットテーブルを削除したのに「名前が重複しています」エラー

原因: シートの内容をクリアしてもピボットキャッシュが残っている場合がある。

対策: TableRange2.Clear でピボットテーブル自体を削除する。Cells.Clear ではピボットの定義が残ることがある。

実行時エラー1004が出たら、この順番で確認する

ピボット系マクロのエラーはほとんどが「実行時エラー1004」で、メッセージ文からは原因が特定しにくい。経験上、当たりが早い順に並べるとこうなる。

確認順 見るところ よくある原因
1 PivotFields に渡している文字列 ヘッダーとの不一致(全角/半角、前後スペース)
2 TableName の指定 同名のピボットテーブルが別シートに残っている
3 SourceData の文字列 シート名の間違い、範囲にヘッダー行が含まれていない
4 出力先セルの位置 既存のピボットテーブルと重なる位置に作ろうとしている

1の確認には、Debug.Print wsData.Cells(1, 2).Value のようにヘッダーセルの値をイミディエイトウィンドウに出力して、コード内の文字列と並べて見比べるのが確実だ。

VBAでピボットテーブルのフィールド名が見つからないときの対処法

「PivotFields(“部署”)を指定したらエラーになる」という場合、原因はヘッダー行の文字列と完全一致していないことだ。全角・半角・前後のスペースが1つでも違うとエラーになる。ヘッダーセルの値をDebug.Printで出力して、コード内の文字列と見比べるのが確実。

VBAでピボットテーブルのデータが更新されないときの対処法

「ソースデータを変更したのにピボットテーブルの値が古いまま」という場合、原因はRefreshTableを呼んでいないことだ。ピボットテーブルはキャッシュでデータを保持しているため、pt.RefreshTable を実行してキャッシュを更新する必要がある。

よくある質問(更新・総計・複数値フィールド・削除)

Q1: 既存のピボットテーブルをVBAで更新(リフレッシュ)するには?

RefreshTable メソッドを使う:


Dim pt As PivotTable
Set pt = Worksheets("集計").PivotTables("売上集計")
pt.RefreshTable

Q2: ピボットテーブルの総計(行・列)を非表示にしたい


pt.ColumnGrand = False   '列の総計を非表示
pt.RowGrand = False      '行の総計を非表示

Q3: 複数の値フィールドを追加したい

AddDataField を複数回呼ぶ:


pt.AddDataField pt.PivotFields("売上金額"), "合計_売上", xlSum
pt.AddDataField pt.PivotFields("売上金額"), "平均_売上", xlAverage
pt.AddDataField pt.PivotFields("件数"), "件数_カウント", xlCount

Q4: VBAで作ったピボットテーブルを削除したい


Dim pt As PivotTable
Set pt = Worksheets("集計").PivotTables("売上集計")
pt.TableRange2.Clear

Q5: ピボットテーブルのソース範囲を変更したい

新しいキャッシュを作成して ChangePivotCache で差し替える:


Dim pc As PivotCache
Set pc = ThisWorkbook.PivotCaches.Create( _
    SourceType:=xlDatabase, _
    SourceData:="Sheet1!A1:D200")

Dim pt As PivotTable
Set pt = Worksheets("集計").PivotTables("売上集計")
pt.ChangePivotCache pc
pt.RefreshTable

Q6: SUMIFS関数で足りる集計に、わざわざピボットを使う意味はある?

集計軸が固定で1〜2種類しかないなら、SUMIFSやCOUNTIFSのほうがシートの管理はしやすい。ピボットが有利になるのは、行×列のクロス集計、集計軸の組み替え、明細へのドリルダウン(集計セルをダブルクリックすると元の明細行が展開される機能)が必要なときだ。自分は「上司が集計軸を変えたがる報告書」はピボット、「毎月まったく同じ形の管理表」は関数、と使い分けている。

まとめ:覚えるのは PivotCaches.Create と CreatePivotTable

  • PivotCaches.Create: ソースデータのキャッシュを作成。SourceData にデータ範囲を指定
  • CreatePivotTable: キャッシュからピボットテーブルを配置。TableName はブック内で一意に
  • PivotFields / Orientation: 行・列・値・フィルタのフィールド配置を制御
  • AddDataField: 値フィールドの追加。第3引数で集計方法(xlSum / xlCount / xlAverage など)を指定
  • グラフ連動: ピボットテーブルの TableRange1 をグラフのソースに指定すれば連動
  • 迷ったら: レイアウト固定でデータだけ変わるなら「更新」、毎回作るなら「自動生成」。先に判断基準の表で確認する

ピボット集計とセットで使う関連記事

次のステップ:元データの整備も自動化する

本番データで動かす前のチェックリスト

  • 元データの1行目に空白の見出しがないか確認する
  • ピボットで使う列名とコード内のフィールド名が完全一致しているか確認する
  • ソース範囲を固定指定せず、最終行・最終列から動的に取得する
  • 同名のピボットテーブルがある場合は、作成前に削除またはシートを作り直す
  • データ更新後に RefreshTable を実行する
  • ピボットの総計と元データの SUM を突き合わせて、集計漏れがないか検算する

最初は基本版で動作確認し、うまく動いたら応用版・実務版へ進めるのが安全です。ピボットテーブルは便利ですが、フィールド名やソース範囲の指定ミスで止まりやすいので、まず小さいデータで試してから本番データに使ってください。

コメント

タイトルとURLをコピーしました