lycheejam's tech log

チラ裏のメモ帳 | プログラミングは苦手、インフラが得意なつもり。

Excel VBAでデータ高速読み込み&書き込み(パターン2)

Excel VBAでデータ高速読み込み&書き込み(パターン2)

パターン2です。

前回のパターン1の応用です。
パターン1はこちら
kitigai.hatenablog.com

処理の概要

前回はデータ数を最初に調べて2次元配列を宣言しましたが
今回は条件でデータを抽出するため最終的なデータ数が不明です。

1.データ読み込んで条件にヒットするか調べる。
2.データが条件にヒットしたら2次元配列を再宣言して要素数を増やす。
3.1と2をどんどん繰り返す。
4.行列入れ替え処理
5.一括転記
ざっとこんな感じっす

今回の読み込み処理はグルーピング処理の過程でできたものなので
抽出条件に当てはまるたびに再宣言しているため
無駄っちゃ無駄です。でも、そこら辺の巷にあふれてるVBAプログラムよりは早いです。

仕様等で数値が決まってる場合は動的2次元配列は使わなくてもいいかもね

2次元配列の再宣言

データが抽出された場合に2次元配列を再宣言して格納できるデータ数を増やしていきます。

ReDim Preserve dataArry(COLUMN_MAX1, dataCnt)
ReDim crossArry(dataCnt, colMax)

配列のデータを保持したまま再宣言する場合はReDim Preserveを使用します。
ReDimだけの場合は配列が作り直される感じ
Preserve使うと今の配列につぎ足す感じ

ここで注意点としてPreserveを使用する場合は列数の再定義しかできません。
その為、再宣言時には行を指定する部分は定数ではないといけません

逆にReDimのみの場合は再定義しているので変数でかまいません

今回の処理の場合はそのままExcelシートの行列が入れ替わった配列があると考えればおk

行列の入れ替え

単純にdataArryをシートに一括転記すると行列が入れ替わったものが転記されます。
行列を入れ替える方法で一番簡単なのがExcelの標準関数であるTranspose関数を使用する方法

crossArry = WorksheetFunction.Transpose(dataArry)

処理も別に遅いわけでもないですしこれでも全然問題ないんですが
扱える最大値の制約があります。
今回はExcelのシートで言う列(フィールド)方向に配列を伸ばしていったわけですが
これ!って公式のドキュメントがなかったんであれですけど
Excel 2007の最大行数65535行時代に関数が作られたから65536行以上だと
エラーになる感じだ~って感じっす。
一応境界値テストもしました。

じゃけん配列そんぐりそのままforでぐるぐる回しましょうね~って感じっす。

    '一括転記した場合行列が逆で転記されてしまうため入れ替える
    ReDim crossArry(dataCnt, colMax)
    '行列入れ替え
    For j = 0 To colMax
        For i = 0 To dataCnt
            crossArry(i, j) = dataArry(j, i)
        Next i
    Next j

crossArryの添え字とdataArryの添え字が逆になってるからね?
そんな解説いらないよね?

雑感

いざ解説っつーかこんな考えとかこんな問題があってこうしたんだよって
書いてみようとしたら文章かちゃかちゃになるのな

書いてて読みずらいだろうなって思うけど
自宅PCにOfficeないから再現画像がないんじゃ~