- 締切済み
VB.NETでの特殊なファイル削除操作
VB.NETでの特殊なファイル削除操作 フォルダ内に以下例のような撮影された画像ファイル群があり、各ファイル名は撮影時間を元に(年月日_時分秒_ミリ秒)名前付けされたもので、この同じ「秒」内に撮影された2枚目以降のファイルを、プログラム的に削除したいのですが、上手くいきません。 フォルダ内のファイル 20100709_135601_113.jpg 20100709_135601_222.jpg 20100709_135601_316.jpg 20100709_135601_364.jpg 20100709_135602_347.jpg 20100709_135602_425.jpg 20100709_135603_910.jpg 20100709_135605_175.jpg 20100709_135605_251.jpg 20100709_135606_628.jpg 例えば、一番上の13時56分01秒には、4枚撮影されたjpgファイルがありますが、最初に撮影された「20100709_135601_113.jpg」 だけを残し 残りの 「20100709_135601_222.jpg」 「20100709_135601_316.jpg」 「20100709_135601_364.jpg」 のファイルを消し、1秒1ファイルだけにしたいのです。 そしてこの結果を 20100709_135601_113.jpg 20100709_135602_347.jpg 20100709_135603_910.jpg 20100709_135605_175.jpg 20100709_135606_628.jpg としたいのです。 なお、このjpgファイルを作成する側のアプリは触れません。 こちら側のプログラムで、削除処理を行いたいです。 ファイル名定義もこのままです。 135604のように、秒内で存在しないjpgファイルも存在します。 どなたか、よいお知恵をお貸し下さいませ。 どうぞよろしくお願いします。 (WinXP Vb.NET2010)
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- imogasi
- ベストアンサー率27% (4737/17069)
VB.NETが特に得意なら別ですが、エクセルVBAでも出来ます。 気が乗らなければ無視してください。 あるフォルダ内のファイル名をエクセルシートのA列のセルに書き出す。 これはGoogleでDir関数やFSOのコード例が沢山在る。「VBA フォルダ ファイル名 全て」で照会 例 データ 書き出し後 20100709_135601_113.jpg 20100709_135601_222.jpg 20100709_135601_316.jpg 20100709_135601_364.jpg 20100709_135602_347.jpg 20100709_135602_425.jpg 20100709_135603_910.jpg 20100709_135605_175.jpg 20100709_135605_251.jpg 20100709_135606_628.jpg A列でソート。これもVBAで出来るが手動が確実。 処理ロジックは、 A列のデータを全行読むが、読んで直前の行と秒までの同じものはファイル削除する。 直前と秒までの文字列で違うものは削除しない(=残す)。 コード Sub test01() d = Range("A65536").End(xlUp).Row '最下行取得 MsgBox d j = 1 For i = 2 To d If Left(Cells(i, "A"), 15) = Left(Cells(i - 1, "A"), 15) Then 'ファイル削除(コードは下記 '削除明細 Cells(j, "C") = Cells(i, "A") j = j + 1 End If Next i End Sub ーー 削除明細は、C列に 20100709_135601_222.jpg 20100709_135601_316.jpg 20100709_135601_364.jpg 20100709_135602_425.jpg 20100709_135605_251.jpg ーー ファイル削除のコードは 「VBA ファイル 削除」で照会 http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_100.html Kill cnsSOUR のところ。
- bluecampus
- ベストアンサー率66% (138/209)
あ、消すやつは逆だった・・・ ということで、 Dim delFileNames As New List(Of String) For Each fileName As String In fileNames mfi = New MyFileInfo(fileName) ' 日付で検索し登録されているか If dic.ContainsKey(mfi.TimeStamp) Then ' ミリ秒を比較し、小さければ差し替え If dic(mfi.TimeStamp).MliliSec > mfi.MliliSec Then delFileNames.Add(dic(mfi.TimeStamp).FileName) dic(mfi.TimeStamp) = mfi Else delFileNames.Add(fileName) End If Else ' 登録 dic(mfi.TimeStamp) = mfi End If Next ' 全部表示 For Each fileName As String In delFileNames Console.WriteLine(fileName) Next こう?
- bluecampus
- ベストアンサー率66% (138/209)
何がうまくいかないのかよくわからないけど、自分だったら ファイル名・日付時間(ミリ秒は除く)・ミリ秒のクラスやら構造体とDictionaryを使ってやるかな。 Imports System Imports System.Collections.Generic Module Module1 Class MyFileInfo Dim fileName_ As String Dim timeStamp_ As DateTime Dim miliSec_ As Integer Public Sub New(ByVal fileName As String) Me.FileName = fileName ' _ と . で文字列を分割 Dim token As String() = fileName.Split(New Char() {"_"c, "."c}) ' 0番目の要素は日付、1番目の要素は時間 -> 時間型に変換 Me.TimeStamp = DateTime.ParseExact(token(0) & token(1), "yyyyMMddHHmmss", Nothing) ' 2番目の要素はミリ秒 -> 数値型に変換 Me.MliliSec = Integer.Parse(token(2)) End Sub Public Property FileName() ' 省略 End Property Public Property TimeStamp() ' 省略 End Property Public Property MliliSec() ' 省略 End Property End Class Sub Main() Dim dic As New Dictionary(Of DateTime, MyFileInfo) Dim fileNames As String() = _ New String() {"20100709_135601_113.jpg", _ "20100709_135601_222.jpg", _ "20100709_135601_316.jpg", _ "20100709_135601_364.jpg", _ "20100709_135602_347.jpg", _ "20100709_135602_425.jpg", _ "20100709_135603_910.jpg", _ "20100709_135605_251.jpg", _ "20100709_135605_175.jpg", _ "20100709_135606_628.jpg"} Dim mfi As MyFileInfo For Each fileName As String In fileNames mfi = New MyFileInfo(fileName) ' 日付で検索し登録されているか If dic.ContainsKey(mfi.TimeStamp) Then ' ミリ秒を比較し、小さければ差し替え If dic(mfi.TimeStamp).MliliSec > mfi.MliliSec Then dic(mfi.TimeStamp) = mfi End If Else ' 登録 dic(mfi.TimeStamp) = mfi End If Next ' 全部表示 For Each mfi In dic.Values() Console.WriteLine(mfi.FileName) Next End Sub End Module ※インデント保持のため全角空白! エラー処理とか考えていないです。 ちなみにVB.NETはほとんど触っていないのでもっといいやり方があるかも。
お礼
たくさん回答ありがとうございました。 以下で望む動作をしてくれるプログラムが組めました。 bluecampusさんimagashiさん、ご教授ありがとうございました。 Dim objFso As Object Dim objFolder As Object Dim objFile As Object Dim lngCount As Long Dim mnm As Object objFso = CreateObject("Scripting.FileSystemObject") objFolder = objFso.GetFolder("D:\") lngCount = 0 mnm = 0 Debug.Print("ファイル数:" & objFolder.Files.Count) For Each objFile In objFolder.Files lngCount = lngCount + 1 If mnm = Mid(objFile.name, 10, 6) Then Kill("D:\" & objFile.Name) Else mnm = Mid(objFile.name, 10, 6) End If Next