和風スパゲティのレシピ

日本語でコーディングするExcelVBA

Dictionaryを新規シートに出力して中身を確認する

Dictionaryは大変便利なオブジェクトなのですが、
ひとつ難点なのが、中身の確認が難しいことです。

ワークシートと違ってすぐに値を見ることができませんし、
ローカルウィンドウでKeyは見れますがItemは見ることができません。


この対策として、「Dictionaryを新規シートに出力する」マクロを用意するのがおすすめです。


ワークシートに書き出せば視覚的にもとても見やすくなりますし、
オートフィルターを付けるだけでソートや検索も使えるようになります。

デバッグ作業のいいお供になりますので、汎用関数に追加してみてください。

目的のプロシージャ概要

今回のプロシージャはテスト・デバッグ用ということで、
イミディエイトウィンドウで実行することが多くなると思います。


イミディエイトウィンドウで以下のコードを実行すると、
画像のような新規ブックを出力してくれるプロシージャを作成します。

Dictionaryの要素を新規シートに出力する, Dic商品リスト

出力したDictionary


またもうひとつの使い方として、Dictionaryの完成時やマクロの終了時に、

Call Dictionaryの要素を新規シートに出力する(Dic商品リスト, "Dic商品リスト")

このコードを書いておき、データのチェックやデバッグに活用することも可能です。
 

開発途中はこれを常に実行するようにしておき、
マクロ完成後の正式運用ではコメントアウトする

ような使い方がおすすめですね。


↑のコードのように第2引数に変数名を渡すと、

変数名付きで出力したDictionary

このように「どの変数のログかわかるシート名が設定される機能」もつけています。

この「どの変数かわかる」系の機能はかなり重宝しますので、
こういったデバッグ用関数には標準搭載しておくと良いと思います。

ソースコード

Sub Dictionaryの要素を新規シートに出力する(出力Dictionary As Dictionary _
                                           , Optional Dictionary名 As String = "Dic")
    
    ' 新規シートを出力してシート名を配列名に
    Dim ws As Worksheet
    Set ws = Workbooks.Add.Worksheets(1)
    ws.Name = Dictionary名
    
    ' 一次元配列→セルの汎用関数を使用した一括出力
    ws.Range("A1") = "Key": ws.Range("B1") = "Item"
    Call 一次元配列をセルに出力する(ws.Range("A2"), 出力Dictionary.Keys)
    Call 一次元配列をセルに出力する(ws.Range("B2"), 出力Dictionary.Items)
    
    ' フィルターを設置
    ws.Rows(1).AutoFilter
    
    ' 全セルをセンタリング
    ws.Cells.HorizontalAlignment = xlCenter

End Sub
    

' 一次元配列 → セル
Sub 一次元配列をセルに出力する(出力始点セル As Range, Arr出力配列 As Variant _
    , Optional is縦方向へ出力 As Boolean = True)

    Dim 要素数 As Long: 要素数 = Count配列の要素数(Arr出力配列)
    If is縦方向へ出力 Then
        出力始点セル.Resize(要素数, 1).Value _
            = GetArray一次元配列→n行1列の二次元配列(Arr出力配列)
    Else
        出力始点セル.Resize(1, 要素数).Value = Arr出力配列
    End If
    
End Sub

' 配列要素数の取得
Function Count配列の要素数(Arr, Optional 次元 = 1) As Long
    Count配列の要素数 = UBound(Arr, 次元) - LBound(Arr, 次元) + 1
End Function

' Transpose上限対応用関数
Function GetArray一次元配列→n行1列の二次元配列(Arr As Variant) As Variant
    
    Dim 生成配列()
    ReDim 生成配列(LBound(Arr) To UBound(Arr), 1 To 1)
    
    Dim i As Long
    For i = LBound(Arr) To UBound(Arr)
        生成配列(i, 1) = Arr(i)
    Next
    
    GetArray一次元配列→n行1列の二次元配列 = 生成配列
    
End Function

コードの解説

メインプロシージャは単純なコードで、
A列にKeysを、B列にItemsをそれぞれ出力するコードです。


この処理は「一次元配列→セル範囲の一括出力」で行いますが、
せっかく汎用関数にするならそれも汎用関数にしておきましょう。

「一次元配列をセルに出力する」という汎用関数を持っておけば、
Splitで作った配列をセルに出力するなどにも便利に活用できます。


なお、「一次元配列→セル範囲」はTRANSPOSE関数を使えば一発なのですが、
TRANSPOSE関数は要素上限が65536件という仕様があります。

こちらに対応するために、一次元配列→二次元配列も汎用関数化しました。


このあたりの解説はこちらの記事をご覧ください。

www.limecode.jp

DictionaryのKey/Itemがオブジェクトの場合

本コードはDictionaryのKey/Itemに数値や文字列を格納している場合のコードとなります。

Dictionaryの中身がオブジェクトでも動く汎用関数については、
こちらの記事をご覧ください。

準備中