Worksheetクラスを継承したクラスを作る(4)
Worksheetクラスを継承したクラスを作る(4)
すでに「継承」というのは詐欺同然の題名である。
懲りずに続ける。
Cellsプロパティの実装
実は、数々の挫折にもめげず、着々とメソッド・プロパティの実装は続けているのであった。
Intellisenseの表示をたよりに、なるべく漏れがないように、アルファベット順に実装している。
いよいよみんな大好きCells
プロパティの登場だ!
Cellsプロパティの謎挙動
ご承知のように、Cells
プロパティの引数といえば、
ご覧のようにRowIndex
とColumnIndex
である。
では、次のコードはそれぞれ何を返すだろうか。
?ActiveSheet.Cells(,2).Address '……(1)' ?ActiveSheet.Cells(2).Address '……(2)' ?ActiveSheet.Cells(2,).Address '……(3)' ?ActiveSheet.Cells(0,2).Address '……(4)' ?ActiveSheet.Cells(RowIndex:=2).Address '……(5)'
こいつらを、それぞれイミディエイト・ウインドウで実行すると、
- (1)--->
"$B$1"
が返る - (2)--->
"$B$1"
が返る - (3)--->コンパイルエラー
- (4)--->実行時エラー1004
- (5)--->
"$B$1"
が返る
(1)、(4)はまあ納得。
しかし、(2)がなぜ"$A$2"
でないのかよくわからないし、(3)がなぜ許されないのかよくわからない。(5)に至っては全く以て意味不明。
なんとも不思議な結果であるが、仕方がない。
以上の点を踏まえて、いよいよCells
プロパティを実装する。
Cellsプロパティの実装
クラスモジュールPoweredSheet
のCells
プロパティの部分のみ掲載。
リスト1 クラスモジュール PoweredSheet
Public Property Get Cells( _ Optional ByVal RowIndex As Variant, _ Optional ByVal ColumnIndex As Variant) As Range Dim ret As Range If IsMissing(RowIndex) And _ IsMissing(ColumnIndex) Then '……(6)' Set ret = realSh.Cells GoTo Finalizer End If If IsMissing(RowIndex) Then '……(7)' RowIndex = 1 Set ret = realSh.Cells(RowIndex, ColumnIndex) GoTo Finalizer End If If IsMissing(ColumnIndex) Then '……(8)' Set ret = realSh.Cells(RowIndex) End If Set ret = realSh.Cells(RowIndex, ColumnIndex) '……(9)' Finalizer: Set Cells = ret End Property
(6)の
If IsMissing(RowIndex) And _ IsMissing(ColumnIndex) Then Set ret = realSh.Cells GoTo Finalizer End If
は、引数が両方とも省略されている場合。
このときは、セル範囲全体を返す。
引数を両方ともVariant
にしているのは、省略検知のため。
(7)の
If IsMissing(RowIndex) Then RowIndex = 1 Set ret = realSh.Cells(RowIndex, ColumnIndex) GoTo Finalizer End If
は、引数RowIndex
が省略されたときの処理。
ActiveSheet.Cells(,2).Address
が$B$1
を返すということは、引数RowIndex
だけが省略されたときは、「1行目」と見なされる、ということらしい。だからこうした。
(8)の
If IsMissing(ColumnIndex) Then Set ret = realSh.Cells(RowIndex) End If
は、引数ColumnIndex
だけが省略されたときの処理。
意味不明ながら上の(5)の挙動を再現した。
ここまでで、引数省略パターンは網羅しているので、(9)の
Set ret = realSh.Cells(RowIndex, ColumnIndex)
で普通にCells
プロパティの返り値を取得。
使ってみる
次のコードで実験。
リスト2
Private Sub test04() Dim ps As PoweredSheet Set ps = New PoweredSheet Call ps.init(Sheet1) With ps Debug.Print .Cells.Address Debug.Print .Cells(, 2).Address Debug.Print .Cells(2).Address Debug.Print .Cells(2, 3).Address End With End Sub
こいつを実行すると、
うむ。
おわりに
(6)、(7)、(8)は別になくても良かったような気がする。
書き終わってから気づいた。
と思って、(6)、(7)、(8)をコメントアウトしてリスト2を実行すると、「メモリが不足しています。」というおっそろしいエラーが出て、[デバッグ]をクリックすると、
こんな状態になった。やっぱり(6)、(7)、(8)は要るみたい。
2019/10/5 追記
「Cells
プロパティの引数」とか言っているのはたぶんまちがい。
そこらあたりは、「Worksheetクラスを継承したクラスを作る(5)」で詳しく述べた。いいかげんなことを言って、正直スマンカッタ。