2022-01-18 VBA データ構造を作る部品達(データコンテナ)

4
吉田拳/Excelで、経営は強くなる @sugoi_kaizen

各所で作られた複数各種のExcel表を一つにまとめるのが大変…というご相談はほんっとに多くてそんなケースで「統合」機能や串刺し計算が多用され数字や項目がずれて困ると聞くのですけど根本的に「データベースファースト」にすればすべてSUMIFS・COUNTIFS関数で楽になれるんです。手順が違うんです。

2022-01-10 12:39:07
ほえほえ@スプシマン @hoehoe1234

これはよくわかります。プログラムも同じですね。アプリケーションはデータ構造が命です。機能でなんとかしようとするとぐちゃぐちゃになります。導出元が複雑だとどうしてもそうなりがちだとおもいます。 twitter.com/sugoi_kaizen/s…

2022-01-10 12:56:49
ほえほえ@スプシマン @hoehoe1234

VBAのデータ構造を作る基本アイテム ①配列 ②collection ③辞書 四つ目としてArrayListを追加してもいいかもしれない。 この4つを習得してからアルゴリズムを勉強する必要があります。知識なき工夫は無駄な時間を生みます。

2022-01-15 10:02:21
ほえほえ@スプシマン @hoehoe1234

Stackとキューは②の応用で簡単作れます。ここで「レコード型がない」と「配列が値としてふるまう」という問題が発生します。これにはベストな解決はありませんん。クラスを使う、Enumを使う、要素にCollectionを使うなど目的に応じた工夫が必要になります。

2022-01-15 10:04:41
ほえほえ@スプシマン @hoehoe1234

最も大事なのは配列の理解です。シートとの値の取得と設定、VBAでのワークシート関数の使用、組み込み関数の戻り値。そしてワークシート上での新関数の利用によるフルエントな操作。

2022-01-15 10:06:20
ほえほえ@スプシマン @hoehoe1234

VBAの配列は勉強する価値があります。簡単でいいので配列操作ライブラリを作っておくとストレスが減ります。配列操作ライブラリを作ることは配列のみならずVBAのよりよい理解につながります。配列を操作する関数群を5つぐらい作ってみるとよいでしょう。

2022-01-15 10:08:12
ほえほえ@スプシマン @hoehoe1234

最初は一次元配列について ①配列に要素を追加する ②配列に配列要素を展開して追加する ③配列の要素と配列の要素をマージする ④配列の要素数を取得する ⑤配列の下限を変更する のような共通関数を作ってみるとよいと思います。

2022-01-15 10:11:18
風柳 @furyutei

自分も一年ちょい前に知ったばかりですが gist.github.com/furyutei/7e6b7… わりと便利に使っています twitter.com/eternal_xlsm/s…

2022-01-17 21:43:21
永久新入社員.xlsm @eternal_xlsm

VBAで.NETのArrayListが使えるという耳寄りな情報が…! あんまり使ってる人見たことないけど処理が遅いとかで使われてないのかな🤔

2022-01-17 21:34:07
風柳 @furyutei

@eternal_xlsm 自分もVBAの配列は使い辛く感じていたので、積極的に使いたいのですけれど、ArrayListも ・VBAの配列→ArrayListへの変換は一括ではできない(ループしてやる必要がある) ・環境によっては使えない場合がある?   evergreen-nage.blog.ss-blog.jp/2018-06-16 という問題はあるのですよね…

2022-01-17 21:59:54
ほえほえ@スプシマン @hoehoe1234

VBAでArrayListをあまり使わないのには理由があって、多くの場合はcollectionと配列で十分なんですね。十分である場合は組み込み型をどうしても使いがちになります。組み込み型が特に優れているわけではないんですがどうしてもそうなる傾向があります。

2022-01-17 23:26:09
ほえほえ@スプシマン @hoehoe1234

ArrayList(以下AList)はリストのIFを持つ、内部実装が配列のデータコンテナなんですが、実はVBAの配列と比較するとどちらも ①要素数を取得できる ②n番目を取得できる ③サイズを変更できる ④for eachで回せる という共通点があります。AListでしかできない機能はSortとかですね。

2022-01-17 23:28:33
ほえほえ@スプシマン @hoehoe1234

また、AListはListなので任意の場所の要素を番号指定で削除/追加できたりします。詳しくは「docs ArrayList vba」などで検索してみてください。docsを見ると多くの操作ができることがわかりますが、AListでなければいけないという絶対的な強みはないんですね。

2022-01-17 23:31:47
風柳 @furyutei

@hoehoe1234 では同じく組み込みではないDictionaryとはどうして差がついたのか…慢心(標準の配列は使いづらいしすぐ泣きついてくるだろう)、環境の違い(.NET 3.5がないと動かないだって!?)…

2022-01-17 23:32:58
ほえほえ@スプシマン @hoehoe1234

これは辞書とは対比をなします。次に性能面ですが、以前簡単に調べたところやはり実装が配列なので挿入、削除などについては配列と同じ性能になります。もちろん、挿入/削除が任意の場所でできるので便利なんですけど。要素を最初に追加すると後の要素が移動されます(たしかそうだったはず)。

2022-01-17 23:34:55
ほえほえ@スプシマン @hoehoe1234

となると、辞書などの絶対的な強みがないので、組み込み関数とかシートから取得する配列、新関数等と相性のよい配列でいいのではないか?となるのだと思います。もちろんVBAの配列は少々扱いにくいですが簡単なライブラリを作成することで回避できます。

2022-01-17 23:36:32
ほえほえ@スプシマン @hoehoe1234

なので私も、VBAの基本データコンテナとしては ①配列 ②Collection ③辞書 の3つとしています。Stack、キューは②を使って簡潔に実装できます。もちろん④としてArrayListを付け加えてもよいと思いますし、滝Libでもサポートしています。

2022-01-17 23:37:59
風柳 @furyutei

@hoehoe1234 ArrayList「で、でも!Collectionみたいに要素が増えたら速度が遅くなっていく、なんてことも無いしっ!」 ユーザー「けど、配列のwrapperクラス twitter.com/furyutei/statu… とパフォーマンスは同程度なんでしょ?」 ArrayList「…」

2022-01-17 23:39:18
風柳 @furyutei

@eternal_xlsm やまと @yamato_1413 さんが作られた自作ArrayList gist.github.com/yamato1413/a69… を使ってみるというのも手です

2022-01-17 22:34:05
ほえほえ@スプシマン @hoehoe1234

AListにはもう一つ用途がありまして、これについてはまだいろいろ調査が済んでないのですが、VBSではCollectionが使えないので代わりに使っています。VBAではCreateObjectが基本となりますので、配列、辞書、そしてArrayListが3大データ構造になるように(現時点では)思います。

2022-01-17 23:40:35
風柳 @furyutei

@hoehoe1234 あとはそもそもVBAとの相性があまりよくないですしね(身も蓋もない) ポリモーフィズム使えないのでメソッドに無意味に_2とかついてたり、Sortとかにしても関数を直接渡せない/クラスはモジュールを作る必要があるVBAだと使いづらい、とか…

2022-01-17 23:51:42