初めて質問させていただきます。
VB初心者です。
ソートされた文字列の書き込まれたファイルを読み、
(文字列は、
”000”
”001”
”001”
”001”
”002”
”002”
”003”
といったように書き込まれています。)
そこから、3つ連続して並んでいる文字列を探し出して、
その文字列と、3つ連続していた文字列がいくつあったのか表示するプログラムを作りたいのですが、
どうにも処理速度が遅く、さらに行数が1万を超えると、応答なしになってしまいます。
どなたか、上手い処理の方法があれば、ぜひともご教授の程をお願いします。
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
OpenFileDialog1.FileName = ""
OpenFileDialog1.InitialDirectory = "c:\"
If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
TextBox1.Text = My.Computer.FileSystem.ReadAllText _
(OpenFileDialog1.FileName, System.Text.Encoding.Default)
End If
End Sub
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim x As Integer
Dim xyz As Integer
'行数を調べる。
Dim i As Integer = TextBox1.Lines.Length
TextBox2.Text = (i - 1 & "行")
MessageBox.Show("一時停止")
For ix = 0 To i - 2
'1行目と2行目を比較
If TextBox1.Lines(x) = TextBox1.Lines(x + 1) Then
'2行目と3行目を比較
If TextBox1.Lines(x + 1) = TextBox1.Lines(x + 2) Then
'3つある番号を記入。
TextBox2.Text = TextBox2.Text + vbCrLf + TextBox1.Lines(x + 2)
'3回重複したことをカウント。
'MessageBox.Show("3発見")
xyz = xyz + 1
Else
End If
Else
End If
'調べる行を+1
x = x + 1
Next
TextBox2.Text = TextBox2.Text + vbCrLf + ("3つ以上は、" & xyz & "個")
End Sub
Private Sub OpenFileDialog1_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
End Sub
Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged
End Sub
End Class
No.1ベストアンサー
- 回答日時:
文字列の連結を
TextBox2.Text = TextBox2.Text + vbCrlf + TextBox1.Lines(x + 2)
といった具合に直接コントロールプロパティで行っているので
速度の低下を招いているのでしょう
ループの外で
Dim sb as New System.Text.StringBuilder
と宣言しておいて条件に合致した場合
sb.AppendLine( TextBox1.Lines( n ) )
xyz += 1
としてメモリー上で文字の連結をします
ループが終了したら
sb.AppendLine( String.Format( "3つ以上は、{0}個", sb.Length ) )
TextBox2.Text = sb.ToString()
といった具合にして見ましょう
重複チェック中の『応答無し』の対処としてはループ中の適当なタイミングでApplication.DoEventsを実行してみましょう
ループの中で
if x mod 100 = 0 then
Application.DoEvents()
end if
といった具合に 100回ごとに実行するとか
また条件チェックを
if TextBox1.Lines(x) = TextBox1.Lines(x+1) AndAlso _
TextBox1.Lines(x) = TextBox1.Lines(x+2) then
といった具合に 1つのif文で判定するとか
2つの条件を Andで連結すると毎回両方の条件をチェックします
AndAlsoで連結すると 前者『TextBox1.Lines(x) = TextBox1.Lines(x+1)』が不成立なら後者の条件はチェックしません
進行状況を可視化するために ProgressBarなどを使ったり
Labelなどに現在のチェックライン番号(または残数)を表示してみましょう
No.2
- 回答日時:
textboxの.Linesで調べているのが原因だと思います。
文字列配列に取り込んで計算すれば、速くなると思います。
それと質問のプログラムでは3個以上を調べているはずなのに、4個以上に対処していないように見えます。
それと、1データのチェックに3データを調べるのは効率が悪いと思います。
と言う訳で以下のようなのはどうでしょうか?
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim xyz As Integer
'配列に取得
Dim d() As String = Split(TextBox1.Text, vbCrLf)
'配列の最大引数取得
Dim ub As Integer = UBound(d)
'元文字列の最後が改行の時にできる余計なデータ分を減らす
If d(ub) = "" Then ub = ub - 1
'行数を調べる。
Dim lines As Integer = ub + 1
TextBox2.Text = (lines & "行")
MessageBox.Show("一時停止")
'最初のデータは1個目
Dim n As Integer = 1
'2番目のデータから最後まで調べる
For i = 1 To ub
If d(i) = d(i - 1) Then
'前のデータと同じならn+1個目
n = n + 1
Else
'違うなら1個目
n = 1
End If
If n = 3 Then
'3つ目なら番号を記入。
TextBox2.Text = TextBox2.Text + vbCrLf + d(i)
xyz = xyz + 1
End If
Next
TextBox2.Text = TextBox2.Text + vbCrLf + ("3つ以上は、" & xyz & "個")
End Sub
p.s.
どうしてもlines()で取得する場合は、文字列に取り込んでTextBox1.Lines(x)でアクセスする回数を減らす方がいいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 九九の答えの計算 3 2022/12/20 22:13
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Visual Basic(VBA) VBAで質問ですが、皆さんはどの様に導き出しているのでしょうか? 6 2022/05/03 21:53
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- Visual Basic(VBA) 【Excel VBA】自動メール送信の機能追加 5 2022/09/29 12:53
- Excel(エクセル) B列に文字がはいったらA列に数字が入るマクロードを完成させたい 4 2023/04/21 01:58
- Excel(エクセル) エクセルVBAでオブジェクトが必要です 2 2022/09/10 16:37
- Excel(エクセル) マクロでテキストファイルを読み込んだ際の最終セルにデータと改行が含まれる問題の改善方法 2 2022/03/25 16:50
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルでアルファベットか数...
-
EXCELで=より左の文字を一括で...
-
VBAでの Replace関数で、ワイル...
-
VBの「As String * 128」とは?
-
文字列からタブコードを取り除...
-
エクセルで文字列をtxtファイル...
-
Left関数とRight関数を合わせた...
-
Excelで指数表現しないようにす...
-
Excelで3E8を3.00E+8にしない方...
-
Pro c/c++ でホスト変数の後に....
-
【Excel VBA】複数ある特定の文...
-
VBAを使って選択した範囲の数字...
-
エクセルでセル内の文字列の最...
-
同一セル内に関数と文字列を同...
-
Msgboxの×が押されたとき
-
アクセスで特定の数字以外(複...
-
エクセルで文字列の最大値を抽...
-
C言語 名前順にソートする方法
-
MS Wordのテキスト ボックス フ...
-
[C言語]fputsとfprintfの違い
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルでアルファベットか数...
-
EXCELで=より左の文字を一括で...
-
VBAでの Replace関数で、ワイル...
-
文字列からタブコードを取り除...
-
Excelで指数表現しないようにす...
-
Excelで3E8を3.00E+8にしない方...
-
エクセルで文字列の最大値を抽...
-
MS SQLServer のSQLで文字列の...
-
エクセルで文字列をtxtファイル...
-
Left関数とRight関数を合わせた...
-
【Excel VBA】複数ある特定の文...
-
同一セル内に関数と文字列を同...
-
VBA2005 16進を2桁で表示したい。
-
VBの「As String * 128」とは?
-
エクセル 数値データを桁をそ...
-
Msgboxの×が押されたとき
-
Excelはなんで先頭の0を消すん...
-
16進数を10進数に簡単に変換す...
-
Pro c/c++ でホスト変数の後に....
-
[C言語]fputsとfprintfの違い
おすすめ情報