• 締切済み

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)

みんなの回答

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.3

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 のところ。

回答No.2

あ、消すやつは逆だった・・・ ということで、     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 こう?

masaokun2
質問者

お礼

たくさん回答ありがとうございました。 以下で望む動作をしてくれるプログラムが組めました。 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

回答No.1

何がうまくいかないのかよくわからないけど、自分だったら ファイル名・日付時間(ミリ秒は除く)・ミリ秒のクラスやら構造体と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はほとんど触っていないのでもっといいやり方があるかも。

関連するQ&A