How to filter file names by date/time? - vb.net

I need help in filtering specific time/dates(all files are in .jpeg format) in my program's report generation (motion detection system) in which the user can view detected images from a specific point of time to another (e.g. 1:00pm - 2:00pm) then display the files in the listbox.
sample screenshot filename: pic_HHMMss_ddMMMyyyy
The system works like this. After a motion is detected by the webcam, it automatically captures an image and save it to C:\Surveillance System\Detected and generate the filename pic_HHMMss_ddMMMyyyy. So this is now the report generation form wherein the authorized person can view detected images by filtering the time/date of which when the photo is captured.
For now, I can only display all the files in the directory without any filters. Any insights or help is greatly appreciated. Thanks! :)
codes:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' make a reference to a directory
Dim di As New IO.DirectoryInfo("c:\Surveillance System\Detected")
Dim diar1 As IO.FileInfo() = di.GetFiles()
Dim dra As IO.FileInfo
'list the names of all files in the specified directory
For Each dra In diar1
ListBox1.Items.Add(dra)
Next
End Sub
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
PictureBox1.Image = Image.FromFile("C:\Surveillance System\Detected\" & ListBox1.Text)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DateTimePicker2.Format = DateTimePickerFormat.Time
DateTimePicker2.ShowUpDown = True
DateTimePicker1.Format = DateTimePickerFormat.Time
DateTimePicker1.ShowUpDown = True
End Sub
button1_click = show detected
button2_click = clear items

There are two ways to do this. One is by the time listed as part of the file name:
Function GetFiles(ByVal FilterStart As DateTime, ByVal FilterEnd As DateTime) As IEnumerable(Of String)
Dim culture As CultureInfo = CultureInfo.InvariantCulture
Dim FormatString As String = "HHmmss_ddMMMyyyy"
Return Directory.EnumerateFiles("c:\Surveillance System\Detected") _
.Where(Function(f)
Dim Filedate As DateTime = DateTime.ParseExact(f.Replace("pic_", "").Replace(".jpeg", ""), FormatString, culture)
Return Filedate >= FilterStart AndAlso Filedate <= FilterEnd
End Function)
End Function
Update:
I see you changed the picture. The format string provided here only supports original file name format used in the original picture. The new picture shows multiple conventions for the file name format. If you are really going to have multiple kinds of names for your files, you should consider using the Created Date option below, or extend this option to use the TryParseExact() overload that accepts an array of possible formats.
The other is to use the Created Date information from the file system:
Function GetFiles(ByVal FilterStart As DateTime, ByVal FilterEnd As DateTime) As IEnumerable(Of String)
Dim di As New DirectoryInfo("c:\Surveillance System\Detected")
Return di.EnumerateFileSystemInfos() _
.Where(Function(f) f.CreationTime >= FilterStart AndAlso f.CreationTime <= FilterEnd) _
.Select(Function(f) f.Name)
End Function

Try using GetAttributes on your files
see http://msdn.microsoft.com/en-us/library/system.io.file.getattributes(v=vs.110).aspx
EDIT
This will add files created between the two times you set in your DateTimePicker. This will work if you want filter on when the file was created, otherwise you need to do some text transformations to dra.FileName to match it to your filenames. You would also want to add an event to track changes in the DateTimePickers so your list will automatically filter and update
'list the names of all files in the specified directory
For Each dra In diar1
If dra.CreationTime > DateTimePicker1.Value And dra.CreationTime < DateTimePicker2.Value Then
ListBox1.Items.Add(dra)
End If
Next
If you want use the filename then you need to the extract date and convert the text to date so you can file based on the DateTimePicker
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
DateTimePicker_ValueChanged(sender,Nothing)
End Sub
Private Sub DateTimePicker_ValueChanged(sender As System.Object, e As System.EventArgs) Handles DateTimePicker1.ValueChanged, DateTimePicker2.ValueChanged
Dim di As New IO.DirectoryInfo("c:\Surveillance System\Detected")
Dim diar1 As IO.FileInfo() = di.GetFiles()
Dim dra As IO.FileInfo
ListBox1.Items.Clear()
'list the names of all files in the specified directory
For Each dra In diar1
'Get file name and then convert to time
Dim splitname As String() = Replace(dra.Name.ToString, ".jpeg", "").Split("_")
Dim filetime As DateTime = Date.ParseExact(splitname(2) & splitname(1), "ddMMMyyyyHHmmss", System.Globalization.DateTimeFormatInfo.InvariantInfo)
If filetime > DateTimePicker1.Value And filetime < DateTimePicker2.Value Then
ListBox1.Items.Add(dra)
End If
Next
end Sub

Related

Go upper folder/directory VB.NET

I'm making a file/folder explorer using a ListView, when clicking a folder, it shows its contents, but I can't make it go back to where I was before opening that folder, or better going on an upper folder. example I'm in D:\Folder1\Subfolder1\Subfolder and I want to go to its upper folder, I should be in D:\Folder1\Subfolder1, Everytime I click a button.
And i have this code but what it does is it replaces all paths, making it looks like this D:\Folder1 and I can't go back further. By the way the Textbox has a default value/text of D:\Folder.
this is my code:
Dim lvs As String
Private Sub ListView1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.DoubleClick
lvs = ListView1.SelectedItems(0).Text.ToString
Form2.TextBox1.Text = Form2.TextBox1.Text & "\" & lvs
End Sub
Private Sub Button5_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
Dim s As String = Form2.TextBox1.Text
s.Replace("\" & lvs, " ").TrimEnd()
End Sub
UPDATE
Hi, I updated my code, what I did was I'm putting the ListView items in an Array and I'm deleting the last element(the last folder path) and it works fine. but when I run my code, It only execute once and it cannot be repeated, what could be wrong?
code:
Dim lvs As New List(Of String)
Private Sub ListView1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.DoubleClick
If ListView1.SelectedItems.Count > 0 Then
For Each item As ListViewItem In ListView1.SelectedItems
lvs.Add(item.Text)
Next
End If
Form2.TextBox1.Text = Form2.TextBox1.Text & "\" & ListView1.SelectedItems(0).Text
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
Label5.Text = Label5.Text.Replace("\" & lvs.ElementAt(lvs.Count - 1), "")
End Sub
You'd need to store the full path to the current folder in a string variable. You would then get the path of the parent folder by:
Dim parentPath As String = IO.Path.GetDirectoryName(currentPath)
Once you've done that you then need to make that new path the current path, which is probably what you weren't doing before. You probably just kept using the same base path to get the parent.
Here is an good sample : https://code.msdn.microsoft.com/windowsapps/Get-upper-folders-in-443e975a
Hopes this help you.
Simple way do this:
Dim path As String = #"C:\Folder1\Folder2\Folder3\Folder4"
Dim newPath As String = Path.GetFullPath(Path.Combine(path, #"..\"));
If you want to go 2level up then try #"..\..\"
Dim Child As String = "C:\Parent\Child"
Dim Parent As String = System.IO.Directory.GetParent(Child).FullName
Someone helped me with my updated code that i just have to put this lvs.RemoveAt(lvs.Count - 1), because i was only removing the item in the Label but not in the List(Of String)(that i thought is an Array, haha).
My Button should look like this:
Label5.Text = Label5.Text.Replace("\" & lvs(lvs.Count - 1), "")
lvs.RemoveAt(lvs.Count - 1)

GetDirectory will not list all Directories

I have a form that allows you to click a button, which triggers an OpenFileDialog. From there, you are suppose to select a specific file within that folder, and then the program is supposed to go through from the folder you were in the the /subjects folder and list those directories.
At the moment, I have 3 directories within /subjects: english, mathematics, and cte.
My issue is that when the program is ran, it will only list the English directory in the combo-box, and will not list any of the others.
Private Sub btnDocumentChoice_Click(sender As Object, e As EventArgs) Handles btnDocumentChoice.Click
Dim ofd As New OpenFileDialog
Dim DirList As New ArrayList
If ofd.ShowDialog = Windows.Forms.DialogResult.OK AndAlso ofd.FileName <> "" Then
strRootLocation = (Path.GetDirectoryName(ofd.FileName))
GetDirectories(strRootLocation + "/subject/", DirList)
'MessageBox.Show(Path.GetDirectoryName(ofd.FileName))
End If
End Sub
Private Sub OpenFileDialog1_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
strRootLocation = OpenFileDialog1.FileName
cmbSubject.Items.Add(strRootLocation)
End Sub
Sub GetDirectories(ByVal StartPath As String, ByRef DirectoryList As ArrayList)
Dim Dirs() As String = Directory.GetDirectories(StartPath)
DirectoryList.AddRange(Dirs)
For Each Dir As String In Dirs
GetDirectories(Dir, DirectoryList)
cmbSubject.Items.Add(Replace(Path.GetDirectoryName(Dir), strRootLocation + "\subject", ""))
cmbSubject.Items.Remove("")
Next
End Sub
I managed to fix my own issue by removing the For Each loop in the question, and replacing it with this:
Dim directories As String
For Each directories In Directory.GetDirectories(strRootLocation + "\subject")
cmbSubject.Items.Add(Replace(directories, strRootLocation + "\subject\", ""))
Next

order by date in txt file using vb.net

i made a program that takes release date and title from IMDB api and saves them in them in .txt file...can i order them by date somehow
Imports System.IO
Imports System.Xml.Linq
Imports System.Text.RegularExpressions
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim _reg As Regex = New Regex("http://www.imdb.com/title/([A-Za-z0-9\-]+)/*?", _
RegexOptions.IgnoreCase)
Dim value As String = TextBox1.Text
Dim m As Match = _reg.Match(value)
If (m.Success) Then
Dim key As String = m.Groups(1).Value
Dim url As String = "http://mymovieapi.com/?id=" + key + "&type=xml&plot=none&episode=0&lang=en-US&aka=simple&release=simple&business=0&tech=0"
Dim Document As XDocument = XDocument.Load(url)
Dim title = Document.Root.Element("title").Value()
Dim releaseDate = Date.ParseExact(Document.Root.Element("release_date").Value,
"yyyyMMdd", System.Globalization.CultureInfo.InstalledUICulture)
TextBox2.Text = "Release Date: " & releaseDate & " / Title: " & title
Else : TextBox2.Text = "Please use IMDB links"
End If
Button2.Enabled = True
End Sub
Private Sub Button2_Click_1(sender As System.Object, e As System.EventArgs) Handles Button2.Click
Dim Writer As System.IO.StreamWriter
Writer = New System.IO.StreamWriter("C:\Users\Azer\Documents\Movies.txt", True)
Writer.Write(TextBox2.Text & vbCrLf)
Writer.Close()
Button2.Enabled = False
End Sub
Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
Dim Reader As System.IO.StreamReader
Reader = New System.IO.StreamReader("C:\Users\Azer\Documents\Movies.txt")
Dim tempstring As String
Do
tempstring = Reader.ReadLine()
TextBox3.Text = TextBox3.Text + tempstring + vbCrLf
Loop Until tempstring = ""
Reader.Close()
End Sub
Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
Me.Close()
End Sub
Private Sub Button5_Click(sender As System.Object, e As System.EventArgs) Handles Button5.Click
TextBox3.Clear()
End Sub
End Class
As David said, a database would make this a lot easier. However, if you can't use a database (or have some other reason for doing it this way), here's one way to approach it.
Make a small class that holds the information (to make it easier to sort, like this:
Public Class MovieInfo
Public Property As DateTime
Public Title As String
End Class
Next, read the current file (if it exists) and populate a List<MovieInfo> with the data in it.
Dim movies As String() = File.ReadAllLines("C:\Users\Azer\Documents\Movies.txt")
Dim movieParts = From m in movies
Select m.Split(New String() { "/", ":" }, StringSplitOptions.RemoveEmptyEntries)
Dim parsedDate As DateTime
Dim movieData As List(Of MovieInfo) = (From mi In movieParts
Select New MovieInfo With
{
.ReleaseDate = _
If(DateTime.TryParseExact(mi(1).Trim, "dd.MM.yyyy", _
System.Globalization.CultureInfo.InvariantCulture, _
System.Globalization.DateTimStyle.None, _
parsedDate), parsedDate, DateTime.MinValue),
.Title = mi(3).Trim()
}.ToList()
Essentially the code above reads the text file into an array (one line per element), and then using LINQ splits each line into 4 parts based on : and /. Then it takes the result of that query and builds a List of MovieInfo, with the date string converted to DateTime for easy sorting.
The DateTime.TryParseExact takes an input string of the specified format (in this case, dd.MM.yyyy) and if possible converts it to a DateTime object. If it's successful, it returns true and the DateTime value is in the parsedDate variable. If it's not true, I use the MinValue for DateTime for the ReleaseDate property of the MovieInfo class.
After that, you'll get the new data from your API call and add it to the List of MovieInfo (you'll probably want to eliminate any duplicates). Since you didn't post the format of the data from the API, it's rather hard for me to give you a code sample to parse it, but in a nutshell you can build a second list of MovieInfo objects and then merge the existing and new list together.
Then you sort the List of MovieInfo and overwrite the original text file. Something like this should do the trick:
movieData.Sort(Function(x, y) y.ReleaseDate.CompareTo(x.ReleaseDate))
Dim output As New StringBuilder()
For Each info As MovieInfo in movieData
output.Append("Release Date: ")
output.Append(info.ReleaseDate.ToString("dd.MM.yyyy"))
output.Append(" / Title: ")
output.Append(info.Title)
output.Append(Enviroment.NewLine)
Next
File.WriteAllText("C:\Users\Azer\Documents\Movies.txt", output.ToString())
This code sorts the list with a lambda expression to put the movies in date order (newest to oldest). It then uses a StringBuilder with a For Each loop to build the output, and then writes it to the file (overwriting the file if it already exists).
Note that if you reverse the x and the y in the Sort, you'll get oldest to newest by date.
Dim allLines As String() = File.ReadAllLines("your file name")
System.Array.Sort(allLines)
IO.File.WriteAllLines("your file name", allLines) 'assuming you want to write the file

Deleting Specific Files and then Extract them into another folder

With the following code I am trying to delete specific files inside of a folder on a flash drive, and then copy the remaining files into a separate folder. When the program runs and I initiate the button to do so, the program deletes files that have not been modified within the past year, but then it does not continue to extract the remaining files and place them into a separate folder.
Does anyone know why?
Imports System.IO
Public Class frmExtractionator
Dim txtFiles1 As Control
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Dim sourceDirectory As String = "E:\CopierFolderforTestDriveCapstone"
Dim archiveDirectory As String = "E:\FilesExtracted"
Try
DeleteUnmodifiedFiles(sourceDirectory, 365)
Dim txtFiles = Directory.EnumerateFiles(sourceDirectory)
If (Not System.IO.Directory.Exists(archiveDirectory)) Then
System.IO.Directory.CreateDirectory(archiveDirectory)
End If
For Each currentFileLoc As String In txtFiles
Dim fileName = currentFileLoc.Substring(sourceDirectory.Length + 1)
File.Move(currentFileLoc, Path.Combine(archiveDirectory, fileName))
Next
Catch eT As Exception
Console.WriteLine(eT.Message)
End Try
End Sub
Private Sub DeleteUnmodifiedFiles(ByVal directoryName As String, ByVal modificationThresholdDays As Integer)
Dim folder As New DirectoryInfo(directoryName)
Dim thresholdDate As Date
Dim wasModifiedSinceThreshold As Boolean
For Each file As FileInfo In folder.GetFiles
thresholdDate = DateTime.Now().AddDays(-1 * modificationThresholdDays)
wasModifiedSinceThreshold = (file.LastWriteTime > thresholdDate)
If (Not wasModifiedSinceThreshold) Then file.Delete()
Next
MessageBox.Show("Deleting Files")
End Sub
End Class
This will delete any file in the source directory that hasn't been modified for a year, and then will move any remaining files to the destination directory...
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Dim fileListA() As String
fileListA = (IO.Directory.GetFiles("C:\Scource_Directory"))
For Each i As String In fileListA
If (IO.File.GetLastWriteTime(i).ToShortDateString.Substring(6)) < (CType(DateTime.Now.Year.ToString, Integer) - 1) Then
IO.File.Delete(i)
End If
Next
Dim fileListB() As String
fileListB = (IO.Directory.GetFiles("C:\Scource_Directory"))
For Each i As String In fileListB
IO.File.Move(i, "Destination_Directory")
Next
End Sub

Opening listview items with a double click vb.net

I want to open items from a list view with a double click.
Imports System.IO
Imports System.Xml
Public Class cv7import
Private Sub cv7import_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim caminho As String
caminho = "C:\Documents and Settings\Software\Ambiente de trabalho\cv7import"
lstvicon.View = View.Details
lstvicon.GridLines = False
lstvicon.FullRowSelect = True
lstvicon.HideSelection = False
lstvicon.MultiSelect = True
lstvicon.Columns.Add("Nome")
lstvicon.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize)
Dim DI As System.IO.DirectoryInfo = New System.IO.DirectoryInfo(caminho)
Dim files() As System.IO.FileInfo = DI.GetFiles
Dim file As System.IO.FileInfo
Dim li As ListViewItem
For Each file In files
li = lstvicon.Items.Add(file.Name)
Next
End Sub
Private Sub btnimp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnimp.Click
Dim caminho As String
caminho = "C:\Documents and Settings\Software\Ambiente de trabalho\cv7import"
Dim items() As ListViewItem = lstvicon.SelectedItems.Cast(Of ListViewItem).ToArray
Dim csv() As String = Array.ConvertAll(items, Function(lvi) String.Join(",", lvi.SubItems.Cast(Of ListViewItem.ListViewSubItem).Select(Function(si) si.Text).ToArray))
IO.File.WriteAllLines("C:\Documents and Settings\Software\Ambiente de trabalho\cv7import\teste.csv", csv)
End Class
That's the important part of the code, I was think of using onclick but I cant seem to get anywhere with it, any suggestions?
I also considered using and Open File Dialog but I dont think it can be done without the user's input of a path
I'm assuming that when you say open, you mean you want to open the associated file in the default program for that file type. In that case, you need to be storing the full path to the file in the list view. That can be accomplished via this code:
For Each file In files
li = lstvicon.Items.Add(file.Name)
li.Tag = file.FullName
Next
You will then need to add an event for the listview's double-click method. Within that event you'll want to look at the selected item and run the default program for it.
Private Sub lstvicon_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstvicon.DoubleClick
Process.Start(lstvicon.SelectedItems(0).Tag)
End Sub