If possible to cotinue a For Each loop after an error jump in VB.NET? - vb.net

I have a BackGroundWorker with a For Each loop that is inside of a Try Catch and I need to detect the error and continue the For Each loop whit the next item.
Actually I have a list of data to send to a server trough UDP and wait for an ACK, but if the server didn't answer in 5 seconds the timeout error is cachet and the whole process is aborted.
I need to do something like this
Dim MyData_Array As String()
For Each MyData As String In MyData_Array
MyData_Actual = MyData
' Translate the passed message into ASCII and store it as a Byte array.
Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(MyData)
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
If data.Length = 67 Then
XMyData += 1
Dim Tx As New UdpClient()
Tx.Connect(Host, Port)
Tx.Client.SendTimeout = 5000
Tx.Client.ReceiveTimeout = 5000
Tx.Send(data, data.Length)
data = Tx.Receive(RemoteIpEndPoint)
Tx.Close()
Else
MyData_ErrorList += MyData & vbCrLf
End If
'Report progress
Porcentaje = (XMyData * 100) / MyData_Array.Count
BackgroundWorker1.ReportProgress(Porcentaje, "Sending MyData " & XMyData.ToString & " de " & MyData_Array.Count.ToString & " : " & MyData)
If BackgroundWorker1.CancellationPending Then
e.Cancel = True
Exit For
End If
Next
End If
Catch ex As TimeoutException
MyData_ErrorList += MyData_Actual & vbCrLf
'**********************************************************
'Here need to delay 100mS and get back to the For Each to process the next item
'**********************************************************
Catch ex As Exception
MyData_List = ex.Message & vbCrLf & "StackTrace: " & ex.StackTrace & vbCrLf & MyData_List
End Try

Put the Try/Catch inside the for loop.
Dim MyData_Array As String()
For Each MyData As String In MyData_Array
Try
MyData_Actual = MyData
' Translate the passed message into ASCII and store it as a Byte array.
Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(MyData)
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
If data.Length = 67 Then
XMyData += 1
Dim Tx As New UdpClient()
Tx.Connect(Host, Port)
Tx.Client.SendTimeout = 5000
Tx.Client.ReceiveTimeout = 5000
Tx.Send(data, data.Length)
data = Tx.Receive(RemoteIpEndPoint)
Tx.Close()
Else
MyData_ErrorList += MyData & vbCrLf
End If
'Report progress
Porcentaje = (XMyData * 100) / MyData_Array.Count
BackgroundWorker1.ReportProgress(Porcentaje, "Sending MyData " & XMyData.ToString & " de " & MyData_Array.Count.ToString & " : " & MyData)
If BackgroundWorker1.CancellationPending Then
e.Cancel = True
Exit For
End If
Catch ex As TimeoutException
MyData_ErrorList += MyData_Actual & vbCrLf
Catch ex As Exception
MyData_List = ex.Message & vbCrLf & "StackTrace: " & ex.StackTrace & vbCrLf & MyData_List
'If you want to exit the For loop on generic exceptions, uncomment the following line
'Exit For
End Try
Next

You might consider putting the try catch inside the for loop, if the iterative collection is not modified somehow by the error. Then handle the exception and continue the for loop.
How you have your loop and try/catch setup now will cause the entire loop to be broken out of on the timeout exception since the try/catch is placed outside the loop.
The your code would look more like this:
For Each MyData As String In MyData_Array
Try
'Perform code for each loop iteration
Catch ex As TimeoutException
'Handle Exception Here
End Try
Next

Related

"Response received is incomplete"

So I reversed the syntax of this send sms code from c# to vb net so I can reuse it.
The code works sometimes, but for some reason it would often give me the "response received is incomplete" exception.
I was thinking perhaps my code is processing commands faster than my GSM device, could handle, so I tried increasing the timeout response for the serial port, still ends up with this exception.
What do you think is the problem and what would you recommend I do to solve it?
Public Class SmsHelper
Public receiveNow As AutoResetEvent
#Region "Open and Close Ports"
'Open Port
Public Function OpenPort(portName As String, baudRate As Integer, dataBits As Integer, readTimeout As Integer, writeTimeout As Integer) As SerialPort
receiveNow = New AutoResetEvent(False)
Dim port As New SerialPort()
Try
port.PortName = portName
'COM1
port.BaudRate = baudRate
'9600
port.DataBits = dataBits
'8
port.StopBits = StopBits.One
'1
port.Parity = Parity.None
'None
port.ReadTimeout = readTimeout
'300
port.WriteTimeout = writeTimeout
'300
port.Encoding = Encoding.GetEncoding("iso-8859-1")
port.NewLine = vbCrLf
AddHandler port.DataReceived, AddressOf port_DataReceived
port.Open()
port.DtrEnable = True
port.RtsEnable = True
Catch ex As Exception
Throw ex
End Try
Return port
End Function
' Send AT Command
Public Function SendATCommand(port As SerialPort, command As String, responseTimeout As Integer, errorMessage As String) As String
Try
port.DiscardOutBuffer()
port.DiscardInBuffer()
receiveNow.Reset()
port.Write(command & Convert.ToString(vbCrLf))
Dim input As String = ReadResponse(port, responseTimeout)
Console.WriteLine("Received data is " & input)
If (input.Length = 0) OrElse ((Not input.EndsWith(vbCr & vbLf & "> ")) AndAlso (Not input.EndsWith(vbCr & vbLf & "OK" & vbCr & vbLf))) Then
Throw New ApplicationException("No success message was received.")
End If
Return input
Catch ex As Exception
Throw ex
Finally
End Try
End Function
'Receive data from port
Public Sub port_DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
Try
If e.EventType = SerialData.Chars Then
receiveNow.[Set]()
End If
Catch ex As Exception
Throw ex
End Try
End Sub
Public Function ReadResponse(port As SerialPort, timeout As Integer) As String
Dim serialPortData As String = ""
Try
Do
If receiveNow.WaitOne(timeout, False) Then
Dim data As String = port.ReadLine()
serialPortData += data
Else
'Console.WriteLine("SerialPortData data is " & serialPortData)
If serialPortData.Length > 0 Then
Console.WriteLine("SerialPortData is " & serialPortData.ToString)
Throw New ApplicationException("Response received is incomplete.")
Else
Throw New ApplicationException("No data received from phone.")
End If
End If
Loop While Not serialPortData.EndsWith(vbCr & vbLf & "OK" & vbCr & vbLf) AndAlso Not serialPortData.EndsWith(vbCr & vbLf & "> ") AndAlso Not serialPortData.EndsWith(vbCr & vbLf & "ERROR" & vbCr & vbLf)
Catch ex As Exception
Throw ex
End Try
Return serialPortData
End Function
Shared readNow As New AutoResetEvent(False)
Public Function SendMessage(port As SerialPort, phoneNo As String, message As String) As Boolean
Dim isSend As Boolean = False
Try
Dim recievedData As String = SendATCommand(port, "AT", 3000, "No phone connected")
Dim command As String = "AT+CMGF=1" + Char.ConvertFromUtf32(13)
recievedData = SendATCommand(port, command, 3000, "Failed to set message format.")
' AT Command Syntax - http://www.smssolutions.net/tutorials/gsm/sendsmsat/
command = (Convert.ToString("AT+CMGS=""") & phoneNo) + """" + Char.ConvertFromUtf32(13)
recievedData = SendATCommand(port, command, 3000, "Failed to accept phoneNo")
'wait(2)
command = message & Char.ConvertFromUtf32(26)
recievedData = SendATCommand(port, command, 3000, "Failed to send message")
Console.WriteLine("Received data is " & recievedData)
If recievedData.EndsWith(vbCr & vbLf & "OK" & vbCr & vbLf) Then
isSend = True
ElseIf recievedData.Contains("ERROR") Then
isSend = False
End If
Return isSend
Catch ex As Exception
Throw ex
End Try
End Function
Private Shared Sub DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
Try
If e.EventType = SerialData.Chars Then
readNow.[Set]()
End If
Catch ex As Exception
Throw ex
End Try
End Sub
#End Region
End Class

Timer to skip to connect to next computer in for each loop while connecting remotely using RegistryKey.OpenRemoteBaseKey

I built a tool (with Visual Studio 2015 Express - Visual Basic) that will check the mcafee dat version and date from the registry on computers input either manually, in a text file, or selected from active directory. The tool works it successfully returned all the information for 714 out of 970 computers/laptops. The majority of the failures were either because they could not be resolved in DNS or weren't pingable and the tools identifies those and successfully logs them. It took a little over 15 minutes for the tool to retrieve the information and log it in a spreadsheet. The issue is that on 19 of the failures I got one of the two following errors and those 19 took the majority of the 15 minutes for the tool get and log all the information:
Attempted to perform an unauthorized operation
The network path was not found
Is there a way of using a timer so that the program will attempt to connect to the registry at this point... rk1 = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, strComputer, RegistryView.Registry64) and then after a certain amount of time stop and move to the next computer in the for each loop? I have only been programming for a little over a year and I have learned exclusively through trial/error and google so please have patience with me as I am not a seasoned programmer. Here is the code:
The program works well my objective here is to improve it by making it skip to the next computer when it hangs for an extended period of time. I have filtered out the computers that can't be resolved in DNS or aren't pingable.
For Each sel In picker.SelectedObjects
Try
If HostIsResolvable(sel.Name) Then
Try
reply = ping.Send(sel.Name, 1)
If reply.Status = IPStatus.Success Then
IPAddr = reply.Address.ToString()
Try
comsys(sel.Name)
Dim rk1 As RegistryKey
Dim rk2 As RegistryKey
rk1 = RegistryKey.OpenRemoteBaseKey
(RegistryHive.LocalMachine, sel.Name,
RegistryView.Registry64)
rk2 = rk1.OpenSubKey
("SOFTWARE\Wow6432Node\McAfee\AVEngine")
mAV = rk2.GetValue("AVDatVersion").ToString
mAD = rk2.GetValue("AVDatDate").ToString
objExcel.Cells(y, 1) = sel.Name
objExcel.Cells(y, 2) = IPAddr
objExcel.Cells(y, 3) = commodel
objExcel.Cells(y, 4) = comuser
objExcel.Cells(y, 5) = "DAT Version Number: " & mAV
objExcel.Cells(y, 6) = "DAT Date: " & mAD
y = y + 1
Catch ex As Exception
My.Computer.FileSystem.WriteAllText(Dell
& "\McAfeeDATeNumFailed.txt", sel.Name & "-Unable to
connect. Make sure this computer is on the network,
has remote administration enabled, and that both
computers are running the remote registry service.
Error message: " & ex.Message & vbCrLf, True)
End Try
Else
My.Computer.FileSystem.WriteAllText(Dell
& "\McAfeeDATeNumFailed.txt", sel.Name & " is not
pingable! " & vbCrLf, True)
End If
Catch ex As Exception
My.Computer.FileSystem.WriteAllText(Dell
& "\McAfeeDATeNumFailed.txt", sel.Name & "Ping error:
Unable to connect. Make sure this computer is on the
network, has remote administration enabled, and that
both computers are running the remote registry
service. Error message: " & ex.Message & vbCrLf, True)
End Try
Else
My.Computer.FileSystem.WriteAllText(Dell
& "\McAfeeDATeNumFailed.txt", sel.Name & " could not be
resolved in DNS! " & vbCrLf, True)
End If
Catch ex As Exception
My.Computer.FileSystem.WriteAllText(Dell
& "\McAfeeDATeNumFailed.txt", sel.Name & "DNS error: Unable to
connect. Make sure this computer is on the network, has remote
administration enabled, andd that both computers are running the
remote registry service. Error message: " & ex.Message &
vbCrLf, True)
End Try
sel = Nothing
Next
You need to put your request in another thread. This thread can be aborted.
Sub Main()
Dim thrd As New Thread(AddressOf endlessLoop) 'thread with your sub
thrd.Start() 'Start thread
thrd.Join(1000) 'Block until completion or timeout
If thrd.IsAlive Then
thrd.Abort() 'abort thread
Else
'thread finished already
End If
End Sub
Sub endlessLoop()
Try
While True
'Your Code
End While
Catch ex As ThreadAbortException
'Your code when thread is killed
End Try
End Sub
Hope this helps.
'***** EDIT ***
Your code could look like this (I didn't checked if there are any variables to pass in Sub)
For Each sel In picker.SelectedObjects
Try
If HostIsResolvable(sel.Name) Then
Try
reply = ping.Send(sel.Name, 1)
If reply.Status = IPStatus.Success Then
IPAddr = reply.Address.ToString()
call timerThread 'New
Else
My.Computer.FileSystem.WriteAllText(Dell
& "\McAfeeDATeNumFailed.txt", sel.Name & " is not
pingable! " & vbCrLf, True)
End If
Catch ex As Exception
My.Computer.FileSystem.WriteAllText(Dell
& "\McAfeeDATeNumFailed.txt", sel.Name & "Ping error:
Unable to connect. Make sure this computer is on the
network, has remote administration enabled, and that
both computers are running the remote registry
service. Error message: " & ex.Message & vbCrLf, True)
End Try
Else
My.Computer.FileSystem.WriteAllText(Dell
& "\McAfeeDATeNumFailed.txt", sel.Name & " could not be
resolved in DNS! " & vbCrLf, True)
End If
Catch ex As Exception
My.Computer.FileSystem.WriteAllText(Dell
& "\McAfeeDATeNumFailed.txt", sel.Name & "DNS error: Unable to
connect. Make sure this computer is on the network, has remote
administration enabled, andd that both computers are running the
remote registry service. Error message: " & ex.Message &
vbCrLf, True)
End Try
sel = Nothing
Next
Sub timerThread()
Dim thrd As New Thread(AddressOf registryRequest) 'thread with your sub
thrd.Start() 'Start thread
thrd.Join(15000) 'Block until completion or timeout (15 seconds)
If thrd.IsAlive Then
thrd.Abort() 'abort thread
Else
'thread finished already
End If
End Sub
Sub registryRequest()
Try
comsys(sel.Name)
Dim rk1 As RegistryKey
Dim rk2 As RegistryKey
rk1 = RegistryKey.OpenRemoteBaseKey
(RegistryHive.LocalMachine, sel.Name,
RegistryView.Registry64)
rk2 = rk1.OpenSubKey
("SOFTWARE\Wow6432Node\McAfee\AVEngine")
mAV = rk2.GetValue("AVDatVersion").ToString
mAD = rk2.GetValue("AVDatDate").ToString
objExcel.Cells(y, 1) = sel.Name
objExcel.Cells(y, 2) = IPAddr
objExcel.Cells(y, 3) = commodel
objExcel.Cells(y, 4) = comuser
objExcel.Cells(y, 5) = "DAT Version Number: " & mAV
objExcel.Cells(y, 6) = "DAT Date: " & mAD
y = y + 1
Catch ex As ThreadAbortException
My.Computer.FileSystem.WriteAllText(Dell
& "\McAfeeDATeNumFailed.txt", sel.Name & "-Unable to
connect. Make sure this computer is on the network,
has remote administration enabled, and that both
computers are running the remote registry service.
Error message: " & ex.Message & vbCrLf, True)
End Try
End Sub
This works great but I am sure it can be improved so please respond with suggestions if you have them. Here is the code:
Try
Dim source1 As New CancellationTokenSource
Dim token As CancellationToken = source1.Token
Dim T20 As Task = Task.Factory.StartNew(Function() getping((sel.Name), token))
T20.Wait(30)
If T20.Status = TaskStatus.Running Then
source1.Cancel()
My.Computer.FileSystem.WriteAllText(Dell & "\McAfeeDATeNumFailed.txt", sel.Name & " Ping timed out. The task was disposed of at " & ex_time & "." & vbCrLf & vbCrLf, True)
End If
Dim source2 As New CancellationTokenSource
Dim token2 As CancellationToken = source2.Token
Dim T21 As Task = Task.Factory.StartNew(Function() comsys((sel.Name), token2))
T21.Wait(500)
If T21.Status = TaskStatus.Running Then
source2.Cancel()
My.Computer.FileSystem.WriteAllText(Dell & "\McAfeeDATeNumFailed.txt", sel.Name & " RPC error. The task was disposed of at " & ex_time & "." & vbCrLf & vbCrLf, True)
End If
Dim source3 As New CancellationTokenSource
Dim token3 As CancellationToken = source3.Token
Dim T22 As Task = Task.Factory.StartNew(Function() getregvalues((sel.Name), token3))
T22.Wait(600)
If T22.Status = TaskStatus.Running Then
source3.Cancel()
My.Computer.FileSystem.WriteAllText(Dell & "\McAfeeDATeNumFailed.txt", sel.Name & " Error retrieving registry value. The task was disposed of at " & ex_time & "." & vbCrLf & vbCrLf, True)
End If
IPAddr = reply.Address.ToString()
objExcel.Cells(y, 1) = sel.Name
objExcel.Cells(y, 2) = IPAddr
objExcel.Cells(y, 3) = commode
objExcel.Cells(y, 4) = comuser
objExcel.Cells(y, 5) = "DAT Version Number: " & mAV
objExcel.Cells(y, 6) = "DAT Date: " & mAD
y = y + 1
IPAddr = Nothing
reply = Nothing
commodel = Nothing
comuser = Nothing
sel = Nothing
Thread.Sleep(10)
Catch ex As Exception
End Try
I will try that and time it both ways. I added a continue for here and it cut it from 6 and a half minutes down to 3 and a half minutes (if it wasn't pingable then move on to the next computer instead of running the other 2 tasks).
If T20.Status = TaskStatus.Running Then
source1.Cancel()
Continue For
End If
I started to change the wait to a loop and I remembered that it takes that amount of time to successfully retrieve the remote information and get it into excel without missing data in the excel spreadsheet. For example I dropped the time to 10 ms and some of the computers didn't respond to the ping fast enough so that computer and it's information wasn't added to the spreadsheet. Likewise, I reduced the ms on the registry task and the registry information for that computer was missing in the spreadsheet.

vb.net mutex class throw exception error

I found error code "The wait completed due to abandoned mutex..Can anyone give me any idea on how to solve it?
Here is the code:
Try
gcLog.log(" UseResource Start[1]")
ltWaitTimeSpan = New System.TimeSpan(0, 0, 20)
gcLog.log(" UseResource Start[3]")
If mut.WaitOne(ltWaitTimeSpan, True) Then
Thread_Status = True
Thread_Status_Chk_Count = 0
gcLog.log(Thread.CurrentThread.Name + " Thread Start !!![2]")
lsWorkInstID = Thread.CurrentThread.Name
gcCommon.IsWorkSheetIDExist(Thread.CurrentThread.Name)
gcMsgQue.mnDisMsgInfo2Label_Active(lsWorkInstID)
gcLog.log(" UseResource Start[2]")
Dim loSeqManage As clsSeqManage
loSeqManage = New clsSeqManage
If Not loSeqManage.bReadMsgFmDb(lsWorkInstID, lsLotID) Then
'gcLog.log(" UseResource Start[3]")
Thread_Status = False
Else
Dim loOutput2Prt As New clsOutput(lsLotID,gtMsgQueueEvent.sCryFileName)
loOutput2Prt.SetVariable()
'gcLog.log(" UseResource Start[4]")
If (loOutput2Prt.Output2PrtAuto And Not loOutput2Prt.GetMoreBatchFlag)
Then
gcLog.log(Thread.CurrentThread.Name + " Delete Record !!!")
Call loOutput2Prt.bDeleteMsgFmBuf()
End If
gcLog.log(Thread.CurrentThread.Name + " Thread Release !!![22]")
Thread_Status = False
mut.ReleaseMutex()
End If
End If
Catch ex As Exception
gcLog.log("UseResource : " + ex.Message & vbLf & ex.TargetSite.Name)
Call gfncCallError("2", "PrintFormServer", "UseResource : " + ex.Message & ""& ex.TargetSite.Name)
Thread_Status = False
End Try

Finding And Removing Duplicates from text file using vb.net

I have a huge text file in which a large number of duplication are occurred. The duplications are as follows.
Total Posts 16
Pin Code = GFDHG
TITLE = Shop Signs/Projection Signs/Industrial Signage/Restaurant signs/Menu Boards&Box in London
DATE = 12-09-2012
Tracking Key # 85265E712050-15207427406854753
Total Posts 16
Pin Code = GFDHG
TITLE = Shop Signs/Projection Signs/Industrial Signage/Restaurant signs/Menu Boards&Box in London
DATE = 12-09-2012
Tracking Key # 85265E712050-15207427406854753
Total Posts 2894
Pin Code = GFDHG
TITLE = Shop Signs/Projection Signs/Industrial Signage/Restaurant signs/Menu Boards&Box in London
DATE = 15-09-2012
Tracking Key # 85265E712050-152797637654753
Total Posts 2894
Pin Code = GFDHG
TITLE = Shop Signs/Projection Signs/Industrial Signage/Restaurant signs/Menu Boards&Box in London
DATE = 15-09-2012
Tracking Key # 85265E712050-152797637654753
and so on upto 4000 total posts are there in this text file. I want that my program match the total post 6 to all total post that occurred in file and where find the duplicate , then programatically remove that duplicate and also delete the next 7 lines of that duplicate. Thank you
Assuming the formatting is consistent (i.e. each logged event in the file uses 6 total lines of text), then if you're looking to remove duplicates from the file you just need to do something like this:
Sub DupClean(ByVal fpath As String) 'fpath is the FULL file path, i.e. C:\Users\username\Documents\filename.txt
Dim OrigText As String = ""
Dim CleanText As String = ""
Dim CText As String = ""
Dim SReader As New System.IO.StreamReader(fpath, System.Text.Encoding.UTF8)
Dim TxtLines As New List(Of String)
Dim i As Long = 0
Dim writer As New System.IO.StreamWriter(Left(fpath, fpath.Length - 4) & "_clean.txt", False) 'to overwrite the text inside the same file simply use StreamWriter(fpath)
Try
'Read in the text
OrigText = SReader.ReadToEnd
'Parse the text at new lines to allow selecting groups of 6 lines
TxtLines.AddRange(Split(OrigText, Chr(10))) 'may need to change the Chr # to look for depending on if 10 or 13 is used when the file is generated
Catch ex As Exception
MsgBox("Encountered an error while reading in the text file contents and parsing them. Details: " & ex.Message, vbOKOnly, "Read Error")
End
End Try
Try
'Now we iterate through blocks of 6 lines
Do While i < TxtLines.Count
'Set CText to the next 6 lines of text
CText = TxtLines.Item(i) & Chr(10) & TxtLines.Item(i + 1) & Chr(10) & TxtLines.Item(i + 2) & Chr(10) & TxtLines.Item(i + 3) & Chr(10) & TxtLines.Item(i + 4) & Chr(10) & TxtLines.Item(i + 5)
'Check if CText is already present in CleanText
If Not (CleanText.Contains(CText)) Then
'Add CText to CleanText
If CleanText.Length = 0 Then
CleanText = CText
Else
CleanText = CleanText & Chr(10) & CText
End If
End If 'else the text is already present and we don't need to do anything
i = i + 6
Loop
Catch ex As Exception
MsgBox("Encountered an error while running cleaning duplicates from the read in text. The application was on the " & i & "-th line of text when the following error was thrown: " & ex.Message, _
vbOKOnly, "Comparison Error")
End
End Try
Try
'Write out the clean text
writer.Write(CleanText)
Catch ex As Exception
MsgBox("Encountered an error writing the cleaned text. Details: " & ex.Message & Chr(10) & Chr(10) & "The cleaned text was " & CleanText, vbOKOnly, "Write Error")
End Try
End Sub
If the format isn't consistent you'll need to get fancier and define rules to tell which lines to add to CText on any given pass through the loop, but without context I wouldn't be able to give you any ideas as to what those may be.

Vb.net Journal Program Issue

Okay so for an internship project i'm making a Journal with streamwriters and streamreaders.
I have to to where you can create an account with a name, Username, and Password. I also have it to where it creates a txt file in that persons name when you create the account. Now, they login and it brings them to the journal page. The Journal Page for the most part has a Date for your journal Entry, the title of the journal and the journal entry text itself.
The problem that I am having is that when you click the button to create/edit a journal entry, it goes through a sub routine that checks if that journal exists (Meaning that there is already one for that date) or not. If it doesn't exist, then it should create a new one at the bottom of the text file. If it does exist then it should edit the lines in which that journal are stationed in the text file.
Code:
Private Sub CreateBtn_Click(sender As System.Object, e As System.EventArgs) Handles CreateBtn.Click
Errors = ""
Dim TempCounter As Integer = 0
If TitleTxt.Text = "" Then
Errors = "You must enter a title." & vbCrLf
End If
If JournalTextRtxt.Text = "" Then
Errors &= "You must enter an entry for the journal."
End If
If Errors <> "" Then
MessageBox.Show("There's an error in creating/editing your journal." & vbCrLf & "Error(s):" & vbCrLf & Errors, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
JournalDate = DateTimePicker1.Value
JournalTitle = TitleTxt.Text
JournalText = JournalTextRtxt.Text
arrJournalEntries(TempCounter).TheDate = JournalDate
arrJournalEntries(TempCounter).Title = JournalTitle
arrJournalEntries(TempCounter).JournalEntry = JournalText
CheckAndWrite()
End If
End Sub
Private Sub CheckAndWrite()
Dim Reader As New StreamReader(MyName & ".txt", False)
Dim Sline As String = Reader.ReadLine
Counter = 0
Do Until (Sline Is Nothing) 'Perform the code until the line in the text file is blank
If Not Sline Is Nothing Then 'If the line in the text file is NOT blank then
For i As Integer = 1 To 3
Select Case i
Case 1
arrJournalEntries(Counter).TheDate = Sline
Sline = Reader.ReadLine
Case 2
arrJournalEntries(Counter).Title = Sline
Sline = Reader.ReadLine
Case 3
arrJournalEntries(Counter).JournalEntry = Sline
Sline = Reader.ReadLine
End Select
Next
End If
JournalDate = arrJournalEntries(Counter).TheDate
Time = DateTimePicker1.Value
MsgBox("Journal Date = " & JournalDate & vbCrLf & "Today's Date = " & Time)
If Time = JournalDate Then
JournalFound = True
Else
Counter += 1
JournalFound = False
End If
Loop
Reader.Close()
Try
If Sline Is Nothing Or JournalFound = False Then
MsgBox("Your journal is now going to be created.")
JournalDate = DateTimePicker1.Value
JournalTitle = TitleTxt.Text
JournalText = JournalTextRtxt.Text
arrJournalEntries(Counter).TheDate = JournalDate
arrJournalEntries(Counter).Title = JournalTitle
arrJournalEntries(Counter).JournalEntry = JournalText
Dim Writer As New StreamWriter(MyName & ".txt", True)
Do Until (arrJournalEntries(Counter).TheDate = Nothing)
Writer.WriteLine(arrJournalEntries(Counter).TheDate)
Writer.WriteLine(arrJournalEntries(Counter).Title)
Writer.WriteLine(arrJournalEntries(Counter).JournalEntry)
Counter += 1
Loop
Writer.Close()
End If
If JournalFound = True Then
MsgBox("Your journal is now going to be edited.")
JournalDate = DateTimePicker1.Value
JournalTitle = TitleTxt.Text
JournalText = JournalTextRtxt.Text
arrJournalEntries(Counter).TheDate = JournalDate
arrJournalEntries(Counter).Title = JournalTitle
arrJournalEntries(Counter).JournalEntry = JournalText
Dim Writer As New StreamWriter(MyName & ".txt", True)
Do Until (arrJournalEntries(Counter).TheDate = Nothing)
Writer.WriteLine(arrJournalEntries(Counter).TheDate)
Writer.WriteLine(arrJournalEntries(Counter).Title)
Writer.WriteLine(arrJournalEntries(Counter).JournalEntry)
Counter += 1
Loop
Writer.Close()
End If
Catch ex As Exception
MessageBox.Show("An error has occured" & vbCrLf & vbCrLf & "Original Error:" & vbCrLf & ex.ToString)
End Try
End Sub`
The problem that's occuring is that it's not only writing in the first time wrong. When it's supposed to say it's going to edit, it doesn't, it just says creating. But it just adds on to the file. After pressing the button 3 times with the current date. and the Title being "Test title", and the journal entry text being "Test text". This is what occured.
It should just be
7/10/2012 3:52:08 PM
Test title
Test text
7/10/2012 3:52:08 PM
Test title
Test text
the whole way through. but of course if it's the same date then it just overwrites it. So can anybody please help me?
You are only filtering your array by the date, so it looks like you have an object with a date but no title or text:
Do Until (arrJournalEntries(Counter).TheDate = Nothing)
The "quick" fix:
Do Until (arrJournalEntries(Counter).TheDate = Nothing)
If arrJournalEntries(Counter).Title <> String.Empty Then
Writer.WriteLine(arrJournalEntries(Counter).TheDate)
Writer.WriteLine(arrJournalEntries(Counter).Title)
Writer.WriteLine(arrJournalEntries(Counter).JournalEntry)
End If
Counter += 1
Loop
Do consider getting rid of the array and using a List(of JournalEntry) instead. Your code looks difficult to maintain in its current state.