Excelでデータベース的なアプリケーションを構築している場合,全ての行(レコード)に対して作業を繰り返し行う処理が必要な場合があります。一般的にはRangeやCellsを使って処理することも考えられますが,行数が決まっていない場合や,途中で列を挿入したりして,RangeやCellに対する処理の書き換えが必要になったりします。そこで,列をColumn(コラムあるいはフィールド),行をRow(あるいはレコード)として取り扱いやすいテーブルオブジェクト(ListObject)を用いるのが有効です。
例として,前述の逆ジオコーディングを連続で処理する例を考えます。例えば上表の逆ジオコーディングを処理するとします。
Cells(i,3)~Cells(i,5)でループ処理をすれば簡単な話なのですが,この部分の処理を書いたあとに途中に列を追加したりなどの変更が発生する場合があります。この場合,3や5など列番号を変更するなど修正が面倒です。
メニューの「挿入」からテーブルに変換します。この機能はExcel2003ではリストと呼ばれていた名残で,VBAでのオブジェクト名はListObjectです。
テーブルは,一番上の濃い青が見出し行でVBAではHeaderRowRangeと呼ばれています。データベース的にはフィールド名を記入するところです。
薄い青の縞模様になっている範囲が実際のデータ(データベース的にはレコードを保存する範囲)でVBAではDataBodyRangeと呼ばれます。オプションで最後の行に集計行を設定することもできます。
このテーブルListobjectの処理は以下のようなコードになります。関数ReverseGeoCodeingはこのページと同じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Sub 繰り返し逆ジオコーディングテスト() Dim 緯度 As Single, 経度 As Single, 住所 As String Dim R As Long, Rmax As Long With ActiveSheet.ListObjects(1) '現在のシートのテーブルに関する処理 Rmax = .ListRows.Count 'リストの行数をカウント(見出し,集計行除く) For R = 1 To Rmax 'R行目に対する処理を繰り返す 緯度 = .ListColumns("緯度").DataBodyRange(R) '緯度の列から緯度を取得 経度 = .ListColumns("経度").DataBodyRange(R) '経度の列から経度を取得 住所 = ReverseGeoCoding(緯度, 経度) '住所へ変換 .ListColumns("住所").DataBodyRange(R) = 住所 '住所の列をセルに表示 Next R End With End Sub |
〔6行目〕
シート内の1番目のテーブルを対象としています。通常は1シートに1テーブルとした方が分かりやすいと思います。テーブルに名前をつけてインデックスの代わりに名前を指定することもできます。
〔8~10行目〕
見出し,集計行を除く,すなわちDataBodyRangeの行数を処理の最大行を取得し,1行目から最大行までの全ての行をループの対象とします。
〔12~16行目〕
”緯度”,”経度”というフィールド名をもつ列(ListColumn)のR行目の値をそれぞれ緯度・経度として取得します。この場合,”緯度”,”経度”の列番号が何番でも知らなくても処理できます。
前述の関数で逆ジオコーディング後,住所の列へ記入しています。
(サンプルの緯度・経度はランダムに設定したものです)