- 締切済み
VBAで2次元配列を使ってセル検索がしたいです。
VBAを使って開発をしています。 セル検索なのですが、検索範囲のセルに対し、 C言語のような配列を作って格納してまず1列検索し、 対象が見つかったらアクションを起こして、 次の行へ移ってまた検索…を繰り返すということが したいです。 しかし範囲指定でRangeを使う場合、 "A1:A12"と指定しなければならないようで、 これでは固定入力になってしまい、"A1:A12"の次に "B1:B12"、"C1:C12"…と検索を続けられなさそうです。 なにかいい方法はないものでしょうか?
- みんなの回答 (9)
- 専門家の回答
みんなの回答
- imogasi
- ベストアンサー率27% (4737/17069)
#7です。#7の一部の主張に反論が出ているので、よければ再反論・再ご教示をください。 >他言語でなじみがあって 多言語(C、VBなどか)が既習で、そこより、エクセルVBAの学習・使用に入るとき、その他言語にとらわれるなといいたい。それらとエクセルVBAは別物と思うからです。 ○エクセルのセルを一旦2次元配列にして使ったほうがよい(便利な)ケースがあれば、簡単なケースなら教えてください。配列化するだけ回りくどいのでは。 >根本的に違いは 違いがあることは、説明される程度のことはわかってます。 >ビジネスモデルに、2次元配列を必要とするかは 「ビジネスモデル」というのは他の特別な大きな意味があります。エクセルVBAを使って仕事(事務)をする場合、というぐらいの意味でしょうが、私は配列化を必要を感じたことはありません。 >上級者向けのVBAの書籍には、2次元配列を詳しく取り上げたものもあります ほとんどVBAの書物は、書店でぱらぱらめくって見て一部購入していますが、出くわしていません。 よければ具体的な書名をあげて見てください。
- Wendy02
- ベストアンサー率57% (3570/6232)
imogashiさん、 >エクセルVBAでセルを扱うことに限ると、2次元配列という発想が出ることがおかしいとおもいます。 その発想が出ること自体は、おかしいことではないと思います。他言語でなじみがあって、応用できるのではないか、と思われる方もいらっしゃるものだと思います。私自身もExcelで2次元配列はよく使います。 ただ、Excel独特な部分を含めて、それなりのテクニックが伴います。1次元配列と比較すると、かなりややこしくなります。ワークシートのRangeオブジェクトと2次元配列の根本的に違いは、片方はオブジェクトで、片方はメモリ空間にあるマトリックス上の値であるということです。一見同じように扱えますが、後者は、ワークシート上のRangeオブジェクトを切り離すことによって、元の位置にあるセルの範囲の加工ができるということです。 ビジネスモデルに、2次元配列を必要とするかは、その人の技術次第でしょうけれども、Excelでは、上級者向けのVBAの書籍には、2次元配列を詳しく取り上げたものもあります。
- imogasi
- ベストアンサー率27% (4737/17069)
エクセルVBAでセルを扱うことに限ると、2次元配列という発想が出ることがおかしいとおもいます。 そもそもエクセルシートが2次元配列的に Cells(i,j) (iは行、jは列)で値などを捕らえられるからです。 ほかにRange(Cells(i,j),Cells(k,l))などの捕らえ方もできますから。 >"A1:A12"と指定しなければならないようで、 これでは固定入力になってしまい、"A1:A12"の次に "B1:B12"、"C1:C12"…と検索を続けられなさそうです。 この真意もよく伝わりませんが、最下行を捉えることができればそれですむことでは? それには3,4種類の方法があります。 その最終行数をdとして For i=1 to d If Cells(i,”A”)=○ Then (処理) Next i のようなパターンで、ほとんどのエクセルVBAのビジネスの処理はまかなえます。 もう少しVBAの解説書を読まれんことを。 i行の範囲は Range(Cells(i,”A”),Cells(i,”J”))のようにも表せます。
- Wendy02
- ベストアンサー率57% (3570/6232)
#5 です。 変数の宣言が抜けていました。 Dim i As Long #1 レスの様子では、タイトルの「二次元配列で検索」という内容ではありませんね。 >"A1:A12"と指定しなければならないようで、 >これでは固定入力になってしまい、"A1:A12"の次に >"B1:B12"、"C1:C12"…と検索を続けられなさそうです。 だから、Range(Cells(x1,y1),Cells(x2,y2)) でもよいけれど、書くのが面倒だから、 For i = 1 To 10 Range("A1:A12").Offset(,i).Value Next i でループするか、 For Each c in Range("A1:F12") If c = "aa" Then Exit For Next c などとしたほうが、便利でしょうね。 アドレスを取るなら、c.Address とすればよいです。
お礼
返信が遅くなりまして大変申し訳ありません。 offsetの使用方法を、調べて確認しました。 大変参考になりました。 本当にありがとうございます。 ※この件につきましては、 Range(Cells(x1,y1),Cells(x2,y2)) で対応させて頂きました。
- Wendy02
- ベストアンサー率57% (3570/6232)
私も、よく、Excelで、2次元配列を使います。 格納するのが楽ということと、やはり検索スピードが速いということです。 サンプル: Sub Test_Array() Dim rngArray As Variant Dim rnum As Long Const KensakuWord As String = "aa" For i = 0 To 5 rngArray = Range("a1", "a12").Offset(, i).Value '二次元配列 rnum = TwoDimSearch(KensakuWord, rngArray) If rnum > 0 Then MsgBox i + 1 & " 列目の" & rnum & " 個目に見つかりました", 64 End If Next i End Sub Private Function TwoDimSearch(KensakuWord As String, BaseArray As Variant) As Long For i = LBound(BaseArray, 1) To UBound(BaseArray, 1) '二次元配列の1次側 If BaseArray(i, 1) = KensakuWord Then TwoDimSearch = i Exit For End If Next i End Function 代わりに、以下のようにしてもよいです。 ただし、rnum は、Variant 型で、 rnum = Application.Match(KensakuWord, rngArray, 0) 見つからなかったときを、 IsError(rnum) で分岐させます。
- hana-hana3
- ベストアンサー率31% (4940/15541)
#3です。ちょっと訂正。 >uboud UBound にしてください。
- hana-hana3
- ベストアンサー率31% (4940/15541)
検索する目的がわかりませんが・・・。 検索するなら、find も使えますし。 Sub a() Dim 範囲 As Variant Dim i As Long Dim j As Long '配列に格納 Set 範囲 = Range("A1:F10") For i = LBound(範囲) To uboud(範囲) For j = LBound(範囲, 2) To uboud(範囲, 2) Debug.Print 範囲(i, j) Next Next 'お手軽なのが Dim c As Variant For Each c In 範囲 Debug.Print c.Value Next 'Range の代わりに For i = 1 To 6 For j = 1 To 10 Debug.Print Cells(i, j) Next Next End Sub
- guruguru2
- ベストアンサー率29% (39/132)
Rangeプロパティ以外にもCellsプロパティもありますよ。 そちらのほうがmarbo30 さんがやりたいことに沿っていると思います。 ・Cells(Row位置,Col位置) Cells(1, 1) は、Range("A1")と同じ位置を示します。 なので、Cellsのインデックスを変数に置き換えて ループすればいいと思います。
- dober-o
- ベストアンサー率59% (260/439)
Cells([rowindex] ,[colomnindex])を使ったらどうでしょう これは変数も使えるので便利です 例えば Range("A1:A12") は Range(Cells(1,1),cells(12,1)) と同じです Cells(i,j) と変数を用いれば 繰り返しルーチンにも使えます
お礼
ありがとうございます。まさにこういう処理を求めていました。 早速活用させて頂きます。 ご解答ありがとうございました。
お礼
私の稚拙な質問に多くの方よりご返信頂き、 大変感謝しております。 私の技術不足により作業が滞っていたため、焦り、 皆様のお知恵をお借りしたのが本質問の発端ですが、 この時点では、掲示板を介して見知らぬ方が、 言葉丁寧に挑発しているようにしか見えません。 > よければ具体的な書名をあげて見てください。 技術力のある方からすれば、些細な質問かも しれませんが、それが元で掲示板上で言い合いに なるのは本意ではありません。 「喧嘩ではない、議論しているだけ」と おっしゃられるかもしれませんが、 正直上記書き込みは、挑発しているだけのように 見えてしまいました。 ※本意でなければ大変申し訳ありません。 お世話になっておきながら大変申し訳ありませんが、 これ以上の議論は辞して頂けないでしょうか。 自分のような技術不足の方が参照したときに 質問のしづらい場所になってしまうようで 心苦しいです。 長文失礼致しました。