- ベストアンサー
【解決方法あり】Visual Basic 2008で複数行の文字列から特定の項目を取得する方法
- Visual Basic 2008を使用して複数行の文字列から特定の項目を取得したい場合のプログラムを組んでいますが、うまくいきません。
- 具体的には、textbox2に複数行の文字列があり、listbox1の中にある項目と一致する行を見つけて、カンマ区切りで取得したいです。
- プログラムを実行すると、うまく結果が得られず、どこが間違っているのかわからず困っています。初心者のため、根本的なミスかもしれませんが、よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
#3で※1のVB6タイプのコード(Split関数を使う)に変更に関して、ヘルプに書かれたようにChar型配列に変換して渡せばvbCrでの文字列分割ではなく、正しくvbCrLfで分割されました。 引数が1つの場合の、ヘルプの記載→String.Split (Char[]) ※Stringクラスから、Char型配列に自動的に変換してくれるだろうと期待していましたが、無理なようです。 元のコードで言えば、下記のようにToCharArrayメソッドを使って渡せば、期待通りvbCrLfで分割してくれて、vbLfが残るような事はありません。 For Each part As String In TextBox2.Text.Split(vbCrLf.ToCharArray) >ということで、listbox1内の2つ目以降の項目が改行+文字列になっているため、含まれていないと判断されていたようです。 私自身が、#3で書いた※1の現象がまさにこのようなデバッグコードが表示されたため、その原因を調べていて、vbLfが文頭に付加されている事に気付きました。 そこから類推するとlistbox1に各アイテムを格納する際に、 For Each part As String In ○○.Split(vbCrLf) Listbox1.Items.Add(part) Next のようなコードで格納しているのだと思います。 であれば、以下のようにChar型配列に変換して渡してやれば、vbCrLfで正しく分割された(vbLfが文頭に存在しない)期待通りの動きをすると思います。 For Each part As String In ○○.Split(vbCrLf.ToCharArray) Listbox1.Items.Add(part) Next
その他の回答 (3)
- BellBell
- ベストアンサー率54% (327/598)
以下のように書き直してみたらどうでしょう? デバッグコードを埋め込んだ以外は、VB6で使用していたような形に書きなおしてみましたってだけです。 '※1 For Each part As String In TextBox2.Text.Split(vbCrLf) For Each part As String In Split(TextBox1.Text, vbCrLf) If (part <> vbNullString) Then For i = ListBox1.Items.Count - 1 To 0 Step -1 '※2 If part.Contains(ListBox1.Items(i)) = True Then If 0 < InStr(part, ListBox1.Items(i)) Then Debug.Print("[" & part & "]中に[" & ListBox1.Items(i) & "]が含まれます") addtag = addtag & "," & ListBox1.Items(i) Else Debug.Print("[" & part & "]中に[" & ListBox1.Items(i) & "]は含まれません") End If Next part = part & addtag TextBox2.Text = TextBox2.Text & part & vbCrLf part = "" addtag = "" End If Next それというのも、先のコードをVB2005で動かした場合に、 TextBox2.Text.Split(vbCrLf) の部分で、なぜかvbCrで分割されるようで、返った配列の要素内にはvbLfが残っている事が判明 ヘルプ等引いても、Char型の配列やString型を引数で受け取る等、連続文字列で問題なく分割できそうな記述がある。 原因不明 VB2005のバグか?と、原因追究は打ち切ってSplitを関数として使った場合、vbLfも含めてきちんと分割される。 それが、※1のように変更した理由 ※2は、先の補足にいただいた情報を元に、Containsに原因があるのだとしたらと、書き直してみたという理由 デバッグコードは原因追究の助けになればと残していますって理由です。
補足
デバッグコードのおかげで何とか原因はわかりました。ありがとうございます。 デバッグの結果です。 [あいうえお]中に[ い]は含まれません [あいうえお]中に[あ]が含まれます [あかさたな]中に[ い]は含まれません [あかさたな]中に[あ]が含まれます [いろはにほ]中に[ い]は含まれません [いろはにほ]中に[あ]は含まれません ということで、listbox1内の2つ目以降の項目が改行+文字列になっているため、含まれていないと判断されていたようです。なるほど、確かにこれだと最初の文字しかまともに判断してくれませんね。 この改行ですが、取り除く方法をいくつか試してみましたが取れませんでした。 新しい問題になってしまいますが、これはどうにかならないでしょうか?
- BellBell
- ベストアンサー率54% (327/598)
#1で実際に動かして確認したのは、VB2005です。 C++の関係で、VB2008インストールしたくないんで。。。 あやしいのは、 If part.Contains(ListBox1.Items(i)) = True Then ですね。 If part.Contains(ListBox1.Items(i)) Then に変えても、同じですかね? 二文字目以降の場合に検索に失敗している可能性を考えて、 Contains の関数仕様が変わったのかも知れない、と疑いましたが。 ※検索してもうまく情報が取れないので、外している可能性大ですが。
補足
= Trueをはずして試してみましたが、やっぱり一緒でした。 今いくつかのパターンを試してみましたが、 listbox1の項目が1つの場合はうまくいきました。 また、listbox1の項目を あ か にした場合、textbox2の2行目の抽出に失敗しました。 確かにおっしゃるように、listbox2の2つ目の項目以降の処理がうまくいってないようです。
- BellBell
- ベストアンサー率54% (327/598)
とりあえずコードの解析が面倒なんで、そのままコードを貼りつけて試してみたら、うまく動きましたよ。 何がうまく動かないんでしょう? あえて言えば、テキストボックス(2,3両方とも)を配置したあと、プロパティからMultiLineをTrueに変更したぐらい。 『あいうえお,い,あ』のように、『い』と『あ』が逆順に並ぶのは、逆順から検索しているから仕様ですよね。 どのように動いてほしくて、どのようにうまく動かないんでしょう?
補足
早速の連絡ありがとうございます。 上記の例で言うと、textbox3に あいうえお,あ あかさたな,あ いろはにほ,い という文字列が返されてしまい、1行目の処理だけがうまくいきません。望む結果は あいうえお,い,あ あかさたな,あ いろはにほ,い という結果です。 うまくいかない理由がわからないのですが、単体のプログラムでは試していませんでした。 そうすると、問題はここの記述以外のところにある可能性が高いと考えていいんでしょうか?
お礼
listbox1への格納がまさにおっしゃる通りになっていたため、アドバイスの通り.ToCharArrayを加えたところ、改行コードがうまく処理できました。 おかげで問題が解決しました。細やかなアドバイスありがとうございます!