- ベストアンサー
VBA配列数式的に一括してRangeを扱える方法とオブジェクト変数の取扱いについて
- VBAを使用して配列数式的に一括でRangeを扱う方法や、オブジェクト変数の取扱いについて教えてください。
- 具体的には、シート関数のIsEmpty関数を配列数式的に一括で使う方法や、オブジェクト変数を配列で宣言し、全ての要素と各要素のobject内に対してNothingを適用する方法について知りたいです。
- VBEの挙動や、素直な描き方を確認しつつ、VBAにおける配列数式とオブジェクト変数の使い方について詳しく教えてください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 > これってシート関数を評価するもの、 はい。その通りです。 > つまりシート関数そのままですよね? 概ねそうです。 ワークシート関数の配列数式の中でも、 配列のサイズに合わせた大きさの範囲を選択してから、数式を入力し、 範囲全体を纏めてCtrl+Shift+Enterするタイプの配列数式ですので、 単一のセルに適用するタイプの、よく見かける配列数式とは勝手が違います。 戻りが配列ですからVBAにとっては"在リ難イ"存在だと思います。 > VBAオリジナルでは出来ないのですか? 今回の設問に答えるなら、出来ないです。 VBAで直接、配列→配列を扱う関数となると、今思いつくのはFilter関数とかですかね、 殆どまったくといっていい位に用意されていません。 関数名を書く代わりに、ループと条件分岐を書く、という感覚で 私は最近あまり気にしなくなりましたけれども、 それでも、早く片付けたい、とか、文字数を減らしたい、とか、 訳ありな場合には、Excelの機能を活用して楽させて貰うことが多いです。 Visual Basic for Application ですからねー。 Excelの機能を融合的に活用するというのは、考え方によっては王道かも知れない、 とか思うこともあります。 もっとも多く見かけるのは、 Application.Transpose(配列) とかですね。 普通にループした方が処理は"速い"けど、 その場限りの処理なら"早く"片付けられる ということを意識して使い分けたりします。 書く人が少ないけど私が良く使うのでは Application.Text(配列, "書式") も便利です。 使える場面は限定されますけれど、 一応、簡単な条件分岐は出来なくもない(数値→文字列)ですし。 他、連想配列なら簡易的な意味ではCollectionオブジェクトもあります。 外部オブジェクトですけれど、Dictionaryの方が便利でよく使いますが。 そういう意味ではVBAは、"なんでもござれ"ではないですけれど、 拡張性を残しながら、コンパクトによくまたまったツールだと思っています。 やってもやっても、まだ、新しい面白い発見がありますねぃ。 以上です。
その他の回答 (2)
- cj_mover
- ベストアンサー率76% (292/381)
Sub testA2() ' ' "一行コード"的に使うなら Range("B1:B5").Value = Evaluate("INDEX(IF(ISBLANK(A1:A5),""結果1"",""結果2""),0)") Range("C1:G1").Value = Evaluate("TRANSPOSE(IF(ISBLANK(A1:A5),""結果1"",""結果2""))") End Sub
お礼
有り難うございます、学ばせて頂きました またどうぞ宜しくお願い致します。 これってシート関数を評価するもの、 つまりシート関数そのままですよね? VBAオリジナルでは出来ないのですか?
- cj_mover
- ベストアンサー率76% (292/381)
こんにちは。 Sub testA() Dim rtn Dim hoge As String Dim piyo As Range ' ' 二次元 rtn = Evaluate("INDEX(IF(ISBLANK(A1:A5),""結果1"",""結果2""),0)") ' ' 一次元 rtn = Evaluate("TRANSPOSE(IF(ISBLANK(A1:A5),""結果1"",""結果2""))") ' ' 文字列変数を使う場合は hoge = "A1:A5" rtn = Evaluate("INDEX(IF(ISBLANK(" & hoge & "),""結果1"",""結果2""),0)") ' ' range型変数を使う場合は Set piyo = Range("A1:A5") rtn = Evaluate("INDEX(IF(ISBLANK(" & piyo.Address & "),""結果1"",""結果2""),0)") ' ' Evaluate()、引数は文字列式。例示の引数の内容はワークシート関数の配列数式。 ' ' 標準モジュールでは Application. 省略可。 ' ' 他のモジュールで Application. を省略すると Me.Evaluate()の意。 End Sub Sub testO() ' ' 動的配列の場合 Dim obj() As Object ' ' とりあえず、redim ReDim obj(1) ' ' とりあえず、要素格納 Set obj(0) = Cells(1) Set obj(1) = Cells(2) ' ' すべてをNothingにするには ReDim obj(1) ' ' 変数を初期化するには Erase obj ' ' 静的配列の場合 Dim objS(1) As Object ' ' とりあえず、要素格納 Set objS(0) = Cells(1) Set objS(1) = Cells(2) ' ' すべてをNothingにするには Erase objS ' ' Set obj = Nothing は無効です。 End Sub
お礼
有り難うございます、学ばせて頂きました またどうぞ宜しくお願い致します。
補足
ところで これってシート関数を評価するもの、 つまりシート関数そのままですよね? VBAオリジナルでは出来ないのですか?
お礼
迅速なご対応、痛み入ります。 >Excelの機能を融合的に活用するとい… 全く同感です。 >今回の設問に答えるなら、出… 残念です、 VBAのループも、もしかしたら 並列実行に展開されているのかも知れないですが、 望みは薄そうですよね? シート関数、特に配列数式が早いのは コンパイルコードのせいもあるでしょうが、 並列化の恩恵だと 勝手に思っています。 スペシャルセルズのように、 ループ無しに処理できるものは そのコード単体では 内部的には 並列処理される可能性も あるでしょうが、 ユーザーが書いたコードまで 並列化して貰えるとは、… インタプリタです(ヨネ?)しね、 並列処理前提の環境が 折角定着しているので、 なるだけ並列処理の 恩恵を授かりたく思いました。 甘かったですね。 いや!!、でも、 「Collection」重白いですね。 事前に構造定義して 組み立てて、組み立てて、静的に構築しなくても 構造体が扱えそうに思いました。 最悪、テキスト形式のコードを吐かせて、それをインクルードすることでしか 構想対や構造体名、構造体要素数やメンバー(て、云うんですか?)の変数の型などを 動的に思いのままに扱えないのかな? と、思っていました。 (※注:要素数は 限定的ですが、動的に変えられますね、失礼しました) これは… ひょっとしたらひょっとしますよね? 目がキラキラです。 仰るとおり、 「やってもやっても、まだ、新しい面白い発見がありますねぃ。」 ですね (※注:「やってもやっても」と、いえる程やっていませんが… 汗) 学ばさせて頂きました、 わくわくが増えました。 有り難うございます。