VB2005 配列から要素を検索する方法

このQ&Aのポイント
  • VB2005入門者のための、配列から要素を検索する方法について解説します。
  • 配列の中で指定した要素を検索し、一致すれば処理を行うプログラムを組みたい場合の方法を説明します。
  • 具体的なコードとして、VB2005での配列検索の処理方法を紹介します。
回答を見る
  • ベストアンサー

VB2005 配列から要素を検索する方法

VB2005入門者です。 配列の中要素を検索し、一致すれば処理を行うというプログラムを組みたいのですがうまくいきません。 1列目hoge_nameと2列目hoge_noが既に配列に代入してあり 0列目 POINT と1列目hoge_name[AやB]と2列目hoge_no[A00~A03]が一致した場合、3列目のhoge_id(0)からhoge_id(17)に格納したいのです。 hoge.txtは BEBE,A,A00  ,ABC POINT,A,A00  ,ABC POINT,A,A01 ,DEF POINT,B,A02 ,ABC ETC,A,A03   ,GHI POINT,B,A03  ,GHI POINT,A,A03  ,GHI といった感じで、スペースが不特定数混じったカンマ区切りテキストです。 以下で実行すると6行目の3列目でA04を探してしまい、6行目の情報をとってくれません。 hoge_no配列に含まれる文字列から検索し、一致した場合に処理できれば解決するのでは、と思いましたが。Allay.indexOfを試したりしましたがうまくいきませんでした。アドバイス頂きたいのでどなたかよろしくお願いします。 Dim reader1 As New System.IO.StreamReader(geo_name, System.Text.Encoding.Default) Dim i As Long = 0 Dim j As Long Dim answer() As String ReDim answer(0 To 0) Do Until reader1.EndOfStream line = reader1.ReadLine() If (line.Contains("POINT")) Then field = line.Split(",") answer(i) = Trim(field(1)) + "," + (field(2).Trim) + "," + (field(7)) If (field(1).Trim = hoge_name(i) = True And field(2).Trim = hoge_no(i)) = True Then hoge_id(i) = field(7) i = i + 1 ReDim Preserve answer(0 To i) ReDim Preserve hoge_id(0 To i) End If End If Loop For j = 0 To UBound(answer, 1) - 1 reader.Close() Next

  • npupu
  • お礼率68% (41/60)

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

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

hoge_id生成ロジックはこのままでは無理ですね hoge_no(1)のA14で hoge.txtの4行目のPOINT,A ,A14 ,GHIJを使ってしまいます 次のループでReadLIneした際には5行目のPOINT,A ,A15 ,GHIJがLineに読み込まれます したがって hoge_id(2)のA14を見つける事は出来なくなりファイルの最後まで行ってしまいます ご希望のデータの生成をしたいのであれば hoge_noをキーにしてループをまわす方法になりそうです for n=0 to hoge_no.Length -1   Dim reader1 As New System.IO.StreamReader("C:\hoge.txt", System.Text.Encoding.Default)   Do Until reader1.EndOfStream     line = reader1.ReadLine()     If (line.Contains("POINT")) Then       field = line.Split(",")       If ((field(1).Trim = hoge_name(n)) And _         (field(2).Trim = hoge_no(n))) = True Then         hoge_id(i) = field(7)         ReDim Preserve hoge_id(0 To i)         ' Reader1.Close()         Exit do       End If     End If   Loop   Reader1.Close() Next といった具合でしょう

npupu
質問者

お礼

その発想が浮かびませんでした。。。 もう一度頭から読み直すのですね。 本当にありがとうございました!

その他の回答 (2)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

現象の再現できるデータと処理コードを提示いただけませんか? ついでに anserやhoge_idの期待する結果と実際の結果もあるとアドバイスしやすいかと思います

npupu
質問者

補足

ありがとうございます。 再現データを転載します。又期待する結果は以下の通りです。 [配列に格納したい] hoge_id[0]にA11列の “ABCD” hoge_id[1]にA14列の”GHIJ” hoge_id[2]にA14列の”GHIJ” hoge_id[3]にA15列の”GHIJ” hoge_id[4]にA18列の”ABCD” ↓HOGE.TXTの内容↓ POINT,A ,A10 ,ABCD POINT,A ,A11 ,ABCD POINT,A ,A13 ,ABCD POINT,A ,A14 ,GHIJ POINT,A ,A15 ,GHIJ POINT,A ,A16 ,ABCD POINT,A ,A18 ,ABCD AUTH,A ,A11 AUTH,A ,A14 N AUTH,A ,A14 M AUTH,A ,A15 AUTH,A ,A18 ↑ コ コ マ デ ↑ ↓データ↓ Dim reader As New System.IO.StreamReader(“C:\hoge.txt”, System.Text.Encoding.Default) Dim Vmax As Long = 0 Dim line As String Dim field() As String Dim hoge_name(Vmax), hoge_no(Vmax) As String Dim hoge_id(Vmax) As String Dim hoge_noSdel As Short = 0 Do Until reader.EndOfStream line = reader.ReadLine() field = line.Split(",") If field(0) = "AUTH" Then hoge_name(Vmax) = field(1).Trim() hoge_noSdel = field(2).Trim().IndexOf(" ") If hoge_noSdel = -1 <> True Then hoge_no(Vmax) = field(2).Remove(hoge_noSdel) Else hoge_no(Vmax) = field(2).Trim() End If Vmax = Vmax + 1 ReDim Preserve hoge_no(0 To Vmax), hoge_name(0 To Vmax) End If Loop reader.Close() Dim reader1 As New System.IO.StreamReader(“C:\hoge.txt”, System.Text.Encoding.Default) Dim i As Long = 0 Dim j As Long Do Until reader1.EndOfStream line = reader1.ReadLine() If (line.Contains("POINT")) Then field = line.Split(",") If (field(1).Trim = hoge_name(i) = True And field(2).Trim = hoge_no(i)) = True Then hoge_id(i) = field(7) i = i + 1 ReDim Preserve hoge_id(0 To i) End If End If Loop For j = 0 To UBound(hoge_id, 1) - 1 reader.Close() Next AUTH列に[A14NとA14M]が存在しますが、それぞれA14とみなし、且つきちんと14はふたつ存在させたいのです。 どうかよろしくお願いします。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

hoge_nameとhoge_noの中身の設定はどのようになっているのでしょう Dim hoge_name as String() = {"A","A","B","B","A"} Dim hoge_no as String() = {"A00","A01","A02","A03","A03" } ならご希望の処理が可能なように思います

npupu
質問者

補足

見ていただきありがとうございます。 困り果てて、重複するhoge_nameとhoge_noを削除し 配列に入れなおしたら事態が悪化してしまいました。 hoge_name hoge_noはいずれも配列(上限は変動。動的配列というのでしょうか)に {"A","A","B","B","A"}及び{"A00","A01","A02","A03","A03" }と なっております。 どうぞよろしくお願いします。

関連するQ&A

  • VB2005複数のキーワードから

    VB2005入門者です。 カンマ区切りのテキスト"C:\DATA.txt"からキーワード"POINT"と"AA"をもとに 数値 "1" を検出し変数"answer"に格納したい場合 ------------------------------ POINT , AA , 1 , 2 , 3 , 4 POINT , AB , 5 , 6 , 7 , 8 NUM , AA , 9 , 10 , 11 , 12 NUM , AA , 13 , 14 , 15 , 16 POINT , AC , 17 , 18 , 19 , 20 ・'以下続く ・ ・ ------------------------------ 下記に何を加えればよいのでしょうか。 Private Sub Form3_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim reader As New System.IO.StreamReader("C:\DATA.txt", System.Text.Encoding.Default) Dim line As String Dim Field() As String Dim answer As Integer Do Until reader.EndOfStream line = reader.ReadLine() Field = line.Split(",") If Field(0) = "POINT" Then answer = Field(2) End If Loop End Sub ちなみに If Field(0) = "POINT" and Field(1) = "AA" Then ←ではエラーがでました。。。 又、同様のケースで10項目の処理を続けて行い、"answer"にカンマ区切りのまま続けて格納 したい場合はどのようにすればいいのでしょうか。 イメージは最後にexcelに貼り付けていきたいです。

  • VBの配列 IsNull, IsNuthing, ...? 用途がわかりません。

    以下の場合、(1)で範囲エラーとなります。 redim a(0)とすると、a配列に1個データがあるということで、for文が実行されますが。 Redimしないまま(データが無い意味としたいので)で、このFor文をパスするには、どのように記述すればよいのでしょうか? dim a() as string '----->(2) for i=LBound(a) to UBound(a) '---->(1) msgbox(a(i)) next i

  • 配列のSession格納、及び取得方法について

    お世話になります。 現在Visual Studio 2005でプログラム作成中です。 質問内容は、 配列(文字列を格納)をSessionに渡し、次ページでその配列の値を取得できるかという点です。 ***(a.aspx.vb)抜粋*** Dim a() As String Redim a(DataTable1.Rows.Count) For i As Integer 0 to DataTable1.Rows.Count - 1 a(i) = CType(DataTable1.Rows(i).Item(0)) Next Session("a.list") = a(DataTable1.Rows.Count) Session("a.count") = DataTable1.Rows.Count ***(b.aspx)抜粋*** Dim b() As String = CType(Session("a.list"), String) Dim bCount as integer = CType(Session("a.count"),Integer) Dim Name as String For i As Integer 0 To bCount Name = CType(b(i),String) Next としているのですが、取得できません。 配列に格納されたものをSessionに格納し、取得することは可能なのでしょうか。 また、その他に適切なものがあればご教授ください。 よろしくお願いいたします。

  • vb 配列の再検索について

    こんばんは、 vbで悩んでいます。  配列の検索で、みつかったら、行と位置を出力する でた結果の次の行から 再検索する ということをしたいのですが。 一回目の検索はできるのですが、ボタンをおしたら つづいて 検索できるようにしたいのです。 できたら、アドバイス等おねがいいたいします。 Dim i,r,j As Integer Dim a1() As String Dim a2 As String a2 = Text.Text For j = LBound(a1) To UBound(a1) r = r + 1 i = a1(j).IndexOf(a2, 0) Do Until i <> 0 text1.Text = Val(i + 1)  i = a1(j).IndexOf(a2, i + 1) text2.Text = r  text3.Text = a1(j) If i <> 0 Then Exit For End If Loop Next a1に以下の内容があった時 a1(0) = "例1" a1(1) = "例2" a1(2) = "例3" ”例”と検索をかけると、 text1.Textには 1と出力。(位置表す) text2.Textには 1と出力。(行表す) text3.Textには 例1と出力。 exit for でループをぬけているのですが。 これを、検索ボタンを押すたびに、行と位置 が表示されるようにしたいのですが、 アドバイスおねがいします。

  • VB 配列

    今,VBでテキストファイルを読込み配列に入れるという作業を書いたのですが,うまくいきません. 初回例外が発生してしまいます.配列は文字列の配列になります. どなたかご教示のほどよろしくお願いいたします. 'ファイルの読込み Dim path1 As String = "C:\Users\aleph_H.S\Desktop\気象台データインポートツール\気象台データインポートツール\" Dim path2 As String = "気象台データリスト.txt" Dim Mypath As String = path1 + path2 ' StreamReader の新しいインスタンスを生成する Dim cReader As New System.IO.StreamReader(Mypath, System.Text.Encoding.Default) ' 読み込んだ結果をすべて格納するための変数を宣言する Dim stResult As String = String.Empty Dim matrix(,) As String Dim ic As Long = 0 Dim icc As Long = 0 ReDim Preserve matrix(80, 3) ' 読み込みできる文字がなくなるまで繰り返す While (cReader.Peek() >= 0) ' ファイルを 1 行ずつ読み込む Dim stBuffer As String = cReader.ReadLine() ' 読み込んだものを追加で格納する stResult &= stBuffer & System.Environment.NewLine ic = ic + 1 'カンマ区切りで分割して配列に格納する Dim stArrayData As String() = stResult.Split(","c) For Each sstData In stArrayData icc = icc + 1 '文字列をInteger型に変換 matrix(ic - 1, icc - 1) = sstData Next End While cReader.Close()

  • Generic.Listに1次元配列の配列を格納したい(VB2005)

    VB2005の質問です。 変数ghogeにString型の1次元配列の配列を格納したいと考えています。 ----------------------------------------------- 'a) Dim hoge()() As string = _       {New string() {"a1", "b1", "c1"}, _       New string() {"a2", "b2", "c2"}, _       New string() {"a3", "b3", "c3"}} Dim ghoge As New Generic.List(of )   'b) MessageBox.Show(ghoge(1)(1))      ' "b2"と表示したい ----------------------------------------------- 質問内容は、(a)を(b)の初期値として設定するにはどのようにすればよいか、ということです。 (b)がGeneric.ListでなくArrayListの場合だと、   Dim ghoge As New ArrayList(hoge) でhoge配列を格納できますが、Generic.Listの場合はどのような構文にすればよいでしょうか。 現在は、下記のような処理でghogeに値を格納しています。 ------------------------------------------------------------ Dim ghoge As New Generic.List(Of Generic.List(Of String)) Dim aryhoge1 As New Generic.List(Of String)(New String() {"a1", "b1", "c1"}) Dim aryhoge2 As New Generic.List(Of String)(New String() {"a2", "b2", "c2"}) gary_hoge.Add(ary_hoge1) gary_hoge.Add(ary_hoge2) MessageBox.Show(gary_hoge(1)(1))    ' "b2"と表示される ------------------------------------------------------------ どうぞよろしくお願い致します。

  • VB2005 符号を踏まえた降順ソートについて

    いつもお世話になっております。 私はVB2005入門者です。 hoge.txtからカンマ0列目に"ABCD"且つ1行目に"T"がつく行の2,3,4列目を nfMov_x(),nfMov_y(),nfMov_z()に格納しソートを使って 配列内の数値を降順に並び替えて、最大値を求めたいのですが 絶対値に置き換え符号を無視した処理しか出来ませんでした。 ----hoge.txt---- ABCD,A1,10.5 ,8.3 , 9.5 ABCD,A2,11.5 ,7.3 , 6.5 ABCD,T1,42.5 ,-10.3 , 3.2 ABCD,T2,25.2 ,-220.2 , -1.2 ABCD,T3,-35.5 ,210.3 , -15.2 ---------------- 希望する取得値は下記の通りで、T3列210.3ではなくT2列-220.2のように ソート時、符号は無視するが最終的には符号を付けた数値を取得したいのです。 Tmov_x(0) = 42.5 Tmov_y(0) = -220.2 Tmov_z(0) = -15.2 下記をどのように変更すれば良いのかわからないので、どなたか アドバイスや添削をよろしくお願いします。 For n = 0 To 2 Dim reader As New System.IO.StreamReader("C:\hoge.txt", System.Text.Encoding.Default) Dim nfMov_x(), nfMov_y(), nfMov_z() As Single Do Until reader.EndOfStream line = reader.ReadLine() field = line.Split(",") If field(0) = "ABCD" Then If field(1).Trim.Substring(0, 1) = "T" Then Do While field(4).Trim.Substring(0, 1) = "T" ReDim Preserve nfMov_x(T_cont), nfMov_y(T_cont), nfMov_z(T_cont) nfMov_x(T_cont) = field(2) nfMov_x(T_cont) = Math.Abs(nfMov_x(T_cont)) nfMov_y(T_cont) = field(3) nfMov_y(T_cont) = Math.Abs(nfMov_y(T_cont)) nfMov_z(T_cont) = field(4) nfMov_z(T_cont) = Math.Abs(nfMov_z(T_cont)) T_cont += 1 line = reader.ReadLine() field = line.Split(",") Loop ReDim Preserve nfMov_x(T_cont - 1), nfMov_y(T_cont - 1), nfMov_z(T_cont - 1), _ Tmov_x(cont), Tmov_y(cont), Tmov_z(cont) Array.Sort(nfMov_x) Array.Sort(nfMov_y) Array.Sort(nfMov_z) Array.Reverse(nfMov_x) Array.Reverse(nfMov_y) Array.Reverse(nfMov_z) Tmov_x(cont) = nfMov_x(0) Tmov_y(cont) = nfMov_y(0) Tmov_z(cont) = nfMov_z(0) cont += 1 T_cont = 0 ReDim nfMov_x(T_cont), nfMov_y(T_cont), nfMov_z(T_cont) Exit Do End If End If Loop reader.Close() Next

  • 動的配列が存在(要素が有る)か否かを判定できますか?

    VBAで、「For ループが初期化されていません」エラーが発生します。 動的配列が要素0の時に発生するようです。 動的配列の要素が生成された場合だけ、Forループしたいのですが、 どうやって判定すればよいのでしょうか? ------------------------------- Dim 配列() As Integer Dim i As Integer i = 0 If (i < 0) Then ' 本当は真になったり偽になったり ReDim 配列(0 To i) 配列(i) = a + b i = i + 1 End If '' if ★★★ then '' 配列が有るか確認 For Each c In 配列 MsgBox c Next '' end if -------------------------------

  • ArrayListの初期値に二次元配列を設定したい(VB2005)

    下記は、aryhogeにTextBoxオブジェクトを格納する処理です。 ---------------------------------------- 'a) Dim hoge()() As TextBox = _       {New TextBox() {txta01, txtb01, txtc01}, _       New TextBox() {txta02, txtb02, txtc02}, _       New TextBox() {txta03, txtb03, txtc03}} Dim aryhoge As New ArrayList    'b) aryhoge.Add(hoge(0)) aryhoge.Add(hoge(1)) aryhoge.Add(hoge(2)) ---------------------------------------- (a)を(b)の初期値として設定するにはどのようにすればよいか、ということが質問内容です。 試しに(b)の部分を以下のようにしてみましたが、「1次元配列の値を変換できない」とのエラーが出ました。 Dim aryhoge As New ArrayList(New TextBox() {hoge(0), hoge(1), hoge(2)}) どうぞよろしくお願い致します。

  • VBAで、配列のデータをセルに書き戻す方法について

    1000行200列の配列があり、配列の5列目と6列目のデータを、セルの10列目と11列目にすばやく書き戻す方法を教えてください。 (方法1) Dim DATA() As Long ReDim DATA(1 To 1000, 1 To 200) FOR 行番号= 1 TO 1000 CELLS(行番号,10).VALUE = DATA(行番号,5) CELLS(行番号,11).VALUE = DATA(行番号,6) NEXT (方法2) Dim DATA() As Long ReDim DATA(1 To 1000, 1 To 200) Dim WORK1() As Long ReDim WORK1(1 To 1000, 1 To 1) Dim WORK2() As Long ReDim WORK2(1 To 1000, 1 To 1) FOR 行番号= 1 TO 1000 WORK1(行番号,1) = DATA(行番号,5) WORK2(行番号,1) = DATA(行番号,6) NEXT RANGE("J1:J1000").VALUE = WORK1() RANGE("K1:K1000").VALUE = WORK2() (方法1)より(方法2)の方が早いのですが、WORKに貯めるのもめんどうなので、 RANGE("J1:K1000").VALUE = DATA(1,5), DATA(2,5), DATA(3,5),~,DATA(999,6),DATA(1000,6)のようなことができればと思います。 よろしくお願いします。