ファイル検索プログラムより
投稿者 あにす  (社会人)
投稿日時
2009/11/23 17:52:34
読んだだけで実行はしていないのですが、気付いた点を挙げていこうと思います。
3行目
変数名の意味がわかりません。SelectedDirectory等のわかりやすい名前を付けた方がいいと思います。
21行目
こういう無駄なネストを避ける書き方は僕好みです。
30行目でIO.SearchOption.AllDirectoriesを指定していますが、検索するフォルダによってはファイル数が多過ぎて検索に時間がかかり、アプリケーションが応答無しの状態になるかも知れません。マルチスレッド化を考えた方がいいと思います。
35~36行目
でコントロールを操作していますが、この操作はTextBox1_TextChangedメソッドを抜けるまで反映されません。Application.DoEvents()を実行することで項目の表示が更新されるでしょう。
また、"(sfile + 1) / (sfile + 1) * 100"の計算結果は常に100になります。正しくは"1 / (sfile + 1) * 100"ではないですか?
45行目
としていますが、Try-Catch文で例外をキャッチして、実行が失敗したことをユーザーに知らせた方がいいと思います。
51行目
第一引数にsenderを渡していますが、イベントプロシージャの第一引数は通常イベントを発生したオブジェクトが指定されます。混乱を避けるためにも、NothingかDirListBox1を指定した方が安全だと思います。
3行目
Dim DD As String
変数名の意味がわかりません。SelectedDirectory等のわかりやすい名前を付けた方がいいと思います。
21行目
If TextBox1.Text.Length = 0 Then
Return
End If
こういう無駄なネストを避ける書き方は僕好みです。
30行目でIO.SearchOption.AllDirectoriesを指定していますが、検索するフォルダによってはファイル数が多過ぎて検索に時間がかかり、アプリケーションが応答無しの状態になるかも知れません。マルチスレッド化を考えた方がいいと思います。
35~36行目
ToolStripProgressBar1.Value = (sfile + 1) / (sfile + 1) * 100
ToolStripStatusLabel1.Text = sfile + 1 & "項目"
でコントロールを操作していますが、この操作はTextBox1_TextChangedメソッドを抜けるまで反映されません。Application.DoEvents()を実行することで項目の表示が更新されるでしょう。
また、"(sfile + 1) / (sfile + 1) * 100"の計算結果は常に100になります。正しくは"1 / (sfile + 1) * 100"ではないですか?
45行目
On Error Resume Next
としていますが、Try-Catch文で例外をキャッチして、実行が失敗したことをユーザーに知らせた方がいいと思います。
51行目
Call DirListBox1_SelectedIndexChanged(sender, Nothing)
第一引数にsenderを渡していますが、イベントプロシージャの第一引数は通常イベントを発生したオブジェクトが指定されます。混乱を避けるためにも、NothingかDirListBox1を指定した方が安全だと思います。
投稿者 over50  (社会人)
投稿日時
2009/11/24 02:47:54
早速の返答ありがとうございます。
あにすさんの言われることを参考に、書き直してみました。
●35~36行目
ToolStripProgressBar1.Value = (sfile + 1) / (sfile + 1) * 100
ToolStripStatusLabel1.Text = sfile + 1 & "項目"
これは、プログレスバーの表示に検索されるファイル数が不明なので、1度ファイル数を ToolStripProgressBar1.Maximum = 100に置き換えているです。
●51行目
Call DirListBox1_SelectedIndexChanged(sender, Nothing)
第一引数にsenderを渡していますが、イベントプロシージャの第一引数は通常イベントを発生したオブジェクトが指定されます。混乱を避けるためにも、NothingかDirListBox1を指定した方が安全だと思います。
このプロシージャの引数について,よく理解できていないのでもう少し詳しく教えていただければ嬉しいです。
あと、昼からデイレクトリ内にファイルが見つからない時に、メッセージを表示しようとしているにですが、上手くいきません。アドバイスをお願いできないでしょうか。
Public Class Form1
Dim DD As String '対象のディレクトリを宣言
'プログレスバーの初期化
Private Sub InitProgress()
ToolStripProgressBar1.Minimum = 0
ToolStripProgressBar1.Maximum = 100
ToolStripProgressBar1.Value = 0
End Sub
Private Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
Dim ofold As New IO.DirectoryInfo(DD) '対象フォルダのインスタンス作成
ListBox1.Items.Clear()
If TextBox1.Text.Length = 0 Then '何も入力されていない場合は何もしない。
Return
End If
Dim ofile As IO.FileInfo
ListBox1.BeginUpdate()
InitProgress() 'プログレスバーを呼び出し
Try
For Each ofile In ofold.GetFiles(TextBox1.Text & "*", IO.SearchOption.AllDirectories)
Dim sfile As Integer = ListBox1.Items.Count + 1 '対象ファイル数
'ここにファイルがないときのメッセージを入れたい。
'If ?????? Then
'MsgBox("ファイルは見つかりません。")
'End If
ListBox1.Items.Add(ofile.FullName)
ToolStripProgressBar1.Value = sfile / sfile * 100 '対象ファイル数を100に変換
ToolStripStatusLabel1.Text = sfile & "項目"
Next
Catch ex As System.UnauthorizedAccessException 'ここにアクセス権限がない場合の処理を書く
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
End Try
ListBox1.EndUpdate()
ToolStripProgressBar1.Value = 0 'プログレスバーを再度初期化
End Sub
Private Sub ListBox1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.DoubleClick
Dim path As String
Try
path = ListBox1.SelectedItem
Process.Start(path) '選択ファイルを起動
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
End Try
End Sub
Private Sub DriveListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DriveListBox1.SelectedIndexChanged
DirListBox1.Path = DriveListBox1.Drive
Call DirListBox1_SelectedIndexChanged(sender, Nothing)
End Sub
Private Sub DirListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DirListBox1.SelectedIndexChanged
'対象ディレクトリを指定
DD = DirListBox1.DirList(DirListBox1.DirListIndex)
StatusBar1.Text = DD
End Sub
End Class
あにすさんの言われることを参考に、書き直してみました。
●35~36行目
ToolStripProgressBar1.Value = (sfile + 1) / (sfile + 1) * 100
ToolStripStatusLabel1.Text = sfile + 1 & "項目"
これは、プログレスバーの表示に検索されるファイル数が不明なので、1度ファイル数を ToolStripProgressBar1.Maximum = 100に置き換えているです。
●51行目
Call DirListBox1_SelectedIndexChanged(sender, Nothing)
第一引数にsenderを渡していますが、イベントプロシージャの第一引数は通常イベントを発生したオブジェクトが指定されます。混乱を避けるためにも、NothingかDirListBox1を指定した方が安全だと思います。
このプロシージャの引数について,よく理解できていないのでもう少し詳しく教えていただければ嬉しいです。
あと、昼からデイレクトリ内にファイルが見つからない時に、メッセージを表示しようとしているにですが、上手くいきません。アドバイスをお願いできないでしょうか。
Public Class Form1
Dim DD As String '対象のディレクトリを宣言
'プログレスバーの初期化
Private Sub InitProgress()
ToolStripProgressBar1.Minimum = 0
ToolStripProgressBar1.Maximum = 100
ToolStripProgressBar1.Value = 0
End Sub
Private Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
Dim ofold As New IO.DirectoryInfo(DD) '対象フォルダのインスタンス作成
ListBox1.Items.Clear()
If TextBox1.Text.Length = 0 Then '何も入力されていない場合は何もしない。
Return
End If
Dim ofile As IO.FileInfo
ListBox1.BeginUpdate()
InitProgress() 'プログレスバーを呼び出し
Try
For Each ofile In ofold.GetFiles(TextBox1.Text & "*", IO.SearchOption.AllDirectories)
Dim sfile As Integer = ListBox1.Items.Count + 1 '対象ファイル数
'ここにファイルがないときのメッセージを入れたい。
'If ?????? Then
'MsgBox("ファイルは見つかりません。")
'End If
ListBox1.Items.Add(ofile.FullName)
ToolStripProgressBar1.Value = sfile / sfile * 100 '対象ファイル数を100に変換
ToolStripStatusLabel1.Text = sfile & "項目"
Next
Catch ex As System.UnauthorizedAccessException 'ここにアクセス権限がない場合の処理を書く
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
End Try
ListBox1.EndUpdate()
ToolStripProgressBar1.Value = 0 'プログレスバーを再度初期化
End Sub
Private Sub ListBox1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.DoubleClick
Dim path As String
Try
path = ListBox1.SelectedItem
Process.Start(path) '選択ファイルを起動
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
End Try
End Sub
Private Sub DriveListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DriveListBox1.SelectedIndexChanged
DirListBox1.Path = DriveListBox1.Drive
Call DirListBox1_SelectedIndexChanged(sender, Nothing)
End Sub
Private Sub DirListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DirListBox1.SelectedIndexChanged
'対象ディレクトリを指定
DD = DirListBox1.DirList(DirListBox1.DirListIndex)
StatusBar1.Text = DD
End Sub
End Class
投稿者 tokumei  (社会人)
投稿日時
2009/11/24 03:49:31
>あと、昼からデイレクトリ内にファイルが見つからない時に、メッセージを表示しようとしているにです
>が、上手くいきません
こちらをご覧下さい
http://msdn.microsoft.com/ja-jp/library/system.io.file.exists(VS.80).aspx
>が、上手くいきません
こちらをご覧下さい
http://msdn.microsoft.com/ja-jp/library/system.io.file.exists(VS.80).aspx
投稿者 葉月  (社会人)
投稿日時
2009/11/24 04:33:09
初めましてよろしくお願いします。
私もあにすさんと同じ意見で、名前をわかりやすく変えた方がいいと思います。
C言語などは、略して使うのが一般的ですが――
オブジェクト指向言語では、略さないで使うのが一般的です。
私も一般的な略しは使います。
たとえば――
Control→Ctrl
Command→Cmd
しかし、本来なら略さない方が親切ですし、MSDNにある「名前に関するガイドライン」にも従っていない形になります。
http://msdn.microsoft.com/ja-jp/library/ms229002.aspx
Dim DD As String
私もあにすさんと同じ意見で、名前をわかりやすく変えた方がいいと思います。
C言語などは、略して使うのが一般的ですが――
オブジェクト指向言語では、略さないで使うのが一般的です。
私も一般的な略しは使います。
たとえば――
Control→Ctrl
Command→Cmd
しかし、本来なら略さない方が親切ですし、MSDNにある「名前に関するガイドライン」にも従っていない形になります。
http://msdn.microsoft.com/ja-jp/library/ms229002.aspx
投稿者 over50  (社会人)
投稿日時
2009/11/24 05:11:57
葉月さん、tokumeiさん、初めましてよろしくお願いします。
変数についてのご指摘ありがとうございます。
tokumeiさんの指摘されたmsdnも参考にして、ブール値や、ファイル数などを利用して条件式を試行しているのですが上手くいきません。
もう少し頑張ってみます。
変数についてのご指摘ありがとうございます。
tokumeiさんの指摘されたmsdnも参考にして、ブール値や、ファイル数などを利用して条件式を試行しているのですが上手くいきません。
もう少し頑張ってみます。
投稿者 葉月  (社会人)
投稿日時
2009/11/24 07:53:36
いくつか気になる点があったので、修正用にサンプルを作りました。
ですが、サンプルの説明をする時間がなくなりました。
(これから、親戚の課題をアドバイスするため別のサンプル作りをします)
こちらに時間を割かないといけないので、即席になりました。
いつも以上にヤバいできですがご了承ください。
>>>状態推移
BackgroundWorkerクラスを使うのが機能的にもいいですが、
ループ中にMe.Textを変更するだけでポンプの役割を果たします。
今回それでごまかしています。
■サンプル
以下のコントロールを貼り付けてください。
テキストボックス×2
リストボックス×1
ボタン×1
ですが、サンプルの説明をする時間がなくなりました。
(これから、親戚の課題をアドバイスするため別のサンプル作りをします)
こちらに時間を割かないといけないので、即席になりました。
いつも以上にヤバいできですがご了承ください。
>>>状態推移
BackgroundWorkerクラスを使うのが機能的にもいいですが、
ループ中にMe.Textを変更するだけでポンプの役割を果たします。
今回それでごまかしています。
■サンプル
以下のコントロールを貼り付けてください。
テキストボックス×2
リストボックス×1
ボタン×1
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.FileSearch()
End Sub
''' <summary>
''' ファイルを探す。
''' </summary>
Private Sub FileSearch()
' 選択ディレクトリ
Dim strSelectDir As String = Me.TextBox1.Text
If Not System.IO.Directory.Exists(strSelectDir) Then
Return
End If
' 作業ディレクトリ
Dim selectDirectory As New System.IO.DirectoryInfo(strSelectDir)
' 作業ファイル
Dim file As System.IO.FileInfo
' 一時的にファイルを格納
Dim arFiles As New ArrayList()
' 探すファイル
Dim strSearch As String = Me.TextBox2.Text
Dim strFile As String = String.Empty
' カウント変数
' 宣言はFor文の前で行うのがいいです。
Dim sCount As Short = 0
For Each file In selectDirectory.GetFiles(strSearch & "*", IO.SearchOption.AllDirectories)
If Not file.Exists() Then
MessageBox.Show("ファイルが存在しません")
Else
strFile = file.FullName
arFiles.Add(strFile)
Me.Text = String.Concat("処理ファイル数:" + sCount.ToString())
' プログレスバーの処理
End If
Next
Me.ListBox1.BeginUpdate()
Me.ListBox1.Items.AddRange(arFiles.ToArray())
Me.ListBox1.EndUpdate()
End Sub
End Class
投稿者 over50  (社会人)
投稿日時
2009/11/24 09:02:22
今晩は、葉月さん。
お忙しい中、有難うございます。
早速サンプルを試して、明日にでも書き込みます。
お忙しい中、有難うございます。
早速サンプルを試して、明日にでも書き込みます。
投稿者 あにす  (社会人)
投稿日時
2009/11/24 18:13:10
>over50さん
イベントプロシージャの引数については、そのまま初級講座を進めていけば"第49回 イベントの作成"で詳しく書かれています。
イベントプロシージャの引数については、そのまま初級講座を進めていけば"第49回 イベントの作成"で詳しく書かれています。
投稿者 over50  (社会人)
投稿日時
2009/11/24 20:33:03
あにすさん、レス有難うございます。
"第49回 イベントの作成"じっくり読みこんでみます。
葉月さん、昨日のコードでいろいろ試しているのですが、配列の部分
”For Each file In selectDirectory.GetFiles(strSearch & "*", IO.SearchOption.AllDirectories)”でエラーが出て前に進みません。
でも違う人が同じ目的のプログラムを書くと私のレベルでは全く違うものに見えて、勉強になります。
じっくり時間をかけて調べてみます。
あと、ファイルが見つからない時のメッセージには手こずっています。
ExistsメソッドやDir関数も試したのですが上手くいきません。
今は、ループ内から出して下にスクリプトを書いて試しています。
この場合は、ファイルがないので配列その物が出来ないのだからそこから判断させる方法を考えています。
"第49回 イベントの作成"じっくり読みこんでみます。
葉月さん、昨日のコードでいろいろ試しているのですが、配列の部分
”For Each file In selectDirectory.GetFiles(strSearch & "*", IO.SearchOption.AllDirectories)”でエラーが出て前に進みません。
でも違う人が同じ目的のプログラムを書くと私のレベルでは全く違うものに見えて、勉強になります。
じっくり時間をかけて調べてみます。
あと、ファイルが見つからない時のメッセージには手こずっています。
ExistsメソッドやDir関数も試したのですが上手くいきません。
今は、ループ内から出して下にスクリプトを書いて試しています。
この場合は、ファイルがないので配列その物が出来ないのだからそこから判断させる方法を考えています。
投稿者 葉月  (社会人)
投稿日時
2009/11/25 05:08:06
サンプルの説明をしていなかったので簡単に説明します。
For文の中でlistboxのAddメソッドを使用していたので、
ArrayListに格納してからAddRangeでまとめて処理しました。
こうすることでコードがシンプルになり処理も向上します。
■サンプル
処理の話は、Addメソッドで一つずつ格納しても、ListBoxだったらよほど大量のデータでな
ければ問題ないと思います。
しかし、ListViewで同じような使い方をすると画面がちらついたり処理がもたつく可能性が
あります。
>サンプルの使い方
TextBox1に作業するフォルダを入力します。
TextBox2に探すファイル名(一部OK)を入力します。
TextBox2に該当するファイルが見つかった場合に、ListBox1にフルパスが表示されます。
>~でエラーが出て前に進みません。
サンプルはVS2005以上なら動くと思うのですが、コンパイルエラー、
もしくは実行時にエラーが起きましたでしょうか?
対応中でしたら、エラー内容と状況をお知らせ頂ければ、他の参加者や私が助言できると思います。
カウント変数が0のままだったり酷い出来ですが、ファイル検索はできていました。
over50さんの方で処理を追加していましたら、その絡みかも知れません。
掲示板のまま打ったとしたら、どこかで打ち間違えているのも考えられます。
その場合は、FileSearch()メソッドを丸ごとコピペしてみてください。
For文の中でlistboxのAddメソッドを使用していたので、
ArrayListに格納してからAddRangeでまとめて処理しました。
こうすることでコードがシンプルになり処理も向上します。
■サンプル
Me.ListBox1.BeginUpdate()
Me.ListBox1.Items.AddRange(arFiles.ToArray())
Me.ListBox1.EndUpdate()
処理の話は、Addメソッドで一つずつ格納しても、ListBoxだったらよほど大量のデータでな
ければ問題ないと思います。
しかし、ListViewで同じような使い方をすると画面がちらついたり処理がもたつく可能性が
あります。
>サンプルの使い方
TextBox1に作業するフォルダを入力します。
TextBox2に探すファイル名(一部OK)を入力します。
TextBox2に該当するファイルが見つかった場合に、ListBox1にフルパスが表示されます。
>~でエラーが出て前に進みません。
サンプルはVS2005以上なら動くと思うのですが、コンパイルエラー、
もしくは実行時にエラーが起きましたでしょうか?
対応中でしたら、エラー内容と状況をお知らせ頂ければ、他の参加者や私が助言できると思います。
カウント変数が0のままだったり酷い出来ですが、ファイル検索はできていました。
over50さんの方で処理を追加していましたら、その絡みかも知れません。
掲示板のまま打ったとしたら、どこかで打ち間違えているのも考えられます。
その場合は、FileSearch()メソッドを丸ごとコピペしてみてください。
投稿者 over50  (社会人)
投稿日時
2009/11/25 08:42:12
葉月さん、丁寧な説明ありがとうございます。
言われるように再度確認すると、TextBox1にドライブの指定だと以下のメッセージが表示。
”unauthorized access axceptionはハンドルされませんでした。とダイアログが出て
パス 'c:\System Volume Information' へのアクセスが拒否されました。”
ディレクトリーまで指定すれば問題なく動作確認。
ただし、ファイルがないときのメッセージや処理ファイル数の表示はカウントされないですね。
”ArrayListに格納してからAddRangeでまとめて処理しました。
こうすることでコードがシンプルになり処理も向上します。
■サンプル
Me.ListBox1.BeginUpdate()
Me.ListBox1.Items.AddRange(arFiles.ToArray())
Me.ListBox1.EndUpdate ”
を参考に再度コードをやり直して、アップします。
言われるように再度確認すると、TextBox1にドライブの指定だと以下のメッセージが表示。
”unauthorized access axceptionはハンドルされませんでした。とダイアログが出て
パス 'c:\System Volume Information' へのアクセスが拒否されました。”
ディレクトリーまで指定すれば問題なく動作確認。
ただし、ファイルがないときのメッセージや処理ファイル数の表示はカウントされないですね。
”ArrayListに格納してからAddRangeでまとめて処理しました。
こうすることでコードがシンプルになり処理も向上します。
■サンプル
Me.ListBox1.BeginUpdate()
Me.ListBox1.Items.AddRange(arFiles.ToArray())
Me.ListBox1.EndUpdate ”
を参考に再度コードをやり直して、アップします。
投稿者 葉月  (社会人)
投稿日時
2009/11/25 10:29:18
>”unauthorized access axceptionはハンドルされませんでした。
権限のないディレクトリにアクセスしてエラーが起こっています。
ドライブ全体を対象にすると、ユーザーにアクセス権限がないフォルダを除外するよう考慮
する必要があり難度が上がると思われます。
以下に修正したサンプルを載せますが、こちらもドライブ全体を考慮していません。
>>>ただし、ファイルがないときのメッセージ
簡易的に修正したサンプルを上げるので、こちらで試してください。
このサンプルを少し修正すれば、エラーファイルのカウントなども取得できるようになりま
す。
■サンプル
権限のないディレクトリにアクセスしてエラーが起こっています。
ドライブ全体を対象にすると、ユーザーにアクセス権限がないフォルダを除外するよう考慮
する必要があり難度が上がると思われます。
以下に修正したサンプルを載せますが、こちらもドライブ全体を考慮していません。
>>>ただし、ファイルがないときのメッセージ
簡易的に修正したサンプルを上げるので、こちらで試してください。
このサンプルを少し修正すれば、エラーファイルのカウントなども取得できるようになりま
す。
■サンプル
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.ListBox1.Items.Clear()
Me.FileSearch()
End Sub
''' <summary>
''' ファイルを探す。
''' </summary>
Private Sub FileSearch()
Const SHORT_COUNT_UP As Short = 1
' 選択ディレクトリ
Dim strSelectDir As String = Me.TextBox1.Text
If Not System.IO.Directory.Exists(strSelectDir) Then
Return
End If
' 作業ディレクトリ
Dim selectDirectory As New System.IO.DirectoryInfo(strSelectDir)
' 作業ファイル
Dim file As System.IO.FileInfo
' 一時的にファイルを格納
Dim arFiles As New ArrayList()
' 探すファイル
Dim strSearch As String = Me.TextBox2.Text
Dim strFile As String = String.Empty
' カウント変数
' 宣言はFor文の前で行うのがいいです。
Dim sCount As Short = 0
For Each file In selectDirectory.GetFiles(strSearch & "*", IO.SearchOption.AllDirectories)
strFile = file.FullName
If System.IO.File.Exists(strFile) Then
sCount += SHORT_COUNT_UP
strFile = file.FullName
arFiles.Add(strFile)
Me.Text = String.Concat("処理ファイル数:" + sCount.ToString())
' プログレスバーの処理
Else
MessageBox.Show("ファイルが存在しません")
End If
Next
Me.ListBox1.BeginUpdate()
Me.ListBox1.Items.AddRange(arFiles.ToArray())
Me.ListBox1.EndUpdate()
End Sub
End Class
投稿者 over50  (社会人)
投稿日時
2009/11/26 08:55:07
葉月さん、度々丁寧なRES.有難うございます。
もう少し早くアップしたかったのですが、動作確認に時間がかかって遅くなりました。
今回は、自分のPCの環境に合わせてTextChangedイベントに拘りました。
マルチブートとドライブが多く、自分では使いやすい物になったように思います。
デザインは、ドライブリストボックス、ディレクトリリストボックス、テキストボックス、ステータスバーとステータスストリップに、ラベルとプログレスバーを各1つづつ張り付けたものです。
特にコードの中のTextChangedイベントで、キー入力のイベント発生を遅らせる処理での
”System.Threading.Thread.Sleep(1000)
Application.DoEvents()”と、
ファイルが無い時のメッセージの処理は何とか出来たもののこれでいいのかよく解っていません。
その他を含め、皆さんから何かアドバイスをいただければ幸いです。
Public Class Form1
Dim SlctDirect As String '対象のディレクトリを宣言
Private Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
'キー入力でのイベントを遅らせて、スムーズにする。
System.Threading.Thread.Sleep(1000)
Application.DoEvents()
'表示を初期化
ToolStripProgressBar1.Value = 0
ToolStripStatusLabel1.Text = Nothing
Me.Text = ("簡易ファイル検索")
Me.ListBox1.Items.Clear()
Me.filesearch()
End Sub
Private Sub filesearch()
Const short_count_up As Short = 1
' 選択ディレクトリ
Dim strSelectDir As String = Me.SlctDirect
'何も入力されていない場合は何もしない。
If TextBox1.Text.Length = 0 Then
Return
End If
' 作業ディレクトリ
Dim selectDirectory As New System.IO.DirectoryInfo(strSelectDir)
' 作業ファイル
Dim file As System.IO.FileInfo
' 一時的にファイルを格納
Dim arFiles As New ArrayList()
' 探すファイル
Dim strSearch As String = Me.TextBox1.Text
Dim strFile As String = String.Empty
' カウント変数
' 宣言はFor文の前で行うのがいいです。
Dim sCount As Short = 0
Try
For Each file In selectDirectory.GetFiles(strSearch & "*", IO.SearchOption.AllDirectories)
strFile = file.FullName
If System.IO.File.Exists(strFile) Then
sCount += short_count_up
strFile = file.FullName
arFiles.Add(strFile)
' プログレスバーの処理
ToolStripProgressBar1.Value = sCount / sCount * 100
ToolStripStatusLabel1.Text = String.Concat(+sCount.ToString() & "項目")
End If
Next
If strFile = String.Empty Then
Me.Text = "ファイルが見つかりません!"
End If
'エラー処理
Catch ex As System.UnauthorizedAccessException
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
End Try
Me.ListBox1.BeginUpdate()
Me.ListBox1.Items.AddRange(arFiles.ToArray())
Me.ListBox1.EndUpdate()
End Sub
Private Sub ListBox1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.DoubleClick
Dim path As String
Try
'選択ファイルの起動
path = ListBox1.SelectedItem
Process.Start(path)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
End Try
End Sub
Private Sub DriveListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DriveListBox1.SelectedIndexChanged
DirListBox1.Path = DriveListBox1.Drive
Call DirListBox1_SelectedIndexChanged(sender, Nothing)
End Sub
Private Sub DirListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DirListBox1.SelectedIndexChanged
'対象のディレクトリの選択
SlctDirect = DirListBox1.DirList(DirListBox1.DirListIndex)
StatusBar1.Text = SlctDirect
End Sub
End Class
もう少し早くアップしたかったのですが、動作確認に時間がかかって遅くなりました。
今回は、自分のPCの環境に合わせてTextChangedイベントに拘りました。
マルチブートとドライブが多く、自分では使いやすい物になったように思います。
デザインは、ドライブリストボックス、ディレクトリリストボックス、テキストボックス、ステータスバーとステータスストリップに、ラベルとプログレスバーを各1つづつ張り付けたものです。
特にコードの中のTextChangedイベントで、キー入力のイベント発生を遅らせる処理での
”System.Threading.Thread.Sleep(1000)
Application.DoEvents()”と、
ファイルが無い時のメッセージの処理は何とか出来たもののこれでいいのかよく解っていません。
その他を含め、皆さんから何かアドバイスをいただければ幸いです。
Public Class Form1
Dim SlctDirect As String '対象のディレクトリを宣言
Private Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
'キー入力でのイベントを遅らせて、スムーズにする。
System.Threading.Thread.Sleep(1000)
Application.DoEvents()
'表示を初期化
ToolStripProgressBar1.Value = 0
ToolStripStatusLabel1.Text = Nothing
Me.Text = ("簡易ファイル検索")
Me.ListBox1.Items.Clear()
Me.filesearch()
End Sub
Private Sub filesearch()
Const short_count_up As Short = 1
' 選択ディレクトリ
Dim strSelectDir As String = Me.SlctDirect
'何も入力されていない場合は何もしない。
If TextBox1.Text.Length = 0 Then
Return
End If
' 作業ディレクトリ
Dim selectDirectory As New System.IO.DirectoryInfo(strSelectDir)
' 作業ファイル
Dim file As System.IO.FileInfo
' 一時的にファイルを格納
Dim arFiles As New ArrayList()
' 探すファイル
Dim strSearch As String = Me.TextBox1.Text
Dim strFile As String = String.Empty
' カウント変数
' 宣言はFor文の前で行うのがいいです。
Dim sCount As Short = 0
Try
For Each file In selectDirectory.GetFiles(strSearch & "*", IO.SearchOption.AllDirectories)
strFile = file.FullName
If System.IO.File.Exists(strFile) Then
sCount += short_count_up
strFile = file.FullName
arFiles.Add(strFile)
' プログレスバーの処理
ToolStripProgressBar1.Value = sCount / sCount * 100
ToolStripStatusLabel1.Text = String.Concat(+sCount.ToString() & "項目")
End If
Next
If strFile = String.Empty Then
Me.Text = "ファイルが見つかりません!"
End If
'エラー処理
Catch ex As System.UnauthorizedAccessException
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
End Try
Me.ListBox1.BeginUpdate()
Me.ListBox1.Items.AddRange(arFiles.ToArray())
Me.ListBox1.EndUpdate()
End Sub
Private Sub ListBox1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.DoubleClick
Dim path As String
Try
'選択ファイルの起動
path = ListBox1.SelectedItem
Process.Start(path)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
End Try
End Sub
Private Sub DriveListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DriveListBox1.SelectedIndexChanged
DirListBox1.Path = DriveListBox1.Drive
Call DirListBox1_SelectedIndexChanged(sender, Nothing)
End Sub
Private Sub DirListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DirListBox1.SelectedIndexChanged
'対象のディレクトリの選択
SlctDirect = DirListBox1.DirList(DirListBox1.DirListIndex)
StatusBar1.Text = SlctDirect
End Sub
End Class
投稿者 葉月  (社会人)
投稿日時
2009/11/26 10:26:15
over50さん、目的のものが出来たようで何よりです。
おめでとうございます。
私的には作ることが大事だと思うので、コードに関してとくにありません。
命名規則だけ簡単に説明いたします。
メソッド(関数)は、最初大文字、違う単語がきたらまた大文字にします。
Private Sub filesearch()だったら――
Private Sub FileSearch()が、.NET系の推奨されている書き方になります。
それから、私はハンガリアン記法をString型とFormコントロールでよく使っていますが、
.NET系では使わないのが推奨になっています。
その点をご理解頂いて使用されているなら、全てに目を通していませんが変数名はとくに問
題ないと思います。
おめでとうございます。
私的には作ることが大事だと思うので、コードに関してとくにありません。
命名規則だけ簡単に説明いたします。
メソッド(関数)は、最初大文字、違う単語がきたらまた大文字にします。
Private Sub filesearch()だったら――
Private Sub FileSearch()が、.NET系の推奨されている書き方になります。
それから、私はハンガリアン記法をString型とFormコントロールでよく使っていますが、
.NET系では使わないのが推奨になっています。
その点をご理解頂いて使用されているなら、全てに目を通していませんが変数名はとくに問
題ないと思います。
投稿者 over50  (社会人)
投稿日時
2009/11/26 17:26:49
葉月さん、有難うございます。
いただいたコード、時間がある時に再度じっくり読み込んでみます。
また何か有りましたらよろしくお願いします。
いただいたコード、時間がある時に再度じっくり読み込んでみます。
また何か有りましたらよろしくお願いします。
よろしくお願いします。
50才を超えて、失業中なのをいいことにデーターベースを勉強しようとMS ACCESSを1段落して、VBを基礎からやってみようとこちらのサイトに来ました。
MS VS2008の評価版を使用しています。
題名の通り、初級講座の第31回ファイルシステムにあるファイル検索プログラムのことで教えていただきたいと書き込みました。
準備講座から始めてなんとか初級講座の第31回ファイルシステムまで来たので、今自分で出来る範囲でこのプログラムを自分で使いやすくカスタマイズしてみました。
と言っても、ドライブとデレクトリーの選択とタスクバーに表示。
プログレスバーと、検索ファイル数の表示だけですが。
如何せん、初めてなものでエラーも出ずに動作はしていますが皆さんに見ていただいて、おかしな点や間違い等、改良すべきところをご指摘いただければと思い投稿しました。
どんな点でも、これからの学習の指標になればと思います。
以下に、コードの全文を入れます。よろしくお願いします。
Public Class Form1
Dim DD As String
'プログレスバーの初期化
Private Sub InitProgress()
ToolStripProgressBar1.Minimum = 0
ToolStripProgressBar1.Maximum = 100
ToolStripProgressBar1.Value = 0
End Sub
Private Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
Dim ofold As New IO.DirectoryInfo(DD)
ListBox1.Items.Clear()
If TextBox1.Text.Length = 0 Then
Return
End If
Dim ofile As IO.FileInfo
ListBox1.BeginUpdate()
InitProgress()
For Each ofile In ofold.GetFiles(TextBox1.Text & "*", IO.SearchOption.AllDirectories)
Dim sfile As Integer = ListBox1.Items.Count
ListBox1.Items.Add(ofile.FullName)
ToolStripProgressBar1.Value = (sfile + 1) / (sfile + 1) * 100
ToolStripStatusLabel1.Text = sfile + 1 & "項目"
Next
ListBox1.EndUpdate()
ToolStripProgressBar1.Value = 0
End Sub
Private Sub ListBox1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.DoubleClick
On Error Resume Next
Process.Start(ListBox1.SelectedItem)
End Sub
Private Sub DriveListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DriveListBox1.SelectedIndexChanged
DirListBox1.Path = DriveListBox1.Drive
Call DirListBox1_SelectedIndexChanged(sender, Nothing)
End Sub
Private Sub DirListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DirListBox1.SelectedIndexChanged
DD = DirListBox1.DirList(DirListBox1.DirListIndex)
StatusBar1.Text = DD
End Sub
End Class