【VBAリファレンス】Excel VBAで実現!数値の海を記号の山に〜積み上げグラフ作成の極意

スポンサーリンク

はじめに:なぜ記号の積み上げグラフなのか?

Excelでデータを可視化する際、グラフ機能は強力なツールです。しかし、時として標準のグラフ機能では表現しきれない、あるいはより直感的でユニークな表現が求められることがあります。特に、ある一定の基準で数値を区切り、その区切られた数値を記号の数で表現する「記号の積み上げグラフ」は、データの大小や構成比を視覚的に、かつ直感的に理解させるのに非常に有効です。

例えば、顧客満足度調査の結果を、満足度が高いほど「★」が多く、低いほど「☆」が多く表示されるようなイメージです。あるいは、製品の売上数量を、大きな四角「■」で10個分、小さな四角「□」で1個分として表現することで、一目で売上の規模感を把握できるようにする、といった応用が考えられます。

本記事では、Excel VBAを活用して、このような「数値を記号の積み上げでグラフ化する」方法を、具体的なサンプルコードと共に詳細に解説します。特に、「■は10」「□は1」というルールに基づいた実装に焦点を当て、その考え方から応用までを網羅的にご紹介します。Excelの標準機能だけでは実現が難しい、オリジナリティあふれるデータ可視化の世界へようこそ。

詳細解説:数値を記号に変換するロジック

今回のテーマは、「数値を記号の積み上げでグラフ化する」ことです。具体的には、与えられた数値を「■」と「□」という2種類の記号に変換し、それらをセルに並べて表示することで、グラフのように見せる手法です。

1. 記号と数値の対応ルール

まず、記号と数値の対応ルールを明確にします。
* 「■」:10を表す
* 「□」:1を表す

このルールに基づき、例えば数値が「123」であった場合、以下のように変換されます。
* 100の位:100 ÷ 10 = 10個の「■」
* 10の位:20 ÷ 10 = 2個の「■」
* 1の位:3 ÷ 1 = 3個の「□」

合計すると、「■」が12個、「□」が3個となります。しかし、このままでは「■」が10を表すというルールと整合しません。より正確には、以下のように分解します。

* 数値「123」を、まず「■」で表現できるだけ表現します。
* 123 ÷ 10 = 12 余り 3
* つまり、「■」が12個、「□」が3個となります。

この分解ロジックをVBAで実装していきます。

2. VBAによる数値から記号への変換処理

VBAでこの変換処理を行うには、数値から10の倍数部分と1の数部分を分離する必要があります。
* 10の倍数部分の個数:「■」の個数
* 1の数部分の個数:「□」の個数

これらは、算術演算子の `Int()` 関数(整数部分を取得)と剰余演算子 `Mod` を使うことで簡単に計算できます。

例えば、変数 `num` に数値が入っているとします。
* `Int(num / 10)`:10で割ったときの整数部分。これが「■」の個数になります。
* `num Mod 10`:10で割ったときの余り。これが「□」の個数になります。

この計算結果を元に、指定されたセルに繰り返し処理で「■」や「□」を書き込んでいきます。

3. グラフ表示エリアの設計

グラフを表示するエリアは、Excelのシート上に設けます。一般的には、データが入力されている列の隣や、別の専用シートに配置するのが良いでしょう。

* **データ列**: 元となる数値データが格納されている列。
* **グラフ表示列**: VBAによって生成された記号が格納される列。

例えば、A列に数値データがあり、B列にグラフを表示する場合、B列の各行に、A列の数値に対応する記号が並ぶようにします。

4. VBAコードの全体構成

VBAコードは、主に以下の要素で構成されます。
* **対象範囲の取得**: グラフ化したい数値データが含まれるセル範囲を取得します。
* **ループ処理**: 取得したセル範囲の各セルに対して、以下の処理を繰り返します。
* **数値の取得**: 現在処理しているセルの数値を取得します。
* **記号への変換**: 上記のロジックに基づき、「■」と「□」の個数を計算します。
* **記号の描画**: 計算された個数に応じて、指定されたグラフ表示列のセルに記号を書き込みます。
* **セルのクリア**: グラフ表示列に既に記号が存在する場合、新しいグラフを描画する前にクリアします。

この基本構成を元に、より実用的なコードを作成していきます。

サンプルコード:実装例と解説

それでは、具体的なVBAコードを見ていきましょう。ここでは、A列に数値データがあり、B列に記号グラフを作成する例を示します。

Sub CreateSymbolGraph()

Dim ws As Worksheet
Dim dataRange As Range
Dim dataCell As Range
Dim graphRow As Long
Dim num As Long
Dim numTens As Long ‘ ■ の個数
Dim numOnes As Long ‘ □ の個数
Dim symbolTens As String
Dim symbolOnes As String
Dim outputCell As Range

‘ ★設定項目★
Const TENS_SYMBOL As String = “■” ‘ 10を表す記号
Const ONES_SYMBOL As String = “□” ‘ 1を表す記号
Const GRAPH_COLUMN As String = “B” ‘ グラフを出力する列
Const DATA_COLUMN As String = “A” ‘ 元データがある列
Const START_ROW As Long = 2 ‘ データが始まる行 (ヘッダー行を除く)

‘ ————————————————–
‘ 初期設定
‘ ————————————————–
Set ws = ThisWorkbook.ActiveSheet ‘ アクティブシートを対象とする

‘ データ範囲の設定 (DATA_COLUMNのSTART_ROWから最終行まで)
On Error Resume Next ‘ データがない場合のエラーを回避
Set dataRange = ws.Range(DATA_COLUMN & START_ROW, ws.Cells(ws.Rows.Count, DATA_COLUMN).End(xlUp))
On Error GoTo 0

If dataRange Is Nothing Or dataRange.Cells.Count = 0 Then
MsgBox “データが見つかりませんでした。”, vbExclamation
Exit Sub
End If

‘ ————————————————–
‘ グラフ表示列のクリア
‘ ————————————————–
‘ グラフ表示列の過去のデータをクリア
ws.Range(GRAPH_COLUMN & START_ROW, ws.Cells(ws.Rows.Count, GRAPH_COLUMN)).ClearContents

‘ ————————————————–
‘ 各データに対する記号グラフの作成
‘ ————————————————–
graphRow = START_ROW ‘ グラフ描画開始行

For Each dataCell In dataRange.Cells

‘ ★現在処理しているセルの値を取得★
num = dataCell.Value

‘ 数値が空または0以下の場合はスキップ
If Not IsNumeric(num) Or num <= 0 Then graphRow = graphRow + 1 GoTo NextIteration ' 次のセルへ End If ' ★10の倍数部分と1の数部分を計算★ numTens = Int(num / 10) ' ■ の個数 (10で割った整数部分) numOnes = num Mod 10 ' □ の個数 (10で割った余り) ' ★記号文字列を生成★ symbolTens = String(numTens, TENS_SYMBOL) ' ■ を numTens 個繰り返す symbolOnes = String(numOnes, ONES_SYMBOL) ' □ を numOnes 個繰り返す ' ★グラフ出力セルに記号を書き込む★ Set outputCell = ws.Cells(graphRow, GRAPH_COLUMN) outputCell.Value = symbolTens & symbolOnes ' 2種類の記号を結合して出力 ' 次の行へ graphRow = graphRow + 1 NextIteration: Next dataCell MsgBox "記号グラフの作成が完了しました。", vbInformation End Sub

コードの解説

1. **変数宣言**:
* `ws`: 操作対象のワークシート。
* `dataRange`: 元データが格納されているセル範囲。
* `dataCell`: `dataRange`内の各セルをループするための変数。
* `graphRow`: グラフを描画する行番号を管理します。
* `num`: 現在処理しているセルの数値。
* `numTens`, `numOnes`: それぞれ「■」と「□」の個数を格納します。
* `symbolTens`, `symbolOnes`: 生成される記号の文字列。
* `outputCell`: グラフを出力するセル。

2. **設定項目 (`Const`)**:
* `TENS_SYMBOL`: 10を表す記号(デフォルトは「■」)。
* `ONES_SYMBOL`: 1を表す記号(デフォルトは「□」)。
* `GRAPH_COLUMN`: グラフを作成する列(デフォルトは「B」)。
* `DATA_COLUMN`: 元データがある列(デフォルトは「A」)。
* `START_ROW`: データが開始する行番号(ヘッダー行などを考慮して設定、デフォルトは2)。

3. **初期設定**:
* `Set ws = ThisWorkbook.ActiveSheet`: 現在アクティブなシートを対象とします。必要に応じて `ThisWorkbook.Sheets(“シート名”)` のように特定のシートを指定することも可能です。
* `Set dataRange`: `DATA_COLUMN` の `START_ROW` から、その列の最終データ行までを範囲として取得します。`On Error Resume Next` は、データが全くない場合にエラーで止まるのを防ぐためです。
* データが見つからない場合はメッセージを表示して終了します。

4. **グラフ表示列のクリア**:
* `ws.Range(GRAPH_COLUMN & START_ROW, ws.Cells(ws.Rows.Count, GRAPH_COLUMN)).ClearContents`: グラフを作成する列(`GRAPH_COLUMN`)の `START_ROW` から最終行までをクリアします。これにより、以前実行したグラフが残ったままにならないようにします。

5. **ループ処理 (`For Each dataCell In dataRange.Cells`)**:
* `dataRange` 内の各セル (`dataCell`) に対して処理を繰り返します。
* `graphRow = START_ROW`: ループの開始前に、グラフ描画行を初期化します。
* `num = dataCell.Value`: 現在のセルの数値を取得します。
* **数値チェック**: `If Not IsNumeric(num) Or num <= 0 Then ... GoTo NextIteration`: セルの値が数値でない場合や、0以下の場合はグラフ化せず、次のセルにスキップします。`GoTo` を使ってループの次のイテレーションに直接ジャンプしています。 * **記号個数の計算**: * `numTens = Int(num / 10)`: 10で割った整数部分で「■」の個数を求めます。 * `numOnes = num Mod 10`: 10で割った余りで「□」の個数を求めます。 * **記号文字列の生成**: * `symbolTens = String(numTens, TENS_SYMBOL)`: VBAの `String` 関数は、指定した文字を指定回数繰り返した文字列を生成します。これで「■」を `numTens` 個生成します。 * `symbolOnes = String(numOnes, ONES_SYMBOL)`: 同様に「□」を `numOnes` 個生成します。 * **グラフ出力**: * `Set outputCell = ws.Cells(graphRow, GRAPH_COLUMN)`: 現在描画している行のグラフ出力セルを取得します。 * `outputCell.Value = symbolTens & symbolOnes`: 生成した「■」の文字列と「□」の文字列を結合して、出力セルに書き込みます。 * `graphRow = graphRow + 1`: 次のデータのために行番号を1つ増やします。 6. **完了メッセージ**: * `MsgBox "記号グラフの作成が完了しました。", vbInformation`: 処理が正常に終了したことをユーザーに通知します。 このコードは、基本的な「■は10、□は1」のルールに基づいた記号グラフを作成します。

応用編:より高度なグラフ作成のために

上記のサンプルコードは基本的な実装ですが、さらに応用することで、よりリッチで使いやすいグラフを作成できます。

1. 記号のカスタマイズ

* **異なる記号の使用**: 「■」「□」だけでなく、「★」「☆」「●」「○」など、任意の文字や記号を使用できます。`Const` で定義されている定数を変更するだけで対応可能です。
* **色分け**: VBAでセルの`Font.Color` プロパティを変更することで、記号に色を付けることができます。例えば、「■」を青色、「□」を赤色にするなど、視覚的な情報を増やすことができます。

‘ 例: ■ を青色、□ を赤色にする場合
With outputCell.Font
.Color = RGB(0, 0, 255) ‘ 青色 (Tens Symbol)
End With
‘ □ の色設定 (別途、String関数で生成した部分を個別に色付けするのは複雑になるため、
‘ ここでは簡略化して、 Tens Symbol の色を適用する例とします。
‘ より厳密に分ける場合は、ループ内で1文字ずつセルに書き込むなどの工夫が必要です。)

*注意点*: 上記のコード例では、`outputCell.Value = symbolTens & symbolOnes` のように文字列を結合してから書き込んでいるため、結合後の文字列全体に1つの色しか適用できません。もし、記号ごとに異なる色を付けたい場合は、1文字ずつセルに書き込むか、あるいは `Font.ColorIndex` を使って色を指定するなどの、より複雑な処理が必要になります。

2. グラフの幅と高さの調整

* **列幅の調整**: グラフが横に長くなる場合、グラフ表示列の列幅を狭くすると、よりグラフらしく見えます。`ws.Columns(GRAPH_COLUMN).ColumnWidth = 2` のように設定できます。
* **行の高さ**: 記号が縦に並ぶわけではありませんが、行の高さを標準より低く設定する(例: `ws.Rows(graphRow).RowHeight = 15`)ことで、見た目の密度を調整できます。

3. 閾値による記号の切り替え

「■」と「□」だけでなく、さらに多くの種類の記号や、異なる基準の記号を使いたい場合、`If` 文や `Select Case` 文をネストして、数値の範囲に応じて記号を切り替えるロジックを追加できます。

例えば、
* 100以上:「★」 (100を表す)
* 10~99:「■」 (10を表す)
* 1~9:「□」 (1を表す)

といった具合です。

‘ Select Case を使った例 (上記サンプルコードの numTens, numOnes 計算部分を置き換え)
Dim symbolToUse As String
Dim numToConvert As Long

numToConvert = num ‘ 変換対象の数値

If numToConvert >= 100 Then
‘ 100の倍数部分を処理
numTens = Int(numToConvert / 100)
numOnes = numToConvert Mod 100 ‘ 残りは10と1で処理
symbolToUse = “★” ‘ 100を表す記号
‘ … ここで numOnes をさらに 10と1に分解して処理 …
ElseIf numToConvert >= 10 Then
‘ 10の倍数部分を処理
numTens = Int(numToConvert / 10)
numOnes = numToConvert Mod 10
symbolToUse = “■” ‘ 10を表す記号
Else
‘ 1の数部分のみ
numTens = 0
numOnes = numToConvert
symbolToUse = “□” ‘ 1を表す記号
End If

‘ 生成する記号文字列の組み立ては、元のコードと同様に行う
symbolTens = String(numTens, symbolToUse)
symbolOnes = String(numOnes, ONES_SYMBOL) ‘ ONES_SYMBOL は1を表す記号
outputCell.Value = symbolTens & symbolOnes

4. グラフの動的な更新

データが変更されたときにグラフも自動的に更新されるようにしたい場合は、ワークシートの `Worksheet_Change` イベントプロシージャを利用します。

‘ 標準モジュールではなく、対象シートのモジュールに記述します。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim changedDataColumn As String
Dim graphColumn As String
Dim startRow As Long

‘ ★設定値 (標準モジュールと同じ設定値を使用)★
changedDataColumn = “A” ‘ データが変更される列
graphColumn = “B” ‘ グラフが出力される列
startRow = 2 ‘ データが始まる行

‘ 変更されたセルがデータ範囲内かチェック
If Not Intersect(Target, Me.Columns(changedDataColumn)) Is Nothing Then
‘ 変更されたセルが START_ROW より後かチェック
If Target.Row >= startRow Then
‘ グラフ更新処理を呼び出す (標準モジュールのプロシージャを想定)
‘ Application.Run “ThisWorkbook.CreateSymbolGraph” ‘ 一旦全部作り直す場合
‘ または、変更された行のみを更新する処理を記述
‘ ここでは簡略化のため、変更があったら全体を再描画する例を示します。
‘ 効率を考えると、変更があった行だけを更新する方が良いです。
Application.EnableEvents = False ‘ イベント連鎖を防ぐ
Call CreateSymbolGraph ‘ 作成した標準モジュールのプロシージャを呼び出す
Application.EnableEvents = True
End If
End If
End Sub

この `Worksheet_Change` イベントを使うと、A列のデータが変更された際に自動的にB列のグラフが更新されるようになります。ただし、大量のデータを扱う場合、毎回全体を再描画するのはパフォーマンスに影響する可能性があるため、変更があった行だけを更新するような、より効率的な処理を検討する必要があるかもしれません。

実務アドバイス:活用のヒントと注意点

記号の積み上げグラフは、そのユニークさと直感性から、様々な場面で活用できます。

1. どのような場面で有効か?

* **進捗状況の可視化**: プロジェクトの完了率を「■」で表し、未完了部分を「□」で表すなど。
* **評価・スコアリング**: 顧客満足度、社員のパフォーマンス評価などを、星や記号の数で表現。
* **数量の比較**: 売上数量、在庫数量などを、大量の数値データとしてではなく、記号の数で視覚的に比較。
* **教育・研修資料**: 概念の理解を助けるための、単純化された表現として。
* **プレゼンテーション資料**: 標準グラフでは伝えにくいニュアンスを、印象的に表現するため。

2. 作成時の注意点

* **記号の選択**: 記号は、その意味が直感的に理解できるものを選びましょう。例えば、達成度なら「■」、未達成なら「□」や「△」など。
* **数値の範囲と記号の数**: 表現したい数値の範囲と、使用する記号の数を考慮してください。あまりに数値が大きすぎると、記号がセルからはみ出したり、読みにくくなったりします。必要に応じて、記号の基準値(例: 「■」を100、「□」を10にするなど)を変更したり、複数列に分けて表示したりする工夫が必要です。
* **フォントと文字コード**: 使用する記号が、Excelのフォント設定(特に全角/半角、フォントの種類)によって正しく表示されるか確認が必要です。Unicodeで定義されている記号は、一般的に多くのフォントで表示されますが、環境によっては文字化けする可能性もゼロではありません。
* **パフォーマンス**: 非常に大量のデータ(数千行以上)に対してこの処理を行う場合、VBAの実行に時間がかかることがあります。その場合は、画面更新を停止する `Application.ScreenUpdating = False` をコードの最初に入れ、処理終了後に `Application.ScreenUpdating = True` に戻すことで、実行速度を向上させることができます。
* **代替手段の検討**: もし、より高度なグラフ機能(折れ線グラフ、棒グラフ、円グラフなど)で十分な表現が可能であれば、そちらを優先する方が、データの分析や共有の観点からは一般的に推奨されます。記号グラフは、あくまで「標準グラフでは難しい、あるいはユニークな表現をしたい」場合に有効な手段です。

3. 記号の基準値

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