VirtualTableクラスは今

VirtualTableクラスは今

f:id:akashi_keirin:20180401123338p:plain

VirtualTableクラスの現状

VLOOKUPにせよ、INDEX & MATCHの合わせ技にせよ、セルに数式がずらずらと書き込まれているというのはちょっとイヤなので、表引きは極力VBAでやっている。

んで、VLOOKUPみたいな働きを持ったクラスを作ったのが

akashi-keirin.hatenablog.com

このときの試み。

いろいろと使っていくうちに、今こんなふうになっている、というのをうpしておくことにした。

リスト1 クラスモジュール

オブジェクト名は「VirtualTable」。

Option Explicit

Private Type Exception
  Number_ As Integer
  Discription_ As String
End Type

Private Const NUM_NOT_INIT As Integer = 10001
Private Const DISCRIPT_NOT_INIT As String = _
                "VirtualTableクラスのinitメソッド未実行"

'Member Variable'
Private thrownException10001 As Exception

Private isInitialized_ As Boolean
Private tableArray_ As Variant
Private rowsCount_ As Long
Private columnsCount_ As Long

'Accessor'
Public Property Get rowsCount() As Long
  If Not isInitialized_ Then Call catchException(thrownException10001)
  rowsCount = rowsCount_
End Property
Public Property Get columnsCount() As Long
  If Not isInitialized_ Then Call catchException(thrownException10001)
  columnsCount = columnsCount_
End Property
Public Property Get valueOfCell(ByVal rowIndex As Long, _
                                ByVal columnIndex As Long) As Variant
On Error GoTo errorHandler
  If Not isInitialized_ Then Call catchException(thrownException10001)
  valueOfCell = tableArray_(rowIndex, columnIndex)
  Exit Property
errorHandler:
  valueOfCell = False
End Property

'Constructor'
Private Sub Class_Initialize()
  With thrownException10001
    .Number_ = NUM_NOT_INIT
    .Discription_ = DISCRIPT_NOT_INIT
  End With
End Sub

Public Sub init(ByVal targetTableRange As Range)
On Error GoTo errorHandler
  tableArray_ = targetTableRange.Value
  rowsCount_ = UBound(tableArray_, 1)
  columnsCount_ = UBound(tableArray_, 2)
  isInitialized_ = True
  Exit Sub
errorHandler:
End Sub

'Method'
Public Function searchValueVertical( _
                  ByVal searchFor As Variant, _
                  Optional ByVal searchColumn As Long = 1, _
                  Optional ByVal returnValueColumn As Long = 1) As Variant
On Error GoTo errorHandler
  If Not isInitialized_ Then Call catchException(thrownException10001)
  Dim i As Long
  Dim tmp As Variant
  For i = 1 To rowsCount_
    tmp = tableArray_(i, searchColumn)
    If tmp = searchFor Then
      searchValueVertical = tableArray_(i, returnValueColumn)
      Exit Function
    End If
  Next
errorHandler:
  searchValueVertical = False
End Function

Private Sub catchException(ByRef thrownException As Exception)
  With thrownException
    Call Err.Raise(Number:=.Number_, _
                   Description:=.Discription_)
  End With
End Sub

大きく変えたのは、initメソッド未実行のときにエラーを吐くようにしたところですかね。

エラー情報の管理のために無駄に構造体を使ってみたりもしています。

現時点での仕様

プロパティ
rowsCount(Long型)

メンバ変数tableArray_として保持している表(正体は2次元配列)の行数。

columnsCount(Long型)

メンバ変数tableArray_として保持している表(正体は2次元配列)の列数。

valueOfCell(Variant型)

メンバ変数tableArray_として保持している表(正体は2次元配列)のrowIndex行columnIndex列の値。

メソッド
init

式.init(targetTableRange)

引数targetTableRangeには、Range型の表を指定する。

searchValueVertical

式.searchValueVertical(searchFor, [searchColumn], [returnValueColumn])

引数searchForには、検索したい値をVariant型で指定する。

引数searchColumn(省略可)には、検索値を検索する対象の列番号をLong型で指定する。デフォルト値は「1」。

引数returnValueColumn(省略可)には、検索値が見つかったときに、検索値のあった行のどの列の値を返すのかをLong型で指定する。デフォルト値は「1」。

返り値はVariant型。表の指定した列(searchColumn列)の値を上から順に調べ、最初にsearchForとマッチした行の指定した列(returnValueColumn列)の値を返す。

検索値がヒットしなかった場合、または検索時にエラーとなった場合(存在しない列を指定するなど)には、Falseが返る。

おわりに

便利な機能を追加したいけど、アイディアがない。

@akashi_keirin on Twitter