VBA_関数から多値を返すには

VBAで関数から多値を返したいときにはどうすればいいのか?についてまとめました。
3
風柳 @furyutei

@yamato_1413 @hoehoe1234 同じ手法で、CollectionやDictionaryにまとめて値を入れるというのもいいかもしれませんね pic.twitter.com/qUQMNHl581

2022-01-16 21:50:08
拡大
風柳 @furyutei

@yamato_1413 @hoehoe1234 以前、引数をkey1, value1, key2, value2, …みたいに指定してDictionaryを初期化するというのは作ったことがあったんですけど gist.github.com/furyutei/6a6d6… 数が少ない場合は SetDict(Dict, key1, key2, …) = Array(value1, value2, …) の方が見通しがよいかもですね

2022-01-16 21:55:38
ほえほえ@スプシマン @hoehoe1234

やまとさんを始め、多くの諸賢のツイをみての実装。プロパティによる手法は風さんからだったような。滝Libらしくシーケンスも対象にしてみました。「なにがしたいのか?」と言うと、VBAでのタプルの実装なんですね。できるだけインテリ、名前が分かる形での。VBAでは、これはクラスの動的生成 pic.twitter.com/FUg1g0X5Ot

2022-01-19 15:03:15
拡大
ほえほえ@スプシマン @hoehoe1234

なんかを使わないと多分無理なんですが、記法と引数のヒントによりかなり使い勝手(ヒントが出る)が良くなることがわかりました。テスト関数はこちらです。 pic.twitter.com/wuHckdE4OE

2022-01-19 15:05:04
拡大
ほえほえ@スプシマン @hoehoe1234

バインドする変数の欠落に対応しています。また、シーケンスの要素数よりもバインドする変数が多い場合はインデックスエラーが出るのですがこれをSIZE_ERRORとして関数仕様に明記しています。

2022-01-19 15:06:43
ほえほえ@スプシマン @hoehoe1234

左辺に「意味のある変数」、右辺に「配列を返す関数」を書くと、右辺の関数仕様を検索すれば arr = path_split() ppath = arr(0) xname = arr(1) ext = arr(2) みたいに書くよりも tkUnpack(ppath, xname, ext) = path_split() と書けるので利便性が高いですし、意味もわかりやすいかな?と思います。

2022-01-19 15:09:24
ほえほえ@スプシマン @hoehoe1234

path_split関数が、親パス、末端パス、拡張子を返すことについてはやはり関数仕様を見るしかありませんが、これはコードを書く場合の話であり、コードを読む場合には逆に記述からpath_splitの返す値が想像できるので可読性は高まる可能性があります。

2022-01-19 15:11:06
ほえほえ@スプシマン @hoehoe1234

実際は、tkUnpack関数のコードを一度自分でみて処理内容を確認しなければわからないので、そのまま見ると謎仕様だと思います。でもソースコードが提供されるのがスクリプト言語の良いところですね。いろいろな記法に挑戦していくものよいかと思います。

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

関数から多値を返すときに、ユーザ定義型が使えればこんなそれで決定なんだけど、ユーザ定義型は第一級の型ではないんだよね。バリアントに入らない、配列も具象型しかだめ、Collection等のデータコンテナにも持てない。これ、どうなるかと言うと関連する関数がすべてユーザ定義型に汚染されちゃうん

2022-01-20 15:24:57
ほえほえ@スプシマン @hoehoe1234

ですよね。関数が A->B->C->D とあって、Aで使ったデータをDで使う場合、バリアントならBとCは型透過にできるんですがユーザ定義型をつかうとそうは行かなくてすべて具象型に縛られてしまいます。ものすごく使いにくい型なんですよね。

2022-01-20 15:26:44
ほえほえ@スプシマン @hoehoe1234

関数xと関数yの間でだけ使うのなら特に問題はありませんが、データコンテナにうまく載せられないデータってあまり意味がないですね。配列もどこまで行っても具象型になって共通関数、ライブラリとかが使えませんし。なので用途は限定してなるべく使わないほうがいいかな?って思います。

2022-01-20 15:28:20