2021/04/05

出現回数ごとにデータを色分け




1.背景

例えば、図1-1のようなデータ(私が適当に作ったもの)があるとします。その日に「何が良く売れたか」を表にしたもののつもりです。
何が良く売れたかデータ
図1-1

データは取れたけど、パっと見ただけでは「何を示しているのか分からない」という時には「グラフ化」をします。Excelの大得意なところです。通常だったら図1-2のような積み上げ棒グラフがまず思いつきます。
棒グラフから分かることは「暑い時にはAが売れる」「寒い時にはBとCが売れる」くらいでしょうか。
何が良く売れたか棒グラフ
図1-2

このグラフを、今回作ったシステムで処理したのが図1-3です。A・B・Cを色分けした様な処理です。図1-3で分かるのは、棒グラフの「暑い時はA」「寒い時はBとC」に加え、「Bは休日に売れる」「Cは平日に売れる」という傾向もあるように見えます。
このように「グラフさえ作れば、全てが解析できた」と思うのは危険で、データの大切な「メッセージ」を見逃している可能性があるのです。
何が良く売れたか分布
図1-3

実は図1-3は、「濃いオレンジ色」は「B」に対して色付けしているのでは無く「出現回数の最も多い種類」であることを表してます。また、少し薄いオレンジ色は「出現回数が2番目に多い種類」、最も薄いのは「3番目」を表します。

今回は3種類のデータでしたので「種類に対する色分け」っぽくなってしまいましたが、多種類のデータを今回システムで処理することで、「出現の多い種類の把握」と同時に「その出現条件」や「分布」みたいなものも見えてくると思い、今回紹介することにしました。

なお、図1-3は「文字データ」でしたが、「数値データ」でも同様に処理できます。時系列データ等ではあまり意味が無いかもしれませんが、例えば「50代の人は〇〇の傾向がある」などの解析には使えるかもしれません。
また、図1-3は「出現回数の多い方から1~3番目」を色付けしましたが、もっと多く設定することも可能です。

2.システム概要

2-1.システム操作手順

本システムは、Excelのアドインに登録することを考慮し作っています。アドインに登録されていれば、図2-1のようにリボン上のボタンをクリックすることで、②のようなインプットボックスが現れます。
なお、サンプルファイルではシートの左上に起動用のボタンを配しています。
システムの起動
図2-1

インプットボックス②の中のテキストボックス枠内にカーソルがあることを確認し、対象とするデータ範囲(図2-2で言うと「C4:AM15」)を選択③します。選択範囲はインプットボックス内のテキストボックス枠に自動的に入力されます。
計算範囲の指定
図2-2

範囲指定後「OKボタン⑤」をクリックすると、インプットボックス⑥が消え、データ範囲⑦に対して図2-3のように「出現回数の多いデータ」のセル背景色が変更になります。
計算実行
図2-3

なお背景色変更について、今回システムでは以下のように設定をしています。
・範囲内で、出現回数の多いデータに対してセル背景色を変更
・最も回数の多いデータが濃い色、少なくなるに従って色も薄くなる(=色が明るくなる)
・サンプルマクロでは、出現回数の多い順に3種に対して着色。なお、マクロの定数を調整することで色の濃淡の段階を変更可。
・なお、異なる種類なのに出現回数が同じ場合には、その異なる種類は同色になる(出現回数のみで、着色を決めています)。

2-2.データ範囲への「条件付き書式」の確認

システム内で行っているのは、「指定したデータ範囲内」に対して「条件付き書式」を設定しているだけです。言わば、手動でも実施できるものです。
今回システムで作った「条件付き書式」を確認するには、まず、条件付き書式が設定されているセル(今回で言えば、背景色がオレンジ色になっているセル)を選択した上で、図2-4のように「ホーム」タブ→「スタイル」グループ→「条件付き書式」を選択し、一番下の「ルールの管理」をクリックします。
条件付き書式の確認方法
図2-4

すると、図2-5のように「条件付き書式ルールの管理」が現れます。今回は「3種類」を設定するプログラムになっているので、3段の条件付き書式が作成されています。
条件付き書式ルールの管理
図2-5

例えば、この3段の内一番上(濃いオレンジ色)の条件付き書式を選択し「ルールの編集」ボタンをクリックすると、図2-6のように「数式」を確認することが出来ます。
数式のチェック
図2-6

数式は「=SUMPRODUCT(($C$4:$AM$15=C4)*1)=138」です。SUMPRODUCT関数を使ったこの式の意味を次項で整理します。

2-3.SUMPRODUCT関数の使い方

まず「SUMPRODUCT関数」の使い方について説明します。1つ目の使い方は、図2-7のように「複数のセル範囲のそれぞれの値を掛け、最後にそれらを足し合わせる」というものです。図2-7ならば(100 x 119)+(200 x 138)+(100 x 108)=50300 という計算式です。
SUMPRODUCT関数による2つのセル範囲の乗算+和算
図2-7

もちろん1つのみのセル範囲でも計算できますが、これは「SUM関数」と同等です(図2-8)。
SUMPRODUCT関数による1つのセル範囲の和算
図2-8

SUMPRODUCT関数の2つ目の使い方は「条件に合致する個数を計算」することです。
図2-9のSUMPRODUCT関数のカッコ内では「 (B3:B5 = B3) * 1 」としています。式の意味は「B3:B5のセル範囲に、B3と同じ値の『A』が入っているセルの数を数える」というもので、その結果「2」がE6セルに表示されています。なお、自分(この場合はB3セル)もカウントに含めます。
SUMPRODUCT関数による文字列範囲のカウント
図2-9

この式は、どういう意味なのかを図2-10に示してみました。
SUMPRODUCT関数の計算過程
図2-10

まず「B3:B5 = B3」は、セル範囲の1つ1つに対して「B3セルと値は同じですか?」ということを確認しています。ここで同じ値が入っているのは、B3セル(比較しているセルと同じなので当然です)とB5セルの2つです。「同じか否か」を問われているので、結果はTrueかFalseになります。
このTrue・Falseの状態では、足し算などの計算は出来ません。しかしTrue・Falseに1を掛けると「True * 1 = 1」「False * 1 = 0」と計算が可能な数値として得ることが出来ます。
最後にこの関数のSUMPRODUCTは、値を足し合わせることが最終目的ですので、「1+0+1(=Trueとなったところの数だけ足し合わせる)」で、図2-10では「2」という値が得られることになります。

なお、文字列の比較だけで無く図2-11のように数値の比較も出来ますし、また等号(=イコール)だけなく不等号(>、<、>=、<=)も使用できます。
文字列の比較でも不等号を使用できますが、比較の大小は「文字コード」で比較をしているようで、複数文字の場合は、まず「1文字目の文字コード」で比較をし、次に「2文字目の文字コード」で比較をする・・・となっているようです。
SUMPRODUCT関数による数値範囲のカウント
図2-11

2-4.条件付き書式の数式の意味

このSUMPRODUCT関数の2つ目の使い方で作成したのが、図2-6の「=SUMPRODUCT(($C$4:$AM$15=C4)*1)=138」です。この中の「$C$4:$AM$15」は「ユーザーが指定したデータ範囲」を差し、「C4」は指定したデータ範囲の左上角のセル位置です。
ですので数式の前半「=SUMPRODUCT(($C$4:$AM$15=C4)*1)」の意味としては、「ユーザー指定したデータ範囲の中でC4セルと同じ値のセルの数」という意味になります。

この条件付き書式の数式は、「適用先のセル範囲の『左上角のセル』の数式」を表しており、その他の適用先セルには「この数式のコピー」が適用されるわけです。
もう一度数式「=SUMPRODUCT(($C$4:$AM$15=C4)*1)=138」を見てみると、中央当たりの「$C$4:$AM$15」には行・列番号の先頭に「$」マークが付いていますので「絶対セル位置」を表します。つまり「コピーをされても、絶対に変わらないセル範囲」となります。
一方その後ろの「C4」には行・列とも「$」マークがついていませんので、「行・列とも相対セル位置」となります。

この数式「=SUMPRODUCT(($C$4:$AM$15=C4)*1)=138」を、適用先の左上角セル(C4セル)から他の適用先セルにコピーするのですから、たとえば右隣のD4セルには「=SUMPRODUCT(($C$4:$AM$15=D4)*1)=138」、下のC5セルには「=SUMPRODUCT(($C$4:$AM$15=C)*1)=138」が適用されることになります。
条件付き書式の数式の元データ部分、つまり数式前半の「=SUMPRODUCT(($C$4:$AM$15=C4)*1)」を適用先セル全てに適用すると、図2-12のような結果が得られることになります。
同データの個数を各セルで計算
図2-12(計算過程の値であり、実際にセル上に表示される値ではありません。)

図2-12に表示されている数値は「各セルの値が適用先セルにいくつ存在するか」を表している訳ですが、条件付き書式の数式の比較データ部分、つまり数式の後半の「=138」に当てはまるセルだけが「条件付き書式」の設定書式(この場合は濃いオレンジ色)になります。

図2-5の2番目、3番目の条件付き書式の数式を見てみると「=SUMPRODUCT(($C$4:$AM$15=C4)*1)=119」「=SUMPRODUCT(($C$4:$AM$15=C4)*1)=108」になっていると思いますが、種類Bが138個・種類Aが119個・種類Cが108個であったため、「=119」の場合は少し薄いオレンジ色、「=108」は最も薄いオレンジ色に設定してあります。
この各種類の個数を数え、背景色を含めた条件付き書式の設定をマクロで自動化しています。

2-5.SUMPRODUCT以外の手法

今回、図2-6では「=SUMPRODUCT(($C$4:$AM$15=C4)*1)=138」という数式を使っています。しかし「範囲内の数を調べるならCOUNTIFで良いのでは?」と思われた方もいると思います。確かに「=COUNTIF($C$4:$AM$15,C4)=138」という数式を使っても同様の結果が得られます。

但し、条件付き書式に「COUNTIF」を使用するとCOUNTIFの計算処理に時間がかかるようです。今回のサンプルファイル(444セル)で試したところ、私のPCで約3倍(InputBoxで範囲の取得後~条件付き書式の表示完の時間(ScreenUpdating = False は無し):SUMPRODUCT=2.1秒、COUNTIF=5.8秒)の開きがありました。
(ScreenUpdating = False を設定すると書式表示完までの時間は大幅に短縮されますが、見た目ですが書式処理の段階でInputBoxの方が一呼吸遅れる感じです。)
少しでも処理の早い方が良いと考え、今回の条件付き書式には「SUMPRODUCT関数」を使用しています。

3.プログラムの流れ

プログラムを起動するとInputBoxが表示され、ユーザーが指定するセル範囲を取得します。
次に、指定セル範囲内の各セルに対して「範囲内で、当セルの値と同じ値を持つセルの数」を計算し、配列(RsAry)に代入していきます。
続いて、指定したセル範囲内の「古い条件付き書式」を削除し、配列RsAryの中から最も大きな値を呼び出し、その値を使って条件付き書式を作成します。最も大きな値での条件付き書式の作成が完了したら、次に大きな値を呼び出し、また条件付き書式を作成する作業を、設定回数分繰り返します。
プログラムの流れ
図3-1

4.標準モジュール(Module1)

今回のマクロは標準モジュールのみ、プロシージャも起動プロシージャ1つのみです。
  1. '========== ⇩(1) システム実行部 ============
  2. Public Sub LargeCountData()
  3.  Const SPLT As Integer = 3     '←データの多い方から〇番目まで書式を設定(split(分割)の略)
  4.  Dim Rs As Range          '←データ範囲
  5.  Dim r As Range           '←データ範囲内の1セル
  6.  Dim RsAry() As Long        '←同じデータのセル数の配列
  7.  Dim uniRsAry As Variant     '←RsAry配列の1データ
  8.  Dim rCnt As Long          '←カウンタ変数(データ範囲のセル数)
  9.  Dim spCnt As Long          '←カウンタ変数(条件付き書式の数)
  10.  Dim currentCnt As Long       '←処理中のセル値のセルの数
  11.  Dim LargeNo As Long         '←同じデータのセル数
  12.  On Error Resume Next
  13.   Set Rs = Application.InputBox _
  14.       (prompt:="データ範囲を選択して下さい", Title:="同データの数の多いものを彩色", Type:=8)
  15.   If Not Err.Number = 0 Then Exit Sub
  16.  On Error GoTo 0
  17.  ReDim RsAry(1 To Rs.Count)
  18.  For Each r In Rs
  19.   rCnt = rCnt + 1
  20.   RsAry(rCnt) = Application.WorksheetFunction.CountIf(Rs, r)
  21. '  RsAry(rCnt) = Application.WorksheetFunction.SumProduct (Evaluate("(" & Rs.Address & "=" & r.Address & ")*1"))
  22.  Next r
  23.  Application.ScreenUpdating = False
  24.  Rs.FormatConditions.Delete
  25.  For spCnt = 1 To SPLT
  26.   If currentCnt >= Rs.Count Then Exit For
  27.   LargeNo = Application.WorksheetFunction.Large(RsAry, 1 + currentCnt)
  28.   For Each uniRsAry In RsAry
  29.    If uniRsAry = LargeNo Then currentCnt = currentCnt + 1
  30.   Next uniRsAry
  31.   With Rs.FormatConditions.Add(Type:=xlExpression, _
  32.     Formula1:="=SUMPRODUCT((" & Rs.Address & "=" & Rs(1).Address(False, False) & ")*1)=" & LargeNo)
  33. '  With Rs.FormatConditions.Add(Type:=xlExpression, _
  34. '    Formula1:="=COUNTIF(" & Rs.Address & "," & Rs(1).Address(False, False) & ")=" & LargeNo)
  35.    With .Interior
  36.     .ThemeColor = msoThemeColorAccent4
  37. '    .Color = RGB(255, 192, 0)
  38.     .TintAndShade = (spCnt - 1) * 0.9 / (SPLT - 1)
  39.    End With
  40.   End With
  41.  Next spCnt
  42.  Set Rs = Nothing
  43.  Application.ScreenUpdating = True
  44. End Sub
図4-1

4-1.変数・定数の宣言

4行目の「Const SPLT As Integer = 3」は、条件付き書式を何個作るかの設定です。今回の「3」だと、同じ値を持つセル数の内「1~『3』番目に多いものに対して条件付き書式を作る」という事を表します。
6~15行目は、変数の宣言です。それぞれコメントに示した通りです。

4-2.InputBoxでのデータ範囲の取得

17~21行目は、「データ範囲」を取得します。
18~19行目では「InputBoxメソッド」を使っています。
InputBoxメソッドと似たものとして「InputBox関数」がありますが、InputBoxメソッドでは引数Typeに図4-2の値を指定することで、様々なデータを取り込むことができます。今回「Type:=8」を指定することで「セル参照(セル範囲)」を取得しています。
InputBoxメソッドの引数Typeの値
 値 説明
0数式
1数値
2文字列(テキスト)
4理論値(True 又は False)
8セル参照(Rangeオブジェクト)
16#N/Aなどのエラー値
64値の配列
図4-2

取得したセル範囲は変数Rsに代入しています。
そのInputBoxメソッド(18~19行目)を、17行目の「On Error Resume Next」と21行目の「On Error GoTo 0」で囲んでいます。もしInputBoxメソッドでエラーが出た時には、20行目の「If Not Err.Number = 0 Then Exit Sub」でマクロを終了することになります。
どういう時にエラーが発生するかと言うと、InputBoxが表示された後で「キャンセル」ボタンがクリックされた時や「ダイアログ右上の×印」をクリックされた時(両方ともエラー番号424が返されます)です。その時には「処理を中止する意図がある」と判断し、マクロを中止させています。

4-3.同じデータを持つセルの個数を配列に代入

23行目の「ReDim RsAry(1 To Rs.Count)」では、変数RsAryの配列サイズを「データ範囲のセル数」にしています。なお、サンプルファイルは37x12の「二次元」ですが、変数RsAryは一次元にしています。
この変数RsAryを処理するのは、27行目の「RsAry(rCnt) = Application.WorksheetFunction.CountIf(Rs, r)」で値を代入する所と、38行目の「LargeNo = Application.WorksheetFunction.Large(RsAry, 1 + currentCnt)」で「Large関数」を使って値を取り出す所、及び40行目の「For Each uniRsAry In RsAry」で配列内の1つ1つを取り出してから順番を計算する所の3か所です。

38行目の「Large関数」も40行目の「For Each~In」も、データが「データ範囲の形の二次元配列」であっても「並び直された一次元配列」でも、データさえ正しく格納されていれば正しく動いてくれます。
ですのでデータを変数RsAryに代入するのに、わざわざFor~Nextを二重にネストして二次元配列に入れなくても、27行目のようにコードの簡単なFor Each~Inを使って一次元配列に代入する方法を採用しました。

25~29行目では、データ範囲の1つ1つのセルについて「データ範囲内に、そのセルと同じ値を持ったセルがいくつあるか」の値を配列RsAryに入れていきます(26行目の「rCnt = rCnt + 1」で1つずつ配列の場所を変更させています)。
27行目で使っているのは「CountIf関数」です。見え消しにしている28行目の「SumProduct関数」も使うことは出来ますが、見て分かるように式が長くなりますし処理時間も変わらかったので、単純な「RsAry(rCnt) = Application.WorksheetFunction.CountIf(Rs, r)」としました。

4-4.条件付き書式の作成

条件付き書式を削除・作成する処理をする間はセルの書式が変更になりますので、画面チラつきが発生し、また処理時間も多く掛かります。ですので31行目の「Application.ScreenUpdating = False」で、処理の間は画面更新を中止させています。
処理終了後の62行目で画面更新を再開しています。

33行目の「Rs.FormatConditions.Delete」で、既存の条件付き書式を削除しています。なお削除範囲は「Rs(今回指定したデータ範囲)」ですので、それ以外の範囲に条件付き書式が存在すれば、それは残ります。
図4-3のように「元の条件付き書式の適用範囲①」に対して「新たな適用範囲②」をDeleteすれば、右側のように②の部分が欠けた条件付き書式範囲①が残ることになります。
条件付き書式の適用先の重なり1
図4-3

一方、図4-4の左側のように「元の条件付き書式の適用範囲①」よりも「広い適用範囲(同じ範囲も含む)②」をDeleteすれば、元の条件付き書式は消去されます。また、Delete範囲が小さい場合は、図4-4の右側のように「真ん中がスッポリ抜けた」条件付き書式が残ります。
条件付き書式の適用先の重なり2
図4-4

「Deleteせずに、上から条件付き書式を重ねる」という方法も考えられますが、新しく設定した条件をすり抜けてしまった場合には、古い条件に合致して「予想外の書式が設定されてしまう」場合がありますので、今回はDeleteしてから新しい設定を行っています。

35行目の「For spCnt = 1 To SPLT」から58行目の「Next spCnt」の間で、繰り返し「条件付き書式を作成」します。「spCnt」はカウンタ変数で、「SPLT」は4行目で設定した条件付き書式の数量です。

36行目の「If currentCnt >= Rs.Count Then Exit For」は、「データの種類より書式の数の方が多い」時に、設定できるところまでで中止するものです。例えば図4-5のように「適用範囲内に2種類しか文字列が無いのに、3種類の書式を設定」しようとした場合には、38行目の「Large関数を使って、配列RsAry内から配列より大きな順番の値を取り出す」ところでエラーが発生してしまいますので、防いでいます。
適用範囲の種類が、書式段数よりも小さい場合
図4-5

4-4-1.個数データを大きい方から取り出し

38行目の「LargeNo = Application.WorksheetFunction.Large(RsAry, 1 + currentCnt)」は、「配列RsAry内から、1番大きな値、次に大きな値、・・・という順に取り出す」ことをしています。値は「LargeNo」に代入されます。
しかし図4-5のように、「配列RsAry内から1番大きな値(12)」を取り出すのは簡単ですが、「次に大きな値(8)」を取り出すのは大変です。というのはLarge関数の構文「Large(配列,順位)」の順位を「2」に設定しても「12」の値が返ってきてしまいます。原因は「配列内を大きい順に並べ、先頭からの『順位』のものを取り出す」というものだからです。

そのため、2番目以降を取り出す際には「一つ前までの数量(currentCnt)」を数えてやる必要があります。それが40~42行目の計算になります。
まず40行目の「For Each uniRsAry In RsAry」で、配列RsAry内の値を全て調べます。取り出した1つ1つの値は「uniRsAry」です。(「For i = 1 to Ubound(RsAry,1)」を使っても良いです。)
41行目の「If uniRsAry = LargeNo Then currentCnt = currentCnt + 1」で、値が38行目で取り出した「〇番目に大きな値(LargeNo)」と同じであれば、変数currentCntを1つ増やしていきます。
currentCntは「1つ前までの大きな値の数」を引き継いでいますので、図4-5のように2番目の大きな値を計算した段階では「1番目に大きな値+2番目に大きな値」が変数currentCntに入ることになります。なお、ここで計算したcurrentCnt値は、1周回って次の36行目で「配列の大きさをオーバーしていないか」のチェックを受け、38行目の「次の大きな値の取り出し」の時に使われます。

なお、似たような機能にFilter関数というものがあります。これを使って「Filter(RsAry, CStr(LargeNo))」とすると同じ数値の配列となるのですが、「Filter関数は部分一致」ですので使えません。例えば「1000,100,10」となった場合、一番多い1000の個数は正しく求められますが、2番目の100の計算には1000も含まれてしまうことになります。

4-4-2.数式の書込み

44~45行目の「With Rs.FormatConditions.Add(Type:=xlExpression, Formula1:="=SUMPRODUCT((" & Rs.Address & "=" & Rs(1).Address(False, False) & ")*1)=" & LargeNo)」で、適用先(Rs)に対して条件付き書式の内「数式部分」を追加(Add)しています。
「Type:=xlExpression」とTypeには「xlExpression(演算)」を指定していますが、Typeに指定できるものは図4-6のように多種あります。
定数内容
xlcellvalue1セルの値
xlexpression2演算
xlColorScale3カラー スケール
xlDataBar4DataBar
xlTop105上から 10 個の値
xlIconSet6アイコン セット
xlUniqueValues8一意の値
xlTextString9テキスト文字列
xlBlanksCondition10空白の条件
xlTimePeriod11期間
xlAboveAverageCondition12平均以上の条件
xlNoBlanksCondition13空白の条件なし
xlerrorscondition16エラー条件
xlnoerrorscondition17エラー条件なし
図4-6

数式(Formula1:=)は、図2-6で示したように「=SUMPRODUCT(($C$4:$AM$15=C4)*1)=138」のように作ります。
「$C$4:$AM$15」の部分は適用範囲(データ指定範囲)です。数式はアドレス形式で表記するため「Rs.Address」とします。
ここでAddressプロパティの5つの引数について説明します。全て省略可の引数です。

構文: セル範囲.Address(RowAbsolute, ColumnAbsolute, ReferenceStyle, External, RelativeTo)
引数値1(既定)値2内容
RowAbsoluteTrueFalse行の絶対参照/相対参照
ColumnAbsoluteTrueFalse列の絶対参照/相対参照
ReferenceStylexlA1xlR1C1A1参照形式/R1C1参照形式
ExternalFalseTrueローカル参照/外部参照
RelativeTo相対参照形式での基準となるRangeオブジェクト
図4-7

なお引数RelativeToは、「RowAbsolute又はColumnAbsolute(又は両方)をFalseに設定」+「ReferenceStyleをxlR1C1に設定」した場合に有効になります。例えば、R[3]C[4]のように「どこかのセル(RelativeTo)を基準にしたセル位置」を指定する場合です。

「Rs.Address」には引数を1つも指定していないため、行・列とも絶対参照($マーク付き)でA1形式、且つ(シート名が入らない)ローカル参照のため「$C$4:$AM$15」のような文字列になります。絶対参照になっていますので、「条件付き書式を左上角セル」用に数式を作り、それを適用範囲全体にCopyしても「参照先が変わらない」ことになります。

次の「Rs(1).Address(False, False)」の中の「Rs(1)」は「左上角セル」を指しています。また「Address(False, False)」は、Addressプロパティの第一・第二引数をFalseにしていますので「行・列とも相対参照($マーク無し)」の「C4」のような文字列になります。
最後尾の「LargeNo」は、38行目で算出した「配列RsAry内から取り出した1番大きな値(2番目の時は、2番目の大きな値)」です。

44~45行目は「SUMPRODUCT」を使った数式の組立ですが、「CountIf」を使った場合は見え消しの47~48行目の数式になります。前述した通り、処理速度の点から今回は「SUMPRODUCT」を使用しています。

4-4-3.書式の書込み

50~54行目は、44~45行目で作成した条件付き書式の数式とのペアである「書式」を設定しています。
50行目の「With Interior」は、セルの背景に対して処理をすることを意味しています。
51行目の「.ThemeColor = xlThemeColorAccent4」は背景色を設定しています。ここでは「ThemeColorプロパティ」を使っているため、図4-8のような「MosThemeColorIndex列挙型」の係数・値を使う必要があります。色は「セルの書式設定」で確認・選択できるものに沿っています。
なお、「XlThemeColor列挙型」の係数・値を使うことも出来ます(マクロ記録で得られるのは、XlThemeColor列挙型のようです)。
背景色一覧
図4-8

また「ThemeColorプロパティ」では無く、代わりに52行目(見え消し部)のような「Colorプロパティ」を使って色を指定することも可能です。Colorプロパティには、RGB関数・カラー定数・XlRgbColor列挙型定数・カラー値が使用できますが、52行目ではRGB関数を使い「RGB(255,192,0)」とすることで「xlThemeColorAccent4」と同色を指定しています。

53行目の「.TintAndShade = (spCnt - 1) * 0.9 / (SPLT - 1)」は、51行目の背景色を元にした「色の明るさ・暗さ」で「出現回数の差」を表すようにしています。「TintAndShadeプロパティ」には「-1(最も暗い)~0(ニュートラル)~+1(最も明るい)」の値をSingle型で与えることになります。TintAndShade値の増減によって、どのような色になるかは図4-8を参照下さい。

今回は定数SPLT値(何段階にするかの値)により可変で色分けをする必要があったので、図4-9のように「最も数の多いもの」をニュートラルとし、2番目・3番目となるごとに明るくする(色としては薄くなる)方法にしました。
色の明るさの設定方法
図4-9

しかし明るさを限界の1までしてしまうと、白になってしまい「書式を設定していないのと見分けがつかない」ので、最大は0.9になるようにし、0と0.9の間を等分して設定することとしました。そのため、53行目のような式になっています。

最後に60行目の「Set Rs = Nothing」で、データ範囲のRangeオブジェクトを解放し、62行目の「Application.ScreenUpdating = True」で画面更新を再開しています。

5.最後に

長年同じようなデータを取り続けていると、その取得方法・分析方法もある程度固定化し定型化・マニュアル化されていくのは、ある程度は効率のためにも大切です。データも自動取得、グラフ化や判断までも自動なんていうシステムもあります。
しかし同じ見方ばかりしていることで、データの持っている大切なメッセージを知らない間に見逃してしまっているかもしれません。
そうならないためにも、様々な解析方法にトライすることは大切だと思います。そして、新たな発見をした時の喜びは何物にも代えがたいもののはずです。

現在のExcelの条件付き書式では、図4-6のように様々な分析方法が選択できます。そのような機能にプラスして今回のようなシステムを使うことで、もし何かの発見につながことがあれば嬉しい限りです。

なお、今回システムで作成した「条件付き書式」は作成するだけで「削除する機能はありません」。条件付き書式が不要になったら、手動で削除をお願いします。

出現回数ごとにデータを色分け(it-054.xlsm)

セキュリティ向上を目的として「インターネット経由でダウンロードしたOfficeファイル(Excel等)のマクロは、既定でブロック」されるようにOfficeアプリケーションの既定動作が変更になりました。(2022年4月より切替開始)
解除の方法については「ダウンロードファイルのブロック解除方法」を参照下さい。