前回はExcel VBAエキスパートスタンダードのSortについて勉強しました。
前回までの記事はこちら
今回は7章のTableの操作についてレポートしていきます。なお少し内容が多いので何回かに分けることにします。
なお理解が間違っているところもあるかもしれませんがわからない人と同じ視点に立てるのは今しかないので細かいところはご容赦ください。
間違えに気づいたら修正していきます(笑)。
<今回の目的>
Tableのデータ取得について理解する
-
8章を精読する
-
Tableの構造とテーブル内のオブジェクト取得の仕方をわかりやすく説明する
結論
いきなりですが結論です。
テーブルを取得するListObjectには大きく4つのオブジェクトと2つのコレクションが存在する
次から詳しく説明します。
テーブル化のメリットって?
テーブル化のメリットって何だろうと思いまずはサイトを調べてみましたが以下の2つのサイトにはとても詳しく書かれていました。
エクセルVBAでテーブル操作~そのメリットと変換方法&ListObjectの取得
いつも隣にITのお仕事 https://tonari-it.com/excel-vba-table-listobject/
VBA史上最強の一冊といわれるパーフェクトVBAを書かれている高橋宣成さんのサイトです。書籍もブログもすごくわかりやすくていつも参考にさせていただいています。
Excelテーブル(ListObject)化のススメと 良く使うListObject メンバ一覧
Qiita joojiさん https://qiita.com/jooji/items/8bedb307a68154c4b0df
エンジニアリングに関する知識を記録・共有するためのサービスQiitaでjoojiさんが書かれている内容です。非常に初心者向けにわかりやすく書いてくださっています。
詳細はお二人のブログの方が詳しいのでこちらでは割愛しますが使ってみた感想としては以下でした。
1 テーブル内の部位の取得が容易
見出し行や集計行、列などの取得のプロパティが多く用意されているとともに最終行の取得も容易です(詳しくは後述します)
2 データが増えた場合の対応も容易
途中で列や行が追加された場合でもテーブルとしての構造は維持する為同様の操作が可能です。
ただこれらを実現する為には部位の取得が容易にできなくてはなりません。その為次にテーブルのオブジェクト構造について説明します。
テーブルのオブジェクト構造
オブジェクトブラウザーで覗くとListObject配下は以下の構造になっていることが分かります。
ListObjectがテーブルを表すオブジェクトです。
Rangeがテーブル内のすべてのデータを表すオブジェクトです。
DataBodyRangeがテーブル内のデータ部分を表すオブジェクトです。
HeaderRowRangeがテーブル内の見出し行を表すオブジェクトです。
TotalsRowRangeがテーブル内の集計行を表すオブジェクトです。
別に以下のコレクションが存在します。
ListColumnsがテーブル内の列の集まりを表すコレクションです。
ListRowsがテーブル内の行の集まりを表すコレクションです。
図に表すと以下のようになります。
今回はListObjectと配下にある4つのオブジェクトの取得について説明します(2つのコレクションを別にした理由は次回説明します)。
それぞれの取得方法について説明します。
テーブルを取得する
テーブル内のセル.ListObject
テーブルの中の一つのセルに対しListObjectプロパティを設定することでテーブルを取得できます。
ただしこれだけではテーブルを取得しただけなので中のデータを取得するには追加のコードが必要になります。
以下はテーブルの取得方法です。
Sub test()
Dim ListObject1 As Object
Set ListObject1 = Range("A1").ListObject
End Sub
テーブル内の全データの取得
Range(“A1”).ListObject.RangeでRangeオブジェクトとして取得します。
以下は全体のアドレスと特定セルのアドレスの取得方法です。For Eachステートメントも使用しています。
Sub Sample1()
'テーブル全体のアドレスの取得
Dim adr1 As String
adr1 = Range("A1").ListObject.Range.Address
MsgBox adr1
'特定セルのアドレスの取得
Dim adr2 As String
adr2 = Range("A1").ListObject.Range(3).Address
MsgBox adr2
'For Each~Nextでループを回す
Dim rng As Range
For Each rng In Range("A1").ListObject.Range
MsgBox rng.Address
Next
End Sub
Addressプロパティでセルのアドレスを取得します。
Range(“A1”).ListObject.Range(インデックス番号)で特定のセルの取得が可能です。
テーブル内のデータ部分の取得
Range(“A1”).ListObject.DataBodyRangeでRangeオブジェクトとして取得します。
以下は全体のアドレスと特定セルのアドレスの取得方法です。
Sub Sample2()
'テーブル内のデータ部分のアドレスの取得
Dim adr1 As String
adr1 = Range("A1").ListObject.DataBodyRange.Address
MsgBox adr1
'特定セルのアドレスの取得
Dim adr2 As String
adr2 = Range("A1").ListObject.DataBodyRange(3).Address
MsgBox adr2
'For Each~Nextでループを回す
Dim rng As Range
For Each rng In Range("A1").ListObject.DataBodyRange
MsgBox rng.Address
Next
End Sub
Range(“A1”).ListObject.DataBodyRange(インデックス番号)で特定のセルの取得が可能です。
テーブル内の見出し行の取得
Range(“A1”).ListObject.HeaderRowRangeでRangeオブジェクトとして取得します。
以下は全体のアドレスと特定セルのアドレスの取得方法です。
Sub Sample3()
'テーブル内のヘッダー部分のアドレスの取得
Dim adr1 As String
adr1 = Range("A1").ListObject.HeaderRowRange.Address
MsgBox adr1
'特定セルのアドレスの取得
Dim adr2 As String
adr2 = Range("A1").ListObject.HeaderRowRange(3).Address
MsgBox adr2
'For Each~Nextでループを回す
Dim rng As Range
For Each rng In Range("A1").ListObject.HeaderRowRange
MsgBox rng.Address
Next
End Sub
Range(“A1”).ListObject.HeaderRowRange(インデックス番号)で特定のセルの取得が可能です。
テーブル内の集計行の取得
Range(“A1”).ListObject.TotalsRowRangeでRangeオブジェクトとして取得します。
以下は全体のアドレスと特定セルのアドレスの取得方法です。
Sub Sample4()
'テーブル内の集計部分のアドレスの取得
Dim adr1 As String
adr1 = Range("A1").ListObject.TotalsRowRange.Address
MsgBox adr1
'特定セルのアドレスの取得
Dim adr2 As String
adr2 = Range("A1").ListObject.TotalsRowRange(3).Address
MsgBox adr2
'For Each~Nextでループを回す
Dim rng As Range
For Each rng In Range("A1").ListObject.TotalsRowRange
MsgBox rng.Address
Next
End Sub
Range(“A1”).ListObject.TotalsRowRange(インデックス番号)で特定のセルの取得が可能です。
ここでのまとめ
テーブルを取得するListObjectには大きく4つのオブジェクトと2つのコレクションが存在します。
今回は4つのオブジェクトの取得の仕方を勉強しましたので次回は2つのコレクションを勉強します。
コメント