How do I speed up searching through files on a network drive and prevent "not responding" in VB.Net - vb.net

Part of my application searches for a string provided by a textbox within .txt files and .pdf files stored on a network drive. It works great on my PC when looking within a directory of a few files stored on a local disk, when I run it on my work PC which is less beefy and looking at a network drive I get "not responding" and it takes a good few minutes to finally wake up again. This is only searching through around 100 files and that number is only going to get bigger.
I thought about adding a progress bar, but if the application is not responding I assume the progress bar will not update? I would be very grateful to hear the advice of someone much more experienced in this than me.
In short, the code searches as described above, uses the name of the folder (that begins with SCC) to add an item to a listbox. If it cannot search the PDF for any reason then it adds it to another listbox displaying the folder names it was unable to search.
Here is the section of code that does the search:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim path As String = ""
Dim list As System.Collections.ObjectModel.ReadOnlyCollection(Of String)
Dim raf As itextsharp.text.pdf.RandomAccessFileOrArray = Nothing
Dim reader As itextsharp.text.pdf.PdfReader = Nothing
Dim searchPhrase As String = faultSearch.Text
VINListBox.Items.Clear()
Region "search plain text"
'finds text within faultSearch textbox within the files in directory
list = My.Computer.FileSystem.FindInFiles(archive_dir, faultSearch.Text, True, FileIO.SearchOption.SearchAllSubDirectories)
For Each foundFile As String In list
path = foundFile
GetVinName(path)
Next
End Region
Region "search PDF"
'Finds text within faultSearch textbox within PDF files in directory
For Each file As String In My.Computer.FileSystem.GetFiles(archive_dir, FileIO.SearchOption.SearchAllSubDirectories)
If System.IO.Path.GetExtension(file).ToUpper = ".PDF" Then
Try
raf = New itextsharp.text.pdf.RandomAccessFileOrArray(file)
reader = New itextsharp.text.pdf.PdfReader(raf, Nothing)
For i As Integer = 1 To reader.NumberOfPages()
Dim pageText As String = itextsharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(reader, i)
If pageText.ToUpper.Contains(searchPhrase) Then
GetVinName(file)
End If
Next
Catch ex As Exception
GetErrVinName(file)
End Try
End If
Next
End Sub
End Region
Private Sub GetVinName(ByVal strVIN As String)
Dim fldName() As String
fldName = Split(strVIN.ToString, "\",, CompareMethod.Text)
For x = 0 To UBound(fldName) - 1
If InStr(fldName(x), "SCC", CompareMethod.Text) > 0 Then
strVIN = Trim(fldName(x))
If errListBox.Items.Contains(strVIN) = True Then
errListBox.Items.Remove(strVIN)
End If
If VINListBox.Items.Contains(strVIN) = False Then
VINListBox.Items.Add(strVIN)
End If
Exit For
End If
Next
End Sub
Private Sub GetErrVinName(ByVal strVIN As String)
Dim fldName() As String
fldName = Split(strVIN.ToString, "\",, CompareMethod.Text)
For x = 0 To UBound(fldName) - 1
If InStr(fldName(x), "SCC", CompareMethod.Text) > 0 Then
strVIN = Trim(fldName(x))
If VINListBox.Items.Contains(strVIN) = False Then
If errListBox.Items.Contains(strVIN) = False Then
errListBox.Items.Add(strVIN)
Else
Exit Sub
End If
Else
Exit Sub
End If
Exit For
End If
Next
End Sub

Related

How to turn off automatic updating of fields in the Microsoft Word?

I have a simple vsto addin for word which allows me to select one or more pictures from disk then it inserts them into the current document. It works just fine and I have no problems with it. However, each time it inserts a picture word updates all fields in the document. Once the document has a hundred or so pictures this gets pretty time consuming. I need to turn off the auto updating of fields while these pictures are being inserted, then turn it back on when done.
What I have tried is this:
Adding this line at program start,
Globals.ThisAddIn.Application.ActiveDocument.Fields.Locked = True
Adding these lines at program end,
Globals.ThisAddIn.Application.ActiveDocument.Fields.Locked = False
Globals.ThisAddIn.Application.ActiveDocument.Fields.Update()
but word still updates ALL the fields in the document with each picture insertion. Is there some other method to accomplish this?
Thanks
Edit: this is the code that inserts the images
Sub ImportPictures()
Dim strPics As String = String.Empty
Dim arrPics() As String
Dim i As Long
Dim vrtSelectedItem As Object = Nothing
Dim tek As Microsoft.Office.Interop.Word.InlineShape = Nothing
Dim picName As String = String.Empty
Globals.ThisAddIn.Application.ActiveDocument.Fields.Locked = True
'Open up a file browser so user can choose the spreadsheet for the part
Try
Using OpenFileDialog1 As New OpenFileDialog()
OpenFileDialog1.InitialDirectory = "c:\\"
OpenFileDialog1.Filter = "Images (*.gif;*.jpg;*.jpeg;*.png;*.bmp)|*.gif;*.jpg;*.jpeg;*.png;*.bmp"
OpenFileDialog1.FilterIndex = 1
OpenFileDialog1.RestoreDirectory = True
OpenFileDialog1.Multiselect = True
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
For Each vrtSelectedItem In OpenFileDialog1.FileNames
strPics = strPics & "|" & vrtSelectedItem
Next vrtSelectedItem
strPics = Mid(strPics, 2)
arrPics = Split(strPics, "|")
System.Array.Sort(arrPics)
For i = 0 To UBound(arrPics)
picName = Right(arrPics(i), Len(arrPics(i)) - InStrRev(arrPics(i), "\"))
tek.LockAspectRatio = True
tek.ScaleHeight = 32.3
tek.Select()
Globals.ThisAddIn.Application.ActiveDocument.Paragraphs.Format.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphCenter
Globals.ThisAddIn.Application.Selection.InsertCaption(Label:="Figure", Title:=": " & picName, Position:=word.WdCaptionPosition.wdCaptionPositionBelow)
Globals.ThisAddIn.Application.Selection.Collapse(word.WdCollapseDirection.wdCollapseEnd)
Globals.ThisAddIn.Application.Selection.TypeParagraph()
Next i
Else
MsgBox("User pressed Cancel.")
End If
End Using
Globals.ThisAddIn.Application.ActiveDocument.Fields.Locked = False
Globals.ThisAddIn.Application.ActiveDocument.Fields.Update()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.SystemModal, "Error")
End Try
End Sub
ActiveDocument.Fields.Locked can only affect fields that exist in the document when that code line is executed. Unless you loop through all story ranges, it will also only affect fields in the document body. If you add another field whose property is 'hot' (see https://support.microsoft.com/en-us/topic/which-fields-are-updated-when-you-open-repaginate-or-print-document-e9580e16-7239-5263-83a4-061a27210076), it will update as soon as you insert it. Running ActiveDocument.Fields.Locked again will only prevent further updates.

Trying to delete a line in a text file -VB

I'm very new to coding so any help is appreciated.
I've created a simple listbox that displays an array from a text file.
I wanted to add a textbox and a delete button so the user can type a word and then delete that line from the text file.
I've read many forums with various solutions for this but all have returned errors - currently I am getting this error: "System.IO.IOException: 'The process cannot access the file 'C:\Users\hches\source\repos\Inventory\Inventory\bin\Debug\Stock.txt' because it is being used by another process.'"
in sub DeleteLine()
Here is the relevant code to the Delete button and the respective DeleteLine() sub:
Private Sub BTDel_Click(sender As Object, e As EventArgs) Handles BTDel.Click
Dim sr As New StreamReader("Stock.txt")
Dim i As Integer = 0
Dim deleted As Boolean = False
If TBSearch.Text = "" Then
MsgBox("Please enter an Item to Delete.")
Else
Do Until sr.Peek() = -1 Or deleted = True 'prevents it from looping through the whole stock if the item is deleted
Dim Itm As String = sr.ReadLine()
If Itm.Contains(TBSearch.Text) Or Itm.ToLower.Contains(TBSearch.Text.ToLower) Then 'if the line read from the text contains the search word, continue
MsgBox(TBSearch.Text & " has been deleted.") 'simple messagebox says it has been deleted
DeleteLine()
deleted = True
TBSearch.Clear()
ElseIf sr.Peek() = -1 Then 'if it reaches the end of the document and it hasn't been found
MsgBox("Item has not been deleted.") 'message box appears saying it is not deleted
deleted = False
TBSearch.Clear()
End If
i = i + 1
Loop
End If
End Sub
Public Sub DeleteLine()
Dim line As Integer = 0
Dim Filename = "Stock.txt"
Dim TheFileLines As New List(Of String)
For line = 0 To TheFileLines.Count
TheFileLines.AddRange(System.IO.File.ReadAllLines(Filename))
' if line is beyond end of list then exit sub
If line >= TheFileLines.Count Then Exit Sub
TheFileLines.RemoveAt(line)
System.IO.File.WriteAllLines(Filename, TheFileLines.ToArray)
Next
End Sub
Many thanks for any guidance,
Henry
SOLVED -- For anyone interested I will post my solution, thanks for the help.
Public Sub DeleteLine()
ArrayLoad() 'populates my array from text file
File.Delete("Stock.txt") 'deletes original text file
Dim stockList As List(Of String) = ItemNames.ToList 'creates a list using my array
stockList.Remove(TBSearch.Text) 'removes the searched item from the list
File.Create("Stock.txt").Dispose() 'creates a new text file (same name as the original so the program will work fine)
Using sw As New StreamWriter("Stock.txt") 'sets up a streamwriter to write the new list to the text file
For Each item As String In stockList
sw.WriteLine(item)
Next
sw.Flush()
sw.Close()
End Using
End Sub
End Class

How to Save, Separate, and Write Data from File to Multiple TextBoxes

I need to save a bunch (around 600) of TextBox content to a (Preferably) single file, then be able to write that data back to their respective TextBoxes on file open. Essentially I'm making a D&D stat sheet, and I want to save what each player has entered as the [character's name].txt. I already got simple saving and writing down by using a single control and the code:
Dim SaveCharacter As StreamWriter
If txtName.Text = "" Then
MessageBox.Show("In order to save, you must enter a name for your character.", "Error: No Name Entered")
Else
Try
SaveCharacter = File.AppendText("H:\Visual Basic Projects\DAndD-2.5\DAndD-2.5\Saves\" & txtName.Text & ".txt")
SaveCharacter.WriteLine(frmNotes.rtxNotes.Text)
SaveCharacter.Close()
Catch
MessageBox.Show("Error")
End Try
End If
'Next event handler
Dim OpenCharacter As StreamReader
OpenCharacter = File.OpenText("H:\Visual Basic Projects\DAndD-2.5\DAndD-2.5\Saves\Jared.txt")
Do Until OpenCharacter.EndOfStream
frmNotes.rtxNotes.Text = OpenCharacter.ReadToEnd.ToString()
For Each strLine As String In frmNotes.rtxNotes.Text.Split(vbNewLine)
Next
Loop
Is there an easy(ish) way to do what I need, especially in mass (few lines of code) without having to save each TextBox as a different .txt file?
Thanks for the help!
Loop through all the controls and pull out the TextBoxes:
Sub SaveFile(strFilename As String)
Using fs As New System.IO.FileStream(strFilename, IO.FileMode.OpenOrCreate)
Using sr As New System.IO.StreamWriter(fs)
For Each ctl As Control In Me.Controls
If TypeOf ctl Is TextBox Then
Dim txt As TextBox = DirectCast(ctl, TextBox)
sr.WriteLine(txt.Name & ":" & txt.Text)
End If
Next ctl
End Using
End Using
End Sub
Sub Readfile(strfilename As String)
Using fs As New System.IO.FileStream(strfilename, IO.FileMode.Open)
Using sr As New System.IO.StreamReader(fs)
Do Until sr.EndOfStream
Dim strLine As String = sr.ReadLine
Dim colonposition As Integer = strLine.IndexOf(":")
If colonposition > 0 And colonposition < strLine.Length - 1 Then
Dim strTextBoxName As String = strLine.Substring(0, colonposition)
Dim strTextBoxText As String = strLine.Substring(colonposition + 1)
Dim ctl() As Control = Me.Controls.Find(strTextBoxName, False)
If ctl.Length > 0 AndAlso TypeOf ctl(0) Is TextBox Then
DirectCast(ctl(0), TextBox).Text = strTextBoxText
End If
End If
Loop
End Using
End Using
End Sub
The above code only works for textboxes on the form itself. You can rework it to be a recursive function to walk the containers, but I'll leave that as an exercise for the reader.
This will write the contents of all your TextBoxes to a file, one line per control:
IO.File.WriteAllLines(filePath, Me.Controls.OfType(Of TextBox).Select(Function(tb) tb.Text))
This will read a file back into those TextBoxes:
Dim textBoxes = Me.Controls.OfType(Of TextBox).ToArray()
Dim lines = IO.File.ReadAllLines(filePath)
For i = 0 To lines.GetUpperBound(0)
textBoxes(i).Text = lines(i)
Next
That assumes that no TextBoxes are multi-line and it also does not validate the file on reading, so you might want to check that the number of lines and TextBoxes matches.

how to to check two files for any lines that match another file

I'm making antivirus script that compare signatures to file it search right now I'm only testing one file at a time to see if it works. I got it to work in python but i want to write the script in vb.net
Dim fname
OpenFileDialog1.ShowDialog()
fname = OpenFileDialog1.FileName
Dim virus = System.IO.File.ReadLines("C:\Users\joeblow\Desktop\virussignatures.txt")
Dim text = System.IO.File.ReadLines(fname)
Dim reuslts = String.Compare(virus.ToString, text.ToString)
If reuslts.ToString Then
lstVirusFiles.Items.Add(fname)
Else
lstCleanFiles.Items.Add(fname)
End If
I have try If String.Compare(virus.ToString, text.ToString) = True Then
and If String.Compare(virus.ToString, text.ToString) then
I even try this If text.Contains(virus.ToString) Then
I was wondering if someone can point me in the right direction thank you.
Try below
Dim fname
If OpenFileDialog1.ShowDialog() <> Windows.Forms.DialogResult.OK Then
Return
'Or Throw error
End If
fname = OpenFileDialog1.FileName
Dim virus = System.IO.File.ReadLines("C:\Users\joeblow\Desktop\virussignatures.txt")
Dim text = System.IO.File.ReadAllText(fname)
Dim found As Boolean = False
For Each signature In virus
If text.IndexOf(signature, 0, StringComparison.CurrentCultureIgnoreCase) > -1 Then
lstVirusFiles.Items.Add(fname)
found = True
Exit For
End If
Next
If found Then
lstVirusFiles.Items.Add(fname)
Else
lstCleanFiles.Items.Add(fname)
End If

Visual Basic - Selecting values from a string and defining them as something

I have a log file in txt, inside are strings of information. one string looks like this:
49000 120614 12334480 12 32 2 90 90 90 321 384 2 345 873 890
each value between the spaces represents something in specific, (e.g the second line "120614" is the date "12 June 2014") I am writing a program where I load the txt file into it, and then when i click a certain button it will take this string and put all the values into a specific text box, for instance, "Date = 12 06 2014". I have been researching how to find a certain line and declare that line with its contents as something, but I have not found the answer!! I am using Visual Basic to write it, and I really need help with what direction to take, will stramreader be able to do this?? What function am I looking for?
Here is my code for loading the file.. Just incase.
Public Class Form1
Private Sub browsebtn1_Click(sender As Object, e As EventArgs) Handles browsebtn1.Click
Dim filedialog As New OpenFileDialog 'openfiledialog1 is now filedialog'
filedialog.Filter = "Text Document|*.txt" 'filter the openfiledialogs file extension to txt only'
filedialog.Title = "Select Bosvark Log File.." 'openfiledialog title'
If filedialog.ShowDialog = Windows.Forms.DialogResult.OK Then 'if the file is chosen then..'
filepath1.Text = filedialog.FileName 'filepath1 text is file path of selected file'
RichTextBox1.LoadFile(filepath1.Text, RichTextBoxStreamType.PlainText) 'richtextbox1 retrieves the file path and displays the document'
End If
End Sub
Private Sub convertbtn_Click(sender As Object, e As EventArgs) Handles convertbtn.Click
If RichTextBox1.Text = "" Then
MessageBox.Show("Please load a file first!") 'If user doesnt load a file, give them an error message.'
End If
End Sub
Private Sub RichTextBox1_TextChanged(sender As Object, e As EventArgs) Handles RichTextBox1.TextChanged
If RichTextBox1.Text = "" Then
RichTextBox1.Visible = False 'If there is no file loaded, The textbox will not appear.'
Else
RichTextBox1.Visible = True 'if the file is loaded, textbox will appear.'
End If
End Sub
End Class
you can load the contents of the file to a string variable (if the file isnt too large)
Dim intFile As Integer
Dim strFile As String
Dim strData As String
intFile = FreeFile
strFile = "c:\temp\file.txt"
Open strFile For Input As #intFile
strData = Input(LOF(intFile), #intFile)
Close #intFile
you can split all the data into an array per line
Dim strLine() As String
strLine = Split(strData)
you can loop over all lines to perform some action on all lines
Dim lngLine As Long
For lngLine = 0 To UBound(strLine)
'do action
Next lngLine
or just perform an action on one specific line:
dim strField() as String
'split line into array separated per spaces
strField = Split(strLine(lngLine), " ")