2.ComboBox でテキストファイルを使っての読み込み及び保存(17_Cbo_02) (旧、SampleNo.) |
1.一般的なテキストファイルの読み込み方法で ComboBox の項目のリストに項目を追加 2.AddRange メソッドを使っての ComboBox の項目のリストに項目を追加 3.重複データを取り除いて ComboBox の項目のリストに項目を追加 4.ComboBox の項目のリストをテキストファイルに保存 5. 6.テスト用のテキストファイルの作成 |
下記プログラムコードに関する補足・注意事項 動作確認:Windows 8.1 (Windows 7) / VB2013 (VB2010) / Framework 4.5.1 / 対象の CPU:x86 Option :[Compare Text] [Explicit On] [Infer On] [Strict On] Imports :追加なし 参照設定:追加なし その他 :使用コントロール・他:ComboBox1 / Button1 〜 Button6 : このサンプル等の内容を無断で転載、掲載、配布する事はお断りします。(私の修正・改訂・削除等が及ばなくなるので) 必要ならリンクをはるようにして下さい。(引用の場合は引用元のリンクを明記して下さい) |
1.一般的なテキストファイルの読み込み方法で ComboBox の項目のリストに項目を追加 |
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '01.一般的なテキストファイルの読み込み方法で ComboBox の項目のリストに項目を追加 Label1.Text = "" Dim sTime1 As Single = Environment.TickCount 'ComboBox1.BeginUpdate() より前に実行する事で下記のようにかなり効果がある(あまり知られていないが) '必要な項目数だけしか表示しない。 1.841 → 0.499 → 0.187 秒に短縮 ComboBox1.IntegralHeight = False 'Windows Vista 以降で有効 '読み込み中の描画をしない(これでかなり高速に処理できる) 1.841 → 0.499 秒に短縮 ComboBox1.BeginUpdate() 'こちらの効果の程は、Web 上でも色々紹介され一般的に知られている Dim st As New System.IO.StreamReader(".\test.txt", System.Text.Encoding.Default) 'ファイルの最後までループ Do Until st.Peek = -1 '1行づつ読込む ComboBox1.Items.Add(st.ReadLine) Loop st.Close() 'ファイルを閉じる ComboBox1.EndUpdate() 'コントロールの描画を再開 Dim eTime1 As Single = Environment.TickCount MessageBox.Show(((eTime1 - sTime1) / 1000) & " 秒かかりました。") '0.187 Debug.Print(ComboBox1.Items.Count.ToString) Label1.Text = ComboBox1.Items.Count.ToString & " 件" End Sub 上記の実験結果からでもわかるように、20,000 行(266KB)のデータの読み込みに、私の環境で 0.187秒しかかからず十分仕様に答えられる範囲かと思います。 |
2.AddRange メソッドを使っての ComboBox の項目のリストに項目を追加 |
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click '02.AddRange メソッドを使っての ComboBox の項目のリストに項目を追加 'StreamReader で一気に読み込み配列での登録 Label1.Text = "" Dim sTime1 As Single = Environment.TickCount ComboBox1.IntegralHeight = False ComboBox1.BeginUpdate() Dim st As New System.IO.StreamReader(".\test.txt", System.Text.Encoding.Default) Dim ss() As String = st.ReadToEnd.Split(CChar(vbCrLf)) ComboBox1.Items.AddRange(ss) ComboBox1.EndUpdate() Dim eTime1 As Single = Environment.TickCount MessageBox.Show(((eTime1 - sTime1) / 1000) & " 秒かかりました。") '0.187 Button1 の方法と変わらず Debug.Print(ComboBox1.Items.Count.ToString) Label1.Text = ComboBox1.Items.Count.ToString & " 件" End Sub 上記テストの結果、元々のデータファイルから一次元配列を作成するのに時間がかかるため通常の読み込み処理と変わらない結果となりました。 それで、AddRange メソッドの効果はどの位なのかを上記作成したデータ(ss)を使って下記のようにテストしてみました。 Dim ss1() As String Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click Dim sTime1 As Single = Environment.TickCount ComboBox1.IntegralHeight = False ComboBox1.BeginUpdate() ComboBox1.Items.AddRange(ss1) ComboBox1.EndUpdate() Dim eTime1 As Single = Environment.TickCount MessageBox.Show(((eTime1 - sTime1) / 1000) & " 秒かかりました。") '0.176 Debug.Print(ComboBox1.Items.Count.ToString) ' ComboBox1.Items.Clear() End Sub 結果は、0.176 秒と一般的な方法(0.187秒)と比べてもそれ程の効果(0.011秒)は見受けられませんでした。 |
3.重複データを取り除いて ComboBox の項目のリストに項目を追加 |
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click '03.重複データを取り除いて ComboBox の項目のリストに項目を追加 '重複を除いて読み込み表示 Label1.Text = "" Dim sTime1 As Single = Environment.TickCount 'ComboBox1.BeginUpdate() より前に実行する事 ComboBox1.IntegralHeight = False ComboBox1.BeginUpdate() Dim strList As New List(Of String) Dim st As New System.IO.StreamReader(".\test.txt", System.Text.Encoding.Default) 'ファイルの最後までループ Do Until st.Peek = -1 Dim s As String = st.ReadLine.Trim() '大文字と小文字を区別せずに比較する(条件を付加するとその分処理速度は遅くなる) 'If strList.Contains(s, StringComparer.OrdinalIgnoreCase) = False Then If strList.Contains(s) = False Then strList.Add(s) Else Debug.Print(s) End If Loop st.Close() 'ファイルを閉じる ComboBox1.Items.AddRange(strList.ToArray) ComboBox1.EndUpdate() 'コントロールの描画を再開 Dim eTime1 As Single = Environment.TickCount MessageBox.Show(((eTime1 - sTime1) / 1000) & " 秒かかりました。") '3.76 秒 Debug.Print(ComboBox1.Items.Count.ToString) Label1.Text = ComboBox1.Items.Count.ToString & " 件" ' End Sub ファイルの段階からの読み込みならこの方法が一番速いような気がする、ただし、比較条件によってはもっと処理速度がかかりるので要注意。 |
4.ComboBox の項目のリストをテキストファイルに保存 |
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click '04.ComboBox の項目のリストをテキストファイルに保存 Label1.Text = "" Dim DelFileName As String = ".\test.txt" 'ファイルの有無を確認 If System.IO.File.Exists(DelFileName) Then 'ファイルを削除 Dim fi As New System.IO.FileInfo(DelFileName) fi.Delete() End If Dim sTime1 As Single = Environment.TickCount Using st As New System.IO.StreamWriter(".\test.txt", False, System.Text.Encoding.Default) For i As Integer = 0 To ComboBox1.Items.Count - 1 st.WriteLine(ComboBox1.Items(i)) Next End Using Dim eTime1 As Single = Environment.TickCount MessageBox.Show(((eTime1 - sTime1) / 1000) & " 秒かかりました。") '0.031秒/20,000 行(266KB) Debug.Print(ComboBox1.Items.Count.ToString) Label1.Text = ComboBox1.Items.Count.ToString & " 件" End Sub テストの公平さを求めるために、一旦ファイルを削除しておりますが通常は必要ありません。 保存の場合は、0.031秒/20,000 行(266KB)と問題になるような値ではないかと思います。 |
5. |
6.テスト用のテキストファイルの作成 |
上記読み込み、保存テスト用に使ったデータ(0.062 秒/20,000 行(266KB))を作成したコードです。 必要なデータに合わせて設定値を変更して使って下さい。 Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click '06.テスト用のテキストファイルの作成 '私が使っているテスト用のデータファイルの作成コードです。 Dim sTime1 As Single = Environment.TickCount Using st As New System.IO.StreamWriter(".\test.txt", False, System.Text.Encoding.Default) Dim myData As String = "12345ABCDEabcdeあいうえおアイウエオ子牛寅卯竜巳午" Dim strList As New List(Of String) For i As Integer = 0 To 19999 'ランダムな長さのランダムな文字列を作成 Dim strLen As Integer = CInt(5 * Rnd() + 5) Dim myStr As String = "" For j = 1 To strLen myStr &= myData.Substring(CInt(30 * Rnd() + 1), 1) Next j st.WriteLine(myStr) Next i End Using Dim eTime1 As Single = Environment.TickCount MessageBox.Show(((eTime1 - sTime1) / 1000) & " 秒かかりました。") '0.062 秒/20,000 行(266KB) End Sub |
検索キーワード及びサンプルコードの別名(機能名) |
コンボボックスにテキストファイルを表示 コンボボックスにテキストファイルを読み込み コンボボックスに表示したデータを保存 ファイル 保存 書き込み 読込 |