• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:VBA 配列数式的に一括してRangeを扱かえ…)

VBA配列数式的に一括してRangeを扱える方法とオブジェクト変数の取扱いについて

このQ&Aのポイント
  • VBAを使用して配列数式的に一括でRangeを扱う方法や、オブジェクト変数の取扱いについて教えてください。
  • 具体的には、シート関数のIsEmpty関数を配列数式的に一括で使う方法や、オブジェクト変数を配列で宣言し、全ての要素と各要素のobject内に対してNothingを適用する方法について知りたいです。
  • VBEの挙動や、素直な描き方を確認しつつ、VBAにおける配列数式とオブジェクト変数の使い方について詳しく教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.3

こんにちは。 > これってシート関数を評価するもの、 はい。その通りです。 > つまりシート関数そのままですよね? 概ねそうです。 ワークシート関数の配列数式の中でも、 配列のサイズに合わせた大きさの範囲を選択してから、数式を入力し、 範囲全体を纏めてCtrl+Shift+Enterするタイプの配列数式ですので、 単一のセルに適用するタイプの、よく見かける配列数式とは勝手が違います。 戻りが配列ですからVBAにとっては"在リ難イ"存在だと思います。 > VBAオリジナルでは出来ないのですか? 今回の設問に答えるなら、出来ないです。 VBAで直接、配列→配列を扱う関数となると、今思いつくのはFilter関数とかですかね、 殆どまったくといっていい位に用意されていません。 関数名を書く代わりに、ループと条件分岐を書く、という感覚で 私は最近あまり気にしなくなりましたけれども、 それでも、早く片付けたい、とか、文字数を減らしたい、とか、 訳ありな場合には、Excelの機能を活用して楽させて貰うことが多いです。 Visual Basic for Application ですからねー。 Excelの機能を融合的に活用するというのは、考え方によっては王道かも知れない、 とか思うこともあります。 もっとも多く見かけるのは、 Application.Transpose(配列) とかですね。 普通にループした方が処理は"速い"けど、 その場限りの処理なら"早く"片付けられる ということを意識して使い分けたりします。 書く人が少ないけど私が良く使うのでは Application.Text(配列, "書式") も便利です。 使える場面は限定されますけれど、 一応、簡単な条件分岐は出来なくもない(数値→文字列)ですし。 他、連想配列なら簡易的な意味ではCollectionオブジェクトもあります。 外部オブジェクトですけれど、Dictionaryの方が便利でよく使いますが。 そういう意味ではVBAは、"なんでもござれ"ではないですけれど、 拡張性を残しながら、コンパクトによくまたまったツールだと思っています。 やってもやっても、まだ、新しい面白い発見がありますねぃ。 以上です。

Nouble
質問者

お礼

迅速なご対応、痛み入ります。 >Excelの機能を融合的に活用するとい… 全く同感です。 >今回の設問に答えるなら、出… 残念です、 VBAのループも、もしかしたら 並列実行に展開されているのかも知れないですが、 望みは薄そうですよね? シート関数、特に配列数式が早いのは コンパイルコードのせいもあるでしょうが、 並列化の恩恵だと 勝手に思っています。 スペシャルセルズのように、 ループ無しに処理できるものは そのコード単体では 内部的には 並列処理される可能性も あるでしょうが、 ユーザーが書いたコードまで 並列化して貰えるとは、… インタプリタです(ヨネ?)しね、 並列処理前提の環境が 折角定着しているので、 なるだけ並列処理の 恩恵を授かりたく思いました。 甘かったですね。 いや!!、でも、 「Collection」重白いですね。 事前に構造定義して 組み立てて、組み立てて、静的に構築しなくても 構造体が扱えそうに思いました。 最悪、テキスト形式のコードを吐かせて、それをインクルードすることでしか 構想対や構造体名、構造体要素数やメンバー(て、云うんですか?)の変数の型などを 動的に思いのままに扱えないのかな? と、思っていました。 (※注:要素数は 限定的ですが、動的に変えられますね、失礼しました) これは…  ひょっとしたらひょっとしますよね? 目がキラキラです。 仰るとおり、 「やってもやっても、まだ、新しい面白い発見がありますねぃ。」 ですね (※注:「やってもやっても」と、いえる程やっていませんが… 汗) 学ばさせて頂きました、 わくわくが増えました。 有り難うございます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.2

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

Nouble
質問者

お礼

有り難うございます、学ばせて頂きました またどうぞ宜しくお願い致します。 これってシート関数を評価するもの、 つまりシート関数そのままですよね? VBAオリジナルでは出来ないのですか?

全文を見る
すると、全ての回答が全文表示されます。
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.1

こんにちは。 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

Nouble
質問者

お礼

有り難うございます、学ばせて頂きました またどうぞ宜しくお願い致します。

Nouble
質問者

補足

ところで これってシート関数を評価するもの、 つまりシート関数そのままですよね? VBAオリジナルでは出来ないのですか?

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • オブジェクトを配列として扱いたい

    Java(オブジェクト指向)を始めて数日の者です。 LinkedListを利用し、インスタンス化したオブジェクトをListに入れて 扱えるようにしたいと考えています。 具体的には LinkedList<クラス名> array = new LinkedList<クラス名>(); クラス名 object1 = new クラス名(); -object1の処理- array.add(object1); -object1の処理- array.add(object1); -object1の処理- array.add(object1); このようにして、object1を配列で管理するイメージです。 object1の処理結果は、毎度変わっています。 しかしこれですと、最後のobject1の処理の内容がすべてのarray(i)に入ってしまいます。 要は、array(i)は全て、同じobject1を参照しているだけ。 object1の変更結果がarray(i)に入っていくというイメージでは無い、ということでしょうか? また、この他でインスタンス化したものを配列で管理できるような方法がございましたら、ご教授いただけると幸いです。m(_ _)m 動的に配列の要素数を変更(要素が追加)ができるようにしたいのです。

    • ベストアンサー
    • Java
  • ExcelVBAの配列変数で一括でセルに数式を挿入する方法

    ExcelVBAの配列変数で一括でセルに数式を挿入する方法 ExcelVBAでTEST1シートを参照して、TEST2シートに数式を貼り付けたいと思っています。 例えばTEST2シートのA1セルには、TEST1シートのA1を参照する数式 =IF('TEST1'!A1="","",'TEST1'!A1))を挿入、 TEST2シートのA2セルには、TEST1シートのA2を参照する数式 =IF('TEST1'!A2="","",'TEST1'!A2))を挿入、 それをA1セルからZ10セルまで同様に数式を挿入したいと思っています。 以下のように配列変数を用いて、一括で挿入すると数式ではなく、文字が入ってしまいます。 Sheets("TEST2").Cells(1, 1).Resize(10, 26).Formula = SUSHIKI ※SUSHIKI←数式を入れた配列 どのような記述を行えば、数式を貼り付けることができるができるでしょうか。 できればOffsetを使用した形で作成したいです。 どうかご教授お願い致します。

  • VBAの動的配列について

    いつもお世話になっております。 エクセルVBAを学習中の者です。 動的配列についてお伺いします。 添付資料を見て頂きたいのですが、 シート名1~4に同一レイアウトの表があります。 これらの表をを2次元配列に格納し、その後、同一レイアウトのシートに一括転記したいと考えています。 転記の事を考えて、条件としては、 シート1から2行目以降のデータを配列『data』に格納、変数『dataCnt』が転記先の行番号と同じになるように考えています。 当初は、配列の定義を『Dim data(100,3) As Variant』と、多めに要素数を定義して、コードを記述していました。 正直、凄く気持ちが悪い感じでした・・・ 最近、動的配列を学習しまして、 シートごとにデータの行数を変数『lastRow』に格納して、配列を再定義して【データ数=要素数】とならないか? と思い、下記のようなコードを書いてみました。 が、『ReDim Preserve~』で実行エラーが発生してしまいます。 原因がなぜかわかりません! そもそも、動的配列はこのような使い方は出来ないのでしょうか? Sub テスト() Dim data() As Variant Dim x As Long Dim i As Long Dim ii As Long Dim lastRow As Long Dim dataCnt As Long dataCnt = 2 For x = 2 To 5 Worksheets(x).Activate lastRow = Cells(Rows.Count, 1).End(xlUp).Row If x = 2 Then ReDim data(2 To lastRow, 3) Else ReDim Preserve data(2 To dataCnt + lastRow - 1, 3) End If For i = 2 To lastRow For ii = 1 To 3 data(dataCnt, ii) = Cells(i, ii) Next ii dataCnt = dataCnt + 1 Next i Next x End Sub どなたかご指導をよろしくお願いいたします。

  • VBAで配列の要素と、配列外の他の変数との時刻比較

    独学の者です、お願いいたします。 Dim item(1 To 288) As Date  ’ 配列をDate型、各要素は07:05のような時刻データ Dim kunt_d As Date  ’上記配列の各要素と別の時刻データ、Date型 If kunt_d = item(a) Then  ’配列の要素と他の変数とを比較、どちらも時刻データ。 この際、上記の同じDate型ですと動作しません、時刻が一致している場合でも、 条件式はスルーされます。 そこで、配列と比較する別の方は、String型にしてみたところ 動作しました。 このケースで、Date型同士は間違った使い方でしょうか? また、配列と配列外の変数との比較は型の一致は必要無いのでしょうか? よろしくお願いいたします。

  • 配列は何故オブジェクト?

    僕はプログラミング初心者です。 javaの参考書で、配列について記述されていた章にて以下の記述がありました。 「データとそれを操作する機能をひとまとまりにしたものをオブジェクトといいますが、その意味では配列もオブジェクトです」と。 そこで、配列がオブジェクトである理由について、以下の仮説を立ててみました。正しいですか? 配列 ・データを保持する(配列要素を保存する) ・指定されたインデックス(牽引番号)のデータ(配列要素)を渡す 例えば、int [] n ={3,5,7};という配列があったとします。このソースコードにより、配列は箱に入れられヒープに保管されます。これにより、配列はデータを持っていることを意味する。これに int data=n[0];のように配列要素へのアクセスを行うと、配列は自身の持ってるデータ(配列要素) を変数dataに渡します。これは配列は、指定されたインデックス(牽引番号)のデータ(配列要素)を渡す機能を実行している。 つまり、上記から配列はデータとそれを操作する機能を持っており、オブジェクトといえる。

    • ベストアンサー
    • Java
  • VBA オブジェクトが空かどうか判定する

    皆様のお知恵を拝借させてください。 エクセルVBAでオブジェクトを入れる変数を定義し、その変数にオブジェクト が入っているかどうか検査したいのですがどうしたらいいでしょうか。 例えば--- Dim a As Workbook If a <> nothing then ←この部分が分からない。このままだとエラー。 処理 End if --------- 環境 エクセル2003 WinXPsp1

  • エクセルVBAのSETステートメントについて

    マクロを組み込んだエクセルファイルが完成したのですが、ファイルサイズが大きくなってしまった ため、ファイルサイズを軽くするために現在 試行錯誤を繰り返しています。(シート数:50シート) ファイルサイズを軽くするために今までに取り組んできたのは下記の9項目です。 ・数式を値に変換 ・シートイベントプロシージャをThisWorkbookイベントに変換してマクロ構文を簡素化 ・隠れオブジェクトを全て削除(オブジェクト数を最小限・最小サイズに抑える) ・条件付書式、入力規則、名称登録を最小限に抑える ・必要な条件付書式のセル番地には必ず 『 $ 』 を付ける ・Offset 構文を最小限に抑える ・未使用セルの削除(最終セルの位置を正常化) ・Call マクロを多用してマクロ構文の情報量を極力減らす ・型に応じた変数宣言を徹底(バリアント変数扱いを最小限に抑える) ただ、『 型に応じた変数宣言 』 のSETステートメントの正しい使い方について私自身が良く理解 をしていないためにご指導を頂きたく投稿をさせて頂きました。不明なのは下記の2点です。 (1)『 SET a = ○○○○ 』 はオブジェクト型変数に対してのみ使用するものなのでしょうか?   データ型(Date)や文字列型(String)の変数に対してはSETステートメントは使用しないもの   なのでしょうか?仮にデータ型や文字列型変数に対してSETステートメントを使用した場合の   メリットとデメリットについて教えて下さい。もしかして、データ型や文字列型の変数の場合は   ただ単純に 『 SET 』 の文字が省略されているだけなのでしょうか。この基本的な部分の   理解ができていないので、理屈が分からずに困っております。 (2)『 SET a = Nothing 』 の対応はどこまで必要なのでしょうか?   上記(1)の質問にも絡むのですが、メモリリソースを開放してファイルサイズを軽くするためには   『 SET a = Nothing 』 が有効であるという情報がインターネット上に多数掲載されてますが   データ型や文字列型変数に対してもプロシージャの末尾に 『 SET a = Nothing 』 の構文   を付け加えた方がファイルサイズが軽くなるものなのでしょうか?   また、下記マクロ処理の場合にも 『 SET a = Nothing 』 の構文は必要なのでしょうか?        'Shをオブジェクト型変数として宣言     Dim Sh As Worksheet           :           :     '全てのシートに対して以下の処理を実行     For Each Sh In Worksheets            固有のシートに対してではなく全てのシートに           :                      対してマクロを実行する処理においても           :                      末尾に 『 SET a = Nothing 』 の構文を     '次のブックに対しても同様の処理を実行   付け加えた方がファイルサイズが軽くなる     Next Sh                        ものなのでしょうか? とにかく、正攻法でファイルサイズを軽くする方法を探しています。コメントが長くなり過ぎてしまい ましたが、『 SETステートメントの正しい使用方法 』、『 ファイルサイズを軽くするための裏技 』 などについて、ご存知の方がいらっしゃいましたら是非教えて頂けますよう宜しくお願いします。

  • VBAを始めたばかりです。

    VBAを始めたばかりです。 下記でエラー「オブジェクトが必要です」が出ます。 何故ですか。 Sub A_Sample048() Dim mySht1 As Object Dim mySht2 As Worksheet '準備ここまで Set mySht1 = ActiveSheet If mySht1.Type = xlWorksheet Then Set mySht2 = mySht1 MsgBox mySht2.Name Else MsgBox "最前面のシートはワークシートではありません" End If Set mySht1 = Nothing 'オブジェクトの解放 Set mySht2 = Nothing End Sub よろしくお願いします。

  • stdClass Objectを連想配列のように個別に取り出したい。

    $aに連想配列が入っているとして、 print "<pre>";print_r($a);print "</pre>";   ↓ array (  [Return] => array   (    [data] => あいうえお   ) ) このように連想配列の入った変数から データを個別に取るとき このように、配列名を並べると print $a['Return']['data']; ↓ あいうえお と、個別に取り出せますが、 あるデータをprint_rすると、 stdClass Object (  [Return] => stdClass Object   (    [data] => あいうえお   ) ) というふうに"stdClass Object"として出力されてしまいました。 stdClass Objectのデータを個別に取り出したいのですが 連想配列のような記述だとうまく取り出せません。 stdClass Objectのデータはどのようにして個別に取り出すのでしょうか?

    • ベストアンサー
    • PHP
  • VBAの配列について

    初めまして、VBAの配列の入力方法について質問させてください。 大量のデータの処理を高速化するため、配列を使用して以下のVBAを入力しました。 インターネットで調べ、見よう見まねで入力してみたものです…(T_T) 内容は、シート「資料」のC列とシート「Sheet1」のG列の文字列が同じ かつ、シート「資料」のL列から最終列(そのときによって変化します) とシート「Sheet1」のE列の文字列が同じ場合、 シート「資料」のA列~D列及びL列から最終列で文字列の一致したセルを 着色するというものです。 変数「アイス」と「チョコ」にそれぞれシート「資料」のデータと シート「Sheet1」のデータを格納したつもりなのですが、 実行したところ「配列がありません。」というエラーメッセージが 表示されました。 どうやらデータを配列として格納できていないときに表示される エラーメッセージのようなのですが、変数の型を変更してみたり、 配列をアイス(2)にしてみたりと、色々方法を変えて試してみたものの、 処理は成功しませんでした(T_T) 一体何が原因で処理が成功しないのか、どなたかご教授いただけると とても嬉しいです…!よろしくお願いいたします。 ちなみに、配列を使用しない場合の処理は、時間が15分ほどと かなりかかりますが、成功しています。 Application.ScreenUpdating = True Dim アイス, チョコ As Long Dim i As Integer, j As Integer, k As Integer アイス = Sheets("資料").Cells(Rows.Count, 1).End(xlUp).Row チョコ = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row For i = 3 To Sheets("資料").Cells(Rows.Count, 1).End(xlUp).Row For j = 12 To Sheets("資料").Cells(i, 12).End(xlToRight).Column For k = 2 To Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row If アイス(i, 3).Value = チョコ(k, 7).Value And アイス(i, j).Value = チョコ(k, 5).Value Then Sheets("資料").Range("A" & i & ":D" & i).Interior.ColorIndex = 22 アイス(i, j).Interior.ColorIndex = 22 End If Next k Next j Next i

専門家に質問してみよう