インストールレスプログラミング( ´ー`)

VBA , JavaScript , HTAなど 365アプリはインストール必要ですが、仕事に無いケースはほぼないから(・_・;)

配列再び。

Excelシートを配列を用いてデータ処理をする時期をすごしています。

一時ワークシートを作っていろいろするより早さもそうですが,コードもシンプルになっていい。

ただ,一時ワークシートの利点と思っているのが,セルの番地等が一目瞭然である点です。

一時ワークシートを作成し,データ処理をしているところでコードを止めてあげると情報を一望でき,メンテナンスは比較的簡単。

配列は・・・ローカルウィンドウでちくちく見てますが,データ構造がずれたりするとほんと大変ですよね。。

本職でコーディングするわけではないので,仕様はころころ変わりますし,その仕事の大前提がひっくり変えることも多々ありますから,そういう時にこまったことになります。

やはり同じ流れでクラスモジュールに気持ちが向かっていくんだなぁと,苦笑しつつ去年のコードを見返しています。

thomさんからいろいろアドバイスをいただいて,去年は大量のデータを扱うことをしていました。

今年は去年ほどの項目数がないので,配列でちゃちゃっとすませてしまったんですが,それでも60程度の項目はあるのかな,メンテナンスのことを考えると,ちょっと途方にくれます。

自分なら自分のメンテナンスは癖がわかってますからやりやすいですが,他人のコードはどこになにがあるのかがわからないと困ります。

特に配列ですから数値指定のものが多く,とても困る。

リハビリ兼ねてすこしずつクラスモジュールを思い出すことにしました。

f:id:chemiphys:20180212103406p:plain

標準モジュール

Option Explicit

Function GetDataAsArray() As Variant
    GetDataAsArray = Sheets(1).Range("a1").CurrentRegion.value
End Function

Function GetDataAsCollection() As Collection
    Dim arr: arr = GetDataAsArray
    Dim C As Collection: Set C = New Collection
    Dim i, j
    
    For i = LBound(arr, 1) + 1 To UBound(arr, 1)
        
        With New Person
            If C.Count = 0 Then .AdjustArrSize UBound(arr, 2)
            For j = 1 To UBound(arr, 2)
                .LetParameter j, arr(i, j)
            Next
            C.Add .Self
        End With
    Next
    Set GetDataAsCollection = C
End Function

Sub テスト()
    Dim a As Collection: Set a = GetDataAsCollection
    Stop
End Sub

クラスモジュール クラス名 Person

Option Explicit
Private Parameter() As Variant

Property Get 名前() As String
    名前 = Parameter(1)
End Property

Property Get Self() As Object
    Set Self = Me
End Property

Sub LetParameter(paramNo, value)
    If Not Not Parameter Then Else Call AdjustArrSize(100)
    Parameter(paramNo) = value
End Sub

Function GetParameter(paramNo) As Variant
    GetParameter = Parameter(paramNo)
End Function

Sub AdjustArrSize(No As Long)
    ReDim Preserve Parameter(1 To No)
End Sub

昨年度教えてもらったやり方から,現時点ではほぼ変わっていません。
ただ,当時項目数が増えたときにその上限を書き換えにいく必要があり,それがちょっと面倒だなぁと思っていました。
大きめに項目数を見て作ればいい話ですが,Emptyが並んでいると,あまり広くないローカルウィンドウがとても狭く感じるのでデータ項目数に合わせて可変にしたいと思っていました。

その部分をとりあえず付け足して書いてみた。

AdjustArrSizeというのを付け足してRedimしているだけですけどね・・(;´▽`A``

ただし,忘れる前提で話をしているので,それを忘れて実行したときは100項目というかなり大きめの項目数で動きはするように作ってみた。

If Not Not Parameter Then Else Call AdjustArrSize(100)

Not Not ってのがわかっていませんが,いろいろネットを見てたら出てきたので Redimし忘れ対策です。

結果は
f:id:chemiphys:20180212104237p:plain

とりあえず私が望むデータの項目数に応じた構成データ数というのは実現できているようです。スマートな書き方ではないとは思いますが,見た目はとりあえず成った。

そしてクラスモジュールならプロパティ実装部分に重要な項目を集めておけばコードがだいぶ見やすくなると思います。

とても大事な部分ですが,

With New Person
If C.Count = 0 Then .AdjustArrSize UBound(arr, 2)
For j = 1 To UBound(arr, 2)
.LetParameter j, arr(i, j)
Next
C.Add .Self
End With

この部分がどうも理解できていません。

やってることはわかるけどどうしてこう書けるんだ??

記録マクロとかでもよくWithでさくっと書かれているときに戸惑うことはあります。苦手な部分なんでしょうね。

いろいろ試して物にしていこう。