データを扱う時のいろいろな操作 2

■ Excel豆知識44 ピボットテーブル条件付き書式サンプルExcel_mame44_pivot2_





44-2 ピボットテーブルの条件付き書式の設定

Microsoftの参考記事
[XL2000] ピボットテーブルで条件付き書式が保持されない
Excel でピボットグラフを変更すると、データ系列の書式が削除される

上のリンクの記事に
******************************
現象
ピボットテーブル レポートで、フィールドの更新や配置の変更を行うと、フィールドに適用されている条件
付き書式が解除されます。条件付き書式は、書式が適用されていた元のセルに残ったままになります。 
原因
この現象は、Microsoft Excel のピボットテーブル レポートで条件付き書式を任意のセルに適用すると発生
します。条件付き書式はセルには適用されますが、ピボットテーブル フィールド自体には適用されません。
そのため、ピボットテーブル レポートのレイアウトを更新または配置変更すると、条件付き書式は最初に適
用されていたセルに残ったままになります。 
******************************
とあります。

つまり、罫線などの書式はフィールド自体に適用されるのでレイアウトを変更しても書式が維持されましたが
条件付き書式はその方法では維持されない、ということです。
でも、やっぱりTasanさんに言わせると「ここで諦めてはいけません。(笑)」ということのようなのです。^^;

そこで、ピボットテーブルに対する条件付き書式の設定について、Tasanさんに説明していただくことにしまし
た。一応手作業でのやり方も書いていただきましたが、この設定はやはりマクロでの作業が現実的だと思いま
す。初心者の方むけのExcel豆知識の記事としてはちょっと高度なのですが、ピボットテーブル大好きの私と
しましては、是非紹介していただきたかったので、無理を言ってお願いいたしました。

では、よろしくお願いいたします。m(__)m


ピボットテーブルに対する条件付き書式設定について

通常の計算表と同じようにピボットテーブル機能で作成した集計表に条件付き書式を設定したい場合があると
思います。しかし、条件付き書式を設定した後で、データを更新したり、レイアウトを変更すると、意図した
結果にならないことがあります。これは、フィールドの対象エリアを選択して設定した書式は、そのエリアに
保持されるのに対して、条件付き書式は、セルに適用されるため、ピボットテーブルの書式保持の対象となら
ないからです。
これを回避するためには、次のような方法が考えられます。

A.手作業で…
データを更新したり、レイアウトを変えた都度、以下のような方法で対象エリアを選択して条件付き書式を再
設定します。

1.最初に設定したセル範囲の条件付き書式は、不要なので一旦削除します。
 編集 > ジャンプ > セル選択 > 条件付き書式 > OK
 これで、条件付き書式を設定したセル範囲が選択されます。
 設定していなければ見つからなかったことのメッセージが表示されます。
2.書式 > 条件付き書式 > 削除 > 削除する条件をチェック > OK > OK
3.新たに条件を設定する範囲を指定します。
4.書式 > 条件付き書式 > 条件式と書式を追加 > OK

もっともオーソドックスな方法ですが「マクロは使わないで…」という人は、この方法しかないようです。


B.マクロで…
「手作業で行なうのが面倒だ…。」と思う方は、マクロで設定する方法があります。
上記の作業をマクロの記録を行ないながら作業すればVBAで記述されたコードが手に入ります。次のように
なります。(コメントは後から追加しています。)
Sub 条件付き書式記録()

'編集 > ジャンプ > セル選択 > 条件付き書式 > OK
    ActiveCell.SpecialCells(xlCellTypeAllFormatConditions).Select
'書式 > 条件付き書式 > 削除 > 3つチェックを入れて > OK > OK
    Selection.FormatConditions.Delete
'ピボットテーブル > 選択 > データ
    ActiveSheet.PivotTables("ピボットテーブル1").PivotSelect "", xlDataOnly
'書式 > 条件付き書式 > セルの値が100以上なら黄緑色のパターンにする
    Selection.FormatConditions.Delete
    Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreaterEqual _
        , Formula1:="100"
    Selection.FormatConditions(1).Interior.ColorIndex = 4
'A4セルを選択する
    Range("A4").Select

End Sub
このマクロをデータ更新やレイアウト変更で表示がおかしいとなった時に実行すれば、条件付き書式が再設定
できます。但し、実際の運用では、"条件付き書式"がなかったり、ピボットテーブル名が"ピボットテーブル1"であ
るとは限りませんから、エラーが発生しても処理を継続するようにしたり、ピボットテーブルの名前をインデ
ックス番号に修正して利用するとよいでしょう。
Sub 条件付き書式記録_修正()

'画面の更新を止める
    Application.ScreenUpdating = False
'実行時エラーが発生しても処理を継続する
    On Error Resume Next
'条件付き書式の範囲の条件付き書式を削除する
    ActiveCell.SpecialCells(xlCellTypeAllFormatConditions).FormatConditions.Delete
'データエリアを選択する
    ActiveSheet.PivotTables(1).PivotSelect "", xlDataOnly
'条件付き書式を設定する
    Selection.FormatConditions.Add Type:=xlCellValue, _
        Operator:=xlGreaterEqual, Formula1:="100"
    Selection.FormatConditions(1).Interior.ColorIndex = 4
'A4セルを選択する
    Range("A4").Select
'エラー処理を無効にする
    On Error GoTo 0
'画面の更新を有効にする
    Application.ScreenUpdating = True

End Sub
C.イベントマクロを利用して…
「マクロを実行するのさえ面倒だ…。」という方には、イベントマクロを使う方法があります。
イベントマクロとは、ユーザーが何かをすることによって動くマクロのことです。ピボットテーブルの操作で
いうと、データを更新したり、レイアウトを変更すると、エクセルは、計算して答えを出そうとします。この
「計算する時/更新する時」のイベントを利用してして「条件付き書式記録_修正」マクロが動くようにすれ
ば、ユーザーがマクロを実行しなくても自動で条件付き書式が設定されます。

--------------------------------------------------------------------------------
【イベントマクロ使用上の注意】
イベントマクロは、ユーザーがマクロを実行しなくても、イベントが発生すれば、イベントプロシージャ内に
記述されたマクロが自動的に実行されますので「予期せぬことでマクロが実行されてしまうことがある」とい
うことを承知の上で利用してください。
また、イベントマクロの実行によって、編集 > 元に戻す(Ctrl+Z)という作業で元に戻すことができなくなり
ます。サンプルブックの操作でいえば、レイアウト変更時に「品名」や「入荷地」を誤ってデータエリアにド
ラッグすると書式が失われますが、元に戻せなくなります。
--------------------------------------------------------------------------------

今回のサンプルでのイベントプロシージャの書く場所と書き方は次のとおりです。

1.ピボットテーブルのあるシート見出しを右クリックして"コードの表示"を選びます。
2.コードウィンドウの左上の"(General)"と表示されたオブジェクトリストボックスの▼をクリックし、
 "WorkSheeet"を選びます。
3.Worksheet_SelectionChangeプロシージャが表示されますが、無視して右上の"SelectionChange"と
 表示されたプロシージャリストボックスの▼をクリックします。
4.リストの"Calculate"をクリックします。
 ブックをXL2002以降で使うなら"PivotTableUpdate"をクリックしてもいいです。
 (どちらかを選択してください。)
5.次のように空白行に作成した条件付き書式記録マクロを加筆します。
 (両方を記述すると2回イベント処理が実行されますので、どちらか一方を記述してください。)
 マクロ処理の意味は、「ワークシートで計算が行なわれたら(ピボットテーブルが更新されたら)
 [条件付き書式記録_修正]マクロを実行する。」という処理です。
Private Sub Worksheet_Calculate()
    Call 条件付き書式記録_修正
End Sub
XL2002以降で動作
Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
    Call 条件付き書式記録_修正
End Sub
6.Worksheet_SelectionChangeプロシージャは、不要なので削除してAlt+F11でワークシートに戻ります。

これで作業は、終了です。データの更新やレイアウトを変更すれば、その都度、条件付き書式が設定される
ようになります。

なお、「条件付き書式記録_修正」マクロには該当しませんが、ユーザーの書いたマクロ処理の中にイベント
を引き起こすようなコードが書かれていてイベントが再帰的に呼び出されてしまうこともありますので、
.EnableEventsプロパティを用いて

Application.EnableEvents = False
マクロ処理
Application.EnableEvents = True

と、マクロ処理中は、イベントの発生を抑えるようにするということと、必ず、イベントを有効にして処理を
終了するようにしてください。

例えば、シートモジュールにイベントマクロが記述された状態で、今回の書式設定マクロを実行すると、23
回イベントが発生します。その都度、条件付き書式記録マクロが実行されたのでは、本末転倒な話ですので、
コードには、イベント処理が無効になるようコードを記述して、1回だけ発生するようにしてあります。

イベントマクロを利用する場合は、作者の意図しない操作で、それこそ予期せぬエラーが発生してしまいます
ので、必要のない時は実行されないように少しずつ改良していけば、より使いやすくなるのではないかと思い
ます。


条件付き書式のサンプルブックについて
マクロを有効にして開くと、自動実行されてデータと条件付き書式のついたピボットテーブルが作成されます。
ブックには、「条件付き書式記録_修正」マクロが実行されるように集計表シートのシートモジュールにイベン
トマクロが記述してあります。
ピボットテーブルツールバーの[データの更新]ボタンをクリックしたり、レイアウトを変えても条件付き書
式が保持されたように設定されることを確認して頂ければと思います。
また、追加で記述してある「条件付書式設定サンプル」マクロは、行エリア/列エリアにフィールドがあって、
データエリアに数値がある時だけ、小計行や総計行/列を除くデータエリアの範囲に条件付き書式が設定される
ようにしてあります。
コメントアウトしたりして、入れ替えて動作確認して頂ければと思います。
なお、レイアウトの変更等によって書式を失ってしまった場合は、"データ"シートの実行ボタンで再作成して
ください。
Sub 条件付書式設定サンプル()
'データエリアのセルの数値が100以上ならパターンを黄緑色にする

    Dim PvtTbl As PivotTable    '対象ピボットテーブル
    Dim PvtFld1 As PivotField   '行フィールド
    Dim PvtFld2 As PivotField   '列フィールド
    Dim mySelect As Range       '処理前選択範囲
    Dim myTarget1 As Range      '行フィールドによる選択範囲
    Dim myTarget2 As Range      '列フィールドによる選択範囲

    With ActiveSheet

'実行時エラーが発生しても処理を継続する
        On Error Resume Next

'条件付き書式が設定されたセルの条件付き書式を削除する
        ActiveCell.SpecialCells(xlCellTypeAllFormatConditions).FormatConditions.Delete

'エラー処理を無効にする
        On Error GoTo 0

'ピボットテーブルをオブジェクト変数へ代入
        Set PvtTbl = .PivotTables(1)
    End With

'ピボットテーブルで
    With PvtTbl

'行エリアと列エリアのフィールド名を取得する
'(データフィールドは取得しない)
        On Error Resume Next
        If .RowFields(.RowFields.Count).Caption = "データ" Then
            Set PvtFld1 = .RowFields(.RowFields.Count - 1)
        Else
            Set PvtFld1 = .RowFields(.RowFields.Count)
        End If
        If .ColumnFields(.ColumnFields.Count) = "データ" Then
            Set PvtFld2 = .ColumnFields(.ColumnFields.Count - 1)
        Else
            Set PvtFld2 = .ColumnFields(.ColumnFields.Count)
        End If

'実行時エラーが発生せず、
        If Err.Number = 0 Then

'データエリアに集計数値があれば(実際はフィールド数と列数や行数の比較)
            If .RowRange.Rows.Count > .RowFields.Count And _
                .ColumnRange.Columns.Count > .ColumnFields.Count Then

'選択されている範囲を変数に取得する
                Set mySelect = Selection

                Application.ScreenUpdating = False

'対象エリアを選択して変数に取得する
                .PivotSelect PvtFld1.Caption, xlDataOnly
                Set myTarget1 = Selection
                .PivotSelect PvtFld2.Caption, xlDataOnly
                Set myTarget2 = Selection

'対象エリアの共有している範囲を選択する
                Application.Intersect(myTarget1, myTarget2).Select
                Set myTarget2 = Nothing
                Set myTarget1 = Nothing

'選択した範囲に対して条件付き書式を設定する
                With Selection
                    .FormatConditions.Add Type:=xlCellValue, _
                        Operator:=xlGreaterEqual, Formula1:="100"
                    .FormatConditions(1).Interior.ColorIndex = 4
                End With

'元の選択範囲を選択する
                mySelect.Select
                Set mySelect = Nothing
                Application.ScreenUpdating = True
            End If
        End If
        On Error GoTo 0
    End With

End Sub
ページTOPへ