Compare two For Each lists in vb.net - vb.net

I have a small problem.
I have two for each routines. One gives me all foldernames in the current folder. The other gives me all window names opened. Both are saving the results in a String. One with newlines, the other with ~, so I can loop through both and get all the items one by one.
This is the part:
Dim Folders As String
For Each Dir As String In System.IO.Directory.GetDirectories(My.Computer.FileSystem.CurrentDirectory & "\Data\")
Dim dirInfo As New System.IO.DirectoryInfo(Dir)
Folders = Folders & dirInfo.Name & "~"
Next
Dim FolderList() As String = Folders.Split("~")
Dim p As Process
Dim Windows As String
For Each p In Process.GetProcesses
Windows = Windows & vbNewLine & p.MainWindowTitle.ToString
Next
Windows = LineTrim(Windows)
This works. But now, I want to compare them.
I only want to get the Folders, where a window exists, which contains the foldername.
For example, I have 3 folders: Test1,Test2,Test3.
I have one Window opened: "Test1 - Window"
Now I only want to get "Test1" as Result once.
I got it working so far, but I get "Test1" 3 times, because there are 3 folders. Because I am creating new Windows by this info, my function spams new windows..
This is the whole function:
Dim Folders As String
For Each Dir As String In System.IO.Directory.GetDirectories(My.Computer.FileSystem.CurrentDirectory & "\Data\")
Dim dirInfo As New System.IO.DirectoryInfo(Dir)
Folders = Folders & dirInfo.Name & "~"
Next
Dim str As String() = Folders.Split("~")
For Each Folder As String In str
If (My.Computer.FileSystem.FileExists(My.Computer.FileSystem.CurrentDirectory & "\Data\" & Folder & "\" & "Status.txt")) Then
Dim StartTime As String = Inireader.WertLesen("Settings", "StartTime", My.Computer.FileSystem.CurrentDirectory & "\Data\" & Folder & "\Time.ini")
Dim StopTime As String = Inireader.WertLesen("Settings", "StopTime", My.Computer.FileSystem.CurrentDirectory & "\Data\" & Folder & "\Time.ini")
If (IsInTime(StartTime, StopTime) = True) Then
Dim p As Process
Dim Windows As String
For Each p In Process.GetProcesses
Windows = Windows & vbNewLine & p.MainWindowTitle.ToString
Next
Windows = LineTrim(Windows)
Dim Ar() As String = Split(Windows, Environment.NewLine)
For Each Window As String In Ar
If sX.ToString.Contains(Window & " - python " & My.Computer.FileSystem.CurrentDirectory & "\Data\" & Window& "\" & Window & ".py") Then ''''The Spam cause line
Else
Dim Path = My.Computer.FileSystem.CurrentDirectory & "\Data\" & Folder & "\" & Folder & ".py"
Dim startInfo As New ProcessStartInfo
startInfo.FileName = "cmd.exe"
startInfo.Arguments = "/k " & "title " & Folder & " & python " & Path
startInfo.WorkingDirectory = My.Computer.FileSystem.CurrentDirectory & "\Data\" & Folder & "\"
Process.Start(startInfo)
End If
Next
End If
End If
Next
I can´t shorten it very much..
Could you help me out?
Thank you :)
Best regards!

Related

Moving files with specific extension to related folders in vb.net

I'm using below sub procedure to classify specific files to specific folders but i thought there should be more logic way to do it instead of using so much if elseif structure. I don't know is it true way to do that.
Dim DirInfo As New DirectoryInfo(strPath & "\" & My.Settings.txt_main_db)
For Each SubFile As FileInfo In DirInfo.GetFiles
If Path.GetExtension(SubFile.Name) = ".spck" Or Path.GetExtension(SubFile.Name) = ".buspck" Then
Dim subPathSpck = strPath & "\" & My.Settings.txt_main_db & "\" & My.Settings.txt_mbs_db_substructure
Directory.CreateDirectory(subPathSpck)
SubFile.MoveTo(subPathSpck & "\" & SubFile.Name)
ElseIf Path.GetExtension(SubFile.Name) = ".fbi" Then
Dim subPathFBI = strPath & "\" & My.Settings.txt_main_db & "\" & My.Settings.txt_elastic_body
Directory.CreateDirectory(subPathFBI)
SubFile.MoveTo(subPathFBI & "\" & SubFile.Name)
ElseIf Path.GetExtension(SubFile.Name) = ".stl" _
Or Path.GetExtension(SubFile.Name) = ".obj" _
Or Path.GetExtension(SubFile.Name) = ".igs" _
Or Path.GetExtension(SubFile.Name) = ".slp" _
Or Path.GetExtension(SubFile.Name) = ".obj" Then
Dim subPathCAD = strPath & "\" & My.Settings.txt_main_db & "\" & My.Settings.txt_cad_geometry
Directory.CreateDirectory(subPathCAD)
SubFile.MoveTo(subPathCAD & "\" & SubFile.Name)
ElseIf Path.GetExtension(SubFile.Name) = ".if2" _
Or Path.GetExtension(SubFile.Name) = ".afs" _
Or Path.GetExtension(SubFile.Name) = ".tre" Then
Dim subPathIF2 = strPath & "\" & My.Settings.txt_main_db & "\" & My.Settings.txt_input_functions
Directory.CreateDirectory(subPathIF2)
SubFile.MoveTo(subPathIF2 & "\" & SubFile.Name)
ElseIf Path.GetExtension(SubFile.Name) = ".subvar" Then
Dim subPathSubVar = strPath & "\" & My.Settings.txt_main_db & "\" & My.Settings.txt_mbs_db_ip
Directory.CreateDirectory(subPathSubVar)
SubFile.MoveTo(subPathSubVar & "\" & SubFile.Name)
ElseIf Path.GetExtension(SubFile.Name) = ".tpf" _
Or Path.GetExtension(SubFile.Name) = ".tir" Then
Dim subPathDelft = strPath & "\" & My.Settings.txt_main_db & "\" & My.Settings.txt_tyre_delft_swift
Directory.CreateDirectory(subPathDelft)
SubFile.MoveTo(subPathDelft & "\" & SubFile.Name)
ElseIf Path.GetExtension(SubFile.Name) = ".rdf" Then
Dim subPathRoad = strPath & "\" & My.Settings.txt_main_db & "\" & My.Settings.txt_mbs_db_road
Directory.CreateDirectory(subPathRoad)
SubFile.MoveTo(subPathRoad & "\" & SubFile.Name)
Else
Dim subPathExt = strPath & "\" & My.Settings.txt_main_db & "\" & My.Settings.txt_mbs_db_extfile
Directory.CreateDirectory(subPathExt)
SubFile.MoveTo(subPathExt & "\" & SubFile.Name)
End If
Next
There is nothing wrong to have some if...elseif.. (or even a Select Case), but if your intent is to remove a lengthy selection you could use a Dictionary where the key is the file extension and the value is a Function that handles that particular key extension.
The key is used to find a Function that configure the variables and do the file move.
This could be done in this way, I leave it to you to judge if this is more clear or not against your current code:
' some test values
Dim strPath As String = "e:\temp"
Dim txt_main_db As String = "root"
Dim txt_mbs_db_substructure = "spkBackup"
Dim txt_elastic_body = "fbiBackup"
' the dictionary
Dim moveHandler As Dictionary(Of String, Action(Of FileInfo))
' initialization somewhere in your code...
Sub Main
' Set the handler for each extensions but you could have the same handler for many extensions
moveHandler.Add(".spck", Function(f As FileInfo) HandleSpck(f))
moveHandler.Add(".buspck", Function(f As FileInfo) HandleSpck(f))
moveHandler.Add(".fbi", Function(f As FileInfo) HandleFbi(f))
......
moveHandler.Add("others", Function(f As FileInfo) HandleOthers(f))
End Sub
' handler to move a file with .spck or .buspck extension
Function HandleSpck(SubFile As FileInfo)
Dim subPathSpck = Path.Combine(strPath,txt_main_db, txt_mbs_db_substructure)
Directory.CreateDirectory(subPathSpck)
SubFile.MoveTo(Path.Combine(subPathSpck,SubFile.Name))
End Function
' handler to move a file with .fbi extension
Function HandleFbi(SubFile As FileInfo)
Dim subPathSpck = Path.Combine(strPath, txt_main_db, txt_elastic_body )
Directory.CreateDirectory(subPathSpck)
SubFile.MoveTo(Path.Combine(subPathSpck, SubFile.Name))
End Function
' Other handlers for other extensions
.....
Finally you can call the handlers with a very short loop
Dim source = Path.Combine(strPath, txt_main_db)
Dim DirInfo As New DirectoryInfo(source)
For Each SubFile As FileInfo In DirInfo.GetFiles
If moveHandler.ContainsKey(SubFile.Extension) Then
moveHandler(SubFile.Extension).Invoke(SubFile)
Else
moveHandler("others").Invoke(SubFile)
End If
Next
But, wait.... now with this code is place it is easy to notate the pattern. You execute always the same code. The only thing that changes is the destination. Now, what if we have an handler where we pass the destination folder and the FileInfo variable? We can have just one handler
Function HandleFileMove(destFolder as String, SubFile As FileInfo)
Dim subFolder = Path.Combine(strPath,txt_main_db, destFolder)
Directory.CreateDirectory(subFolder)
SubFile.MoveTo(Path.Combine(subFolder,SubFile.Name))
End Function
and we have to adjust the dictionary to call always the same handler but giving the new parameter required to create the subfolder.
moveHandler.Add(".spck", Function(f As FileInfo) HandleFileMove(txt_mbs_db_substructure, f))
moveHandler.Add(".fbi", Function(f As FileInfo) HandleFileMove(txt_elastic_body, f))
.....
Of course this is good only if your only task inside the common handler is to copy a file in a predefined subfolder. If you need to do any other task for a specific extension then it is better to have separate handlers for each extension.

Ms Access Get filename with wildcards or loop

I am using MS Access Forms and I am trying to open a file but don't know how to open the file based knowing only part of the name. Example below works
Private Sub Open_Email_Click()
On Error GoTo Err_cmdExplore_Click
Dim x As Long
Dim strFileName As String
strFileName = "C:\data\office\policy num\20180926 S Sales 112.32.msg"
strApp = """C:\Program Files\Microsoft Office\Office15\Outlook.exe"""
If InStr(strFileName, " ") > 0 Then strFileName = """" & strFileName & """"
x = Shell(strApp & " /f " & strFileName)
Exit_cmdExplore_Click:
Exit Sub
Err_cmdExplore_Click:
MsgBox Err.Description
Resume Exit_cmdExplore_Click
End Sub
If I change the strFilename to being
strFileName = "C:\data\" & Me.Office & "\" & Me.nm & " " & Me.pol & "\" & "*"& " S Sales " & Me.amt & "*" & ".msg"
It includes the * rather than using it as a wildcard, the date/numbers can be anything or in another format but always eight numbers. I tried using a while loop on the numbers but I am not sure the best way of doing this sorry.
You can use the Dir function to iterate over all files that match a string pattern.
strApp = """C:\Program Files\Microsoft Office\Office15\Outlook.exe"""
Dim strFilePattern As String
strFilePattern ="C:\data\" & Me.Office & "\" & Me.nm & " " & Me.pol & "\" & "*"& " S Sales " & Me.amt & "*" & ".msg"
Dim strFileName As String
strFileName = Dir(strFilePattern)
Do While Not strFileName = vbNullString
If InStr(strFileName, " ") > 0 Then strFileName = """" & strFileName & """"
x = Shell(strApp & " /f " & strFileName)
strFileName = Dir
Loop
The first call to Dir with the pattern as a parameter will find the first file that matches the pattern supplied. All subsequent calls without the pattern will return the next file that matches the pattern.
So, lets rebuild the question a bit. Imagine that you are having the following 5 files in a given folder:
A:\peter.msg
A:\bstack.msg
A:\coverflow.msg
A:\heter.msg
A:\beter.msg
and you need to find the files, that correspond to "A:\*eter.msg" and print them.
For this, you need to use the keyword Like:
Sub TestMe()
Dim someNames As Variant
someNames = Array("A:\peter.msg", "A:\bstack.msg", _
"A:\coverflow.msg", "A:\heter.msg", "A:\beter.msg")
Dim cnt As Long
For cnt = LBound(someNames) To UBound(someNames)
If someNames(cnt) Like "A:\*eter.msg" Then
Debug.Print someNames(cnt)
End If
Next
End Sub
Loop through files in a folder using VBA?

Recursive search code optimization with vb.net

I have created a little program to search a set of folders holding documents scanned.
the folder structure is as follows:
c:\images\year\month\date\documenttype\firstpartofdocumentNo.\
the year folder contains years from 2005 - 2015
the month folder contains the months of the year (Obviously)
same with date
the documenttype folder can contain between 1 and 5 folders
the firstpartofdocumentno. can contain between 1 and 3 folders
the code I am using at the moment is :
CompName = Environment.MachineName
'MsgBox(CompName)
TicketNo = TxtTicketNo.Text
If CompName = "Comp1" Then
ImageDir = "C:\Images\"
Else
ImageDir = "\\Comp1\Images\"
End If
For Each DirYear As String In Directory.GetDirectories(ImageDir)
Dim YearInfo As New DirectoryInfo(DirYear)
For Each DirMonth As String In Directory.GetDirectories(DirYear)
Dim MonthInfo As New DirectoryInfo(DirMonth)
For Each DirDate As String In Directory.GetDirectories(DirMonth)
Dim DateInfo As New DirectoryInfo(DirDate)
For Each DirType As String In Directory.GetDirectories(DirDate)
Dim TypeInfo As New DirectoryInfo(DirType)
For Each DirStart As String In Directory.GetDirectories(DirType)
Dim StartInfo As New DirectoryInfo(DirStart)
MainDirectory = ImageDir & YearInfo.Name & "\" & MonthInfo.Name & "\" & DateInfo.Name & "\" & TypeInfo.Name & "\" & StartInfo.Name & "\"
'LstFiles.Items.Add(YearInfo.Name & "\" & MonthInfo.Name & "\" & DateInfo.Name & "\" & TypeInfo.Name & "\")
'Dim files() As String = Directory.GetFiles(MainDirectory, TicketNo & "*")
'For Each Ticket As String In Directory.GetFiles(MainDirectory, TicketNo)
For Each Ticket As String In Directory.GetFiles(MainDirectory, TicketNo & "*")
LstFiles.Items.Add(Ticket)
Next
'Next
Next
'MsgBox(files)
'LstFiles.Items.Add()
Next
'LstFiles.Items.Add(dirInfo.Name)
Next
Next
'MsgBox(ImageDir)
Next
I have a textbox on the form which is used to enter the last four numbers of the ticketno and then this code runs when the button is clicked.
The problem is it can take up to five minutes to search, so I was wondering if there is a way to optimize this code to speed it up a bit or does this sound about right for searching that many folders.
Thanks in advance
Gareth

VB file compression in VS2013

I came across an article on implementing .zip VB file compression in VS2013 but have a snag in implementing it.
When I get to the line System.IO.Compression.ZipFile.CreateFromDirectory, I get an error in VS that .ZipFile is not a member of ".Compression".
Here’s the code for my command button (using user3688529's code) called zipButton and listbox called filesListBox:
Private Sub zipButton_Click(sender As Object, e As EventArgs) Handles zipButton.Click
'Button click events.
'Start backup.
Dim PjtPath As String = TextBox1.Text
Dim ZipLocal As String = TextBox2.Text
Dim ZipNetwk As String = TextBox3.Text
Static Dim StartPath As String
Static Dim ZipPath As String
For Each a As String In filesListBox.SelectedItems()
'Dim PjtName As String = ListBox1.SelectedItems(a).ToString
Dim PjtName As String = a
Dim ZipExt As String = Format(Now, " yyyy-MM-dd # HHmm") & ".zip"
If TextBox2.Text = String.Empty Then
StartPath = PjtPath & "\" & PjtName
ZipPath = PjtPath & "\" & PjtName & ZipExt
ElseIf TextBox2.Text <> String.Empty Then
StartPath = PjtPath & "\" & PjtName
ZipPath = ZipLocal & "\" & PjtName & ZipExt
End If
System.IO.Compression.ZipFile.CreateFromDirectory _
(StartPath, ZipPath, IO.Compression.CompressionLevel.Optimal, True)
If TextBox3.Text <> String.Empty Then
Dim ZipCopy As String = ZipNetwk & "\" & PjtName & ZipExt
My.Computer.FileSystem.CopyFile(ZipPath, ZipCopy)
End If
Next
End Sub
Is there some module I need to include in order for the .ZipFle member to be accessable?
You probably need to add a reference to System.IO.Compression.FileSystem in your project references.
"Project -> Add Reference". Under Framework, find System.IO.Compression.FileSystem.

How find excel.exe path and notpad.exe path

In my application after export excel or csv file then show the file in excel or notepad.
In this case am use
Excel:
Dim xExcelFilePath As String = System.Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\Microsoft Office"
xDir = New DirectoryInfo(xExcelFilePath)
For Each xDirectory As DirectoryInfo In xDir.GetDirectories ' it use for find any version of excel is installed or not
If xDirectory.Name.Count < 6 Then Continue For
If xDirectory.Name.Trim.Substring(0, 6).ToUpper = "OFFICE" Then
If System.IO.File.Exists(xExcelFilePath & "\" & xDirectory.Name & "\EXCEL.EXE") Then
xExcelFilePath = xExcelFilePath & "\" & xDirectory.Name & "\EXCEL.EXE"
Exit For
End If
End If
Next
If System.IO.File.Exists(xExcelFilePath) Then
Dim p As New Process() ' xExcelFilePath means start and stop the local system process
p.StartInfo.UseShellExecute = True
p.StartInfo.WindowStyle = ProcessWindowStyle.Maximized
p.StartInfo.FileName = xExcelFilePath ' Assaign the file name
p.StartInfo.Arguments = """" + xDestinationPath + """"
Grid1.SaveExcel(xDestinationPath, FarPoint.Win.Spread.Model.IncludeHeaders.ColumnHeadersCustomOnly) ' Export the Excel File
p.Start()
Else
Msg.Err("Could not find Excel installed on this system; file saved to:" + xExcelFilePath + ".")
End If
Notepad:
Dim p As New Process() ' xExcelFilePath means start and stop the local system process
p.StartInfo.UseShellExecute = True
p.StartInfo.WindowStyle = ProcessWindowStyle.Maximized
p.StartInfo.FileName = "C:\windows\notepad.exe"
p.StartInfo.Arguments = """" + Application.StartupPath & Grid1.ActiveSheet.SheetName & ".csv" + """"
xCSVSheet.SaveTextFile(Application.StartupPath & Grid1.ActiveSheet.SheetName & ".csv", TextFileFlags.None, Model.IncludeHeaders.BothCustomOnly, "", ",", "")
p.Start()
In above code in some system excel file path not in this order so its throw exception and Notepad exe is staticly added here. How can i get the exe file path in sysem?
Don't worry about the exact path, let Windows handle that. If you want to open a file with Notepad, simply use the following code:
Process.Start("notepad.exe", Application.StartupPath & Grid1.ActiveSheet.SheetName & ".csv")
To start the program maximized, you would have to change it to something like this:
Dim startInfo As New ProcessStartInfo("notepad.exe")
startInfo.WindowStyle = ProcessWindowStyle.Maximized
startInfo.Arguments = """" & Application.StartupPath & Grid1.ActiveSheet.SheetName & ".csv"""
Process.Start(startInfo)
Try this:
Dim excelpath = Registry.GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe", "Path", "Key does not exist")
excelpath= excelpath & "EXCEL.EXE"
Shell(Chr(34) & excelpath & Chr(34) & " " & Chr(34) & FLE & Chr(34), vbNormalFocus)
where in my case FLE is the XML file