- ベストアンサー
配列内の検索方法
こんにちは 以下のような配列aの一列目の中に104という数字(文字?)があるかどうか検索したいのですが、最速検索方法を教えていただけませんでしょうか。ある場合は、行数を返すようお願いします。 一個一個調べてると、日が暮れそうなくらいのデータがあります。。。 1行目は昇順に並んでいます。 よろしくお願いします。 --------------------------------- Dim a(1 To 5, 1 To 2) As Variant a(1, 1) = 101 a(2, 1) = 102 a(3, 1) = 103 a(4, 1) = 104 a(5, 1) = 105 a(1, 2) = "a" a(2, 2) = "b" a(3, 2) = "c" a(4, 2) = "d" a(5, 2) = "e" ----- エクセル2003
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 Excelの場合は、Range からいれるものだと思いますが、そのすべてを配列にいれるのではなくて、列を指定して、一次配列してしまって調べたほうが良いような気がします。理由は、ソートされている条件は不要ですが、1次元にするために、Transpose 関数は、Excel2003 の場合は、制限があったはずです。いずれにしろ、Index にしても、切り出し関数を使うよりは、列そのものを取得したほうが楽です。 '------------------------------------------- Sub Test1() Dim a(1 To 5, 1 To 2) As Variant Dim b As Variant Dim sFind As Variant Dim i As Long Dim j As Variant '--------------------- '検索語 sFind = "104" '--------------------- If IsNumeric(sFind) Then sFind = CLng(sFind) ''数字と数値の違いをチェック a(1, 1) = 101 a(2, 1) = 102 a(3, 1) = 103 a(4, 1) = 104 a(5, 1) = 105 a(1, 2) = "a" a(2, 2) = "b" a(3, 2) = "c" a(4, 2) = "d" a(5, 2) = "e" For i = LBound(a, 2) To UBound(a, 2) b = Application.Index(a, 0, i) '縦の切り出し j = Application.Match(sFind, b, 0) If IsNumeric(j) Then Exit For Next If IsNumeric(j) Then MsgBox j & ":" & i Else MsgBox "Not Found", vbExclamation End If End Sub
その他の回答 (2)
- chie65536(@chie65535)
- ベストアンサー率44% (8741/19839)
「ソートされている」と言う前提なら、以下のように処理出来ます。 まず、先頭、最後、真ん中の位置を示す変数を用意する。 そして、以下の1.~10.の処理を行う。 1.最初は、先頭変数=配列の先頭、最後変数=配列の最後、にセットする。 2.真ん中変数の値を「先頭変数と最後変数の真ん中」にする。 3.「探す値<先頭変数で示す配列の中身」であれば「見付からない」として終了。 4.「探す値=先頭変数で示す配列の中身」であれば「先頭変数が示す位置が見付かった位置」として終了。 5.「探す値>最後変数で示す配列の中身」であれば「見付からない」として終了。 6.「探す値=最後変数で示す配列の中身」であれば「最後変数が示す位置が見付かった位置」として終了。 7.「探す値=真ん中変数で示す配列の中身」であれば「真ん中変数が示す位置が見付かった位置」として終了。 8.「探す値<真ん中変数で示す配列の中身」であれば「真ん中変数-1」の値を、最後変数に入れ2.から繰り返し。 9.「探す値>真ん中変数で示す配列の中身」であれば「真ん中変数+1」の値を、先頭変数に入れ2.から繰り返し。 10.「上記3.~9.のどれでもない場合」は有り得ないので、エラー表示してプログラム終了(この処理には来ない筈) a(1, 1) = 101 a(2, 1) = 102 a(3, 1) = 103 a(4, 1) = 104 a(5, 1) = 105 の状態で104を探す場合は、以下のようになります。 1.最初は、先頭変数=配列の先頭、最後変数=配列の最後、にセットしておく。 a(1, 1) = 101←先頭変数。値は1。 a(2, 1) = 102 a(3, 1) = 103 a(4, 1) = 104 a(5, 1) = 105←最後変数。値は5。 2.真ん中変数の値を「先頭変数と最後変数の真ん中」にする。 a(1, 1) = 101←先頭変数。値は1。 a(2, 1) = 102 a(3, 1) = 103←真ん中変数。値は3。 a(4, 1) = 104 a(5, 1) = 105←最後変数。値は5。 3.「探す値<先頭変数で示す配列の中身」であれば「見付からない」として終了。 成り立たないので次。 4.「探す値=先頭変数で示す配列の中身」であれば「先頭変数が示す位置が見付かった位置」として終了。 成り立たないので次。 5.「探す値>最後変数で示す配列の中身」であれば「見付からない」として終了。 成り立たないので次。 6.「探す値=最後変数で示す配列の中身」であれば「最後変数が示す位置が見付かった位置」として終了。 成り立たないので次。 7.「探す値=真ん中変数で示す配列の中身」であれば「真ん中変数が示す位置が見付かった位置」として終了。 成り立たないので次。 8.「探す値<真ん中変数で示す配列の中身」であれば「真ん中変数-1」の値を、最後変数に入れ2.から繰り返し。 成り立たないので次。 9.「探す値>真ん中変数で示す配列の中身」であれば「真ん中変数+1」の値を、先頭変数に入れ2.から繰り返し。 成り立つので a(1, 1) = 101 a(2, 1) = 102 a(3, 1) = 103←真ん中変数。値は3。 a(4, 1) = 104←先頭変数。値は4。 a(5, 1) = 105←最後変数。値は5。 にしてから2.に戻る。 2.真ん中変数の値を「先頭変数と最後変数の真ん中」にする。 a(1, 1) = 101 a(2, 1) = 102 a(3, 1) = 103 a(4, 1) = 104←先頭変数。値は4。←真ん中変数。値は4(4と5の真ん中は4でも5でも可) a(5, 1) = 105←最後変数。値は5。 3.「探す値<先頭変数で示す配列の中身」であれば「見付からない」として終了。 成り立たないので次。 4.「探す値=先頭変数で示す配列の中身」であれば「先頭変数が示す位置が見付かった位置」として終了。 成り立つので、「先頭変数の値4」を見付かった位置として終了。
お礼
丁寧な解説ありがとうございます。 よく分かりました。
- watabe007
- ベストアンサー率62% (476/760)
For i = 1 To UBound(a) If a(i, 1) = "104" Then MsgBox i & "行目" Exit For End If Next
お礼
それだと10億回くらい計算しないといけなくなるので、 もっと早い方法を探しています。
お礼
エクセルらしい回答、ありがとうございます。 参考にさせていただきます。