テーブル機能を使うなら列名が使いたい

テーブル機能は便利だ。VBAで読むにしてもデータの範囲が決まっているのがありがたい。

今までは「セルが空白になったら」とか 「UsedRangeの範囲外になったら」「印刷範囲外になったら」などの割合あいまいな終了条件を書くことが多かったからだ。テーブル機能を使う場合、列の内容を取得する場合、EnumやConstで定義した列番号でアクセスするのが一般的だ。

しかし、ACCESSやDBでよく使うような列名が使いたい。だってテーブル機能にはヘッダが合って列名があるじゃん!それ使えないんかい!ということで、以前も紹介した集計処理に使用できる Cursorクラスをテーブル用に作成した。

ブレイク処理対応テーブル読み込みクラス

'------------------------------------------------------------------------
' ブレイク処理対応テーブル読み込みクラス
'------------------------------------------------------------------------
Option Explicit

Private LO As ListObject
Private WS As Worksheet
Private lngStartRow As Long
Private lngRow As Long
Private lngLastRow As Long
'------------------------------------------------------
' コンストラクタ
'------------------------------------------------------
Public Sub Init(sheet As Worksheet)
    
    Set WS = sheet
    Set LO = WS.ListObjects(1)
    
    'データの最初の行
    lngStartRow = LO.DataBodyRange(1).Row
    
    'データの最後の行
    lngLastRow = LO.DataBodyRange(LO.DataBodyRange.Count).Row
    
    'カレント行
    lngRow = lngStartRow
    
    SkipHiddenRow

End Sub
'------------------------------------------------------
' 終了判定
'------------------------------------------------------
Property Get Eof() As Boolean
    Eof = (lngRow > lngLastRow Or lngRow < 1)
End Property
'------------------------------------------------------
' 最初の行に移動
'------------------------------------------------------
Sub MoveFirst()
    lngRow = lngStartRow
    SkipHiddenRow
End Sub
'------------------------------------------------------
' 次行取得
'------------------------------------------------------
Sub MoveNext()
    lngRow = lngRow + 1
    SkipHiddenRow
End Sub
'------------------------------------------------------
' セル取得
'------------------------------------------------------
Property Get item(ByVal strCol As String) As Range
    
    Set item = WS.Cells(lngRow, LO.ListColumns(strCol).Range(1).Column)
    
End Property
'------------------------------------------------------
' 非表示行をスキップ
'------------------------------------------------------
Private Sub SkipHiddenRow()
    Do Until Not WS.Rows(lngRow).Hidden Or Me.Eof
        lngRow = lngRow + 1
    Loop
End Sub

Private Sub Class_Terminate()
    Set LO = Nothing
    Set WS = Nothing
End Sub

56行目の LO.ListColumns(strCol).Range(1).Column で列名から列番号に変換をかけている。

テーブルの指定がシートに1つ目固定になっているので適宜修正していただきたい。

非表示行をスキップするようになっているのでそっちも適宜で。

このようなテーブル機能で作成された表を読むこととする。

呼び出し側

Sub 呼び出し側()

    Dim tc As TableCursor
    
    Set tc = New TableCursor
    
    tc.Init Sheet1
    
    Do Until tc.Eof

       Debug.Print tc.item("id").Value
       Debug.Print tc.item("ja").Value
       Debug.Print tc.item("en").Value
        
        tc.MoveNext
    Loop

End Sub

どうだろうか。便利だと思うのだが。

ABOUTこの記事をかいた人

はてなブックマークで驚愕の1600越えを記録した伝説が今明らかに! エクセル方眼紙 四天王の1人(ほぼ最弱)窓の杜大賞2014 大賞受賞! Excelを便利にする250以上の機能を体系化したアドインはこちらです。