Skipping Current Iteration of For Loop if Condition is False - vb.net

I've got a large subroutine (1958 lines) to calculate some prices and figures based on a complex decision tree.
The figures will be in one of multiple tables, so to check if there is an applicable set of data to use, I've got the following If statement
If dDt.Rows.Count = 0 And cDt.Rows.Count = 0 And p1Dt.Rows.Count = 0 And p2Dt.Rows.Count = 0 And p3Dt.Rows.Count = 0 Then
If SysAQ = False Then
Me.Cursor = Cursors.Default
MessageBox.Show("There are no rates in the system for " & cmbSupplier.Text & "/" & ugr.Cells("Product_Code").Value & "/" & cmbCustCode.Text & " for todays " & _
"date. Please add one and try again.", "No Rate Exists", MessageBoxButtons.OK, MessageBoxIcon.Information)
ugr.Cells("DSC_Code").Value = ""
ugr.Cells("DSC_Rate").Value = 0
ugr.Cells("DSC_Value").Value = 0
ugr.Cells("DSC_VAT").Value = 0
Exit Sub
ElseIf suppAQ = False Then
Me.Cursor = Cursors.Default
MessageBox.Show("There are no rates in the system for " & cmbSupplier.Text & "/" & ugr.Cells("Product_Code").Value & "/" & cmbCustCode.Text & " for todays " & _
"date. Please add one and try again.", "No Rate Exists", MessageBoxButtons.OK, MessageBoxIcon.Information)
ugr.Cells("DSC_Code").Value = ""
ugr.Cells("DSC_Rate").Value = 0
ugr.Cells("DSC_Value").Value = 0
ugr.Cells("DSC_VAT").Value = 0
Exit Sub
ElseIf aDt.Rows.Count = 0 Then
Me.Cursor = Cursors.Default
MessageBox.Show("There are no rates in the system for " & cmbSupplier.Text & "/" & ugr.Cells("Product_Code").Value & "/" & cmbCustCode.Text & " for todays " & _
"date. Please add one and try again.", "No Rate Exists", MessageBoxButtons.OK, MessageBoxIcon.Information)
ugr.Cells("DSC_Code").Value = ""
ugr.Cells("DSC_Rate").Value = 0
ugr.Cells("DSC_Value").Value = 0
ugr.Cells("DSC_VAT").Value = 0
Exit Sub
End If
End If
This block of code is within a For Loop, For Each ugr As UltraGridRow in ugLines.Rows
This means it's checking if there is a price for the product on the line, and if not, alerts the user and exits the subroutine.
This subroutine is called on ugLines.AfterRowInsert, (Once a product has been added), as well as before saving the full data.
It works fine for the latter scenario, as whenever it detects a line with no price, it will error and not save. However, if a product has been added with no price, then the user adds another product, it will never add the price in or tell the user the new line is missing a price as the first one always fails.
What I'm wondering, is if there is another way to set this out? Instead of having Exit Sub, can I change it to skip the rest of the code and jump straight to the next iteration? I've looked at using Continue and Continue For, but that seems to be only applicable if checking the opposite, to check where each product does have a price in at least one of the tables, making the If Statement more complex - Is there another way around this?

Essentially, just changing the code in your question to the following:
Dim noRatesInSystem As Boolean = False
If dDt.Rows.Count = 0 And cDt.Rows.Count = 0 And p1Dt.Rows.Count = 0 And p2Dt.Rows.Count = 0 And p3Dt.Rows.Count = 0 Then
If SysAQ = False OrElse suppAQ = False OrElse aDt.Rows.Count = 0 Then
Me.Cursor = Cursors.Default
MessageBox.Show("There are no rates in the system for " & cmbSupplier.Text & "/" & ugr.Cells("Product_Code").Value & "/" & cmbCustCode.Text & " for todays " & _
"date. Please add one and try again.", "No Rate Exists", MessageBoxButtons.OK, MessageBoxIcon.Information)
ugr.Cells("DSC_Code").Value = ""
ugr.Cells("DSC_Rate").Value = 0
ugr.Cells("DSC_Value").Value = 0
ugr.Cells("DSC_VAT").Value = 0
noRatesInSystem = True
End If
End If
If noRatesInSystem = True Then Continue For
This will A) Tidy up the If Statement, B) Continue the loop if a price is found and C) Skip the iteration (Jump to Next) if there are no prices found.

Related

DateTime.TryParseExact Doesn't Work With Single-Digit Day or Month, Regardless of Format String

I'm trying to implement a TextBox validation for user input of dates. Long story short, I'm building a new application and the users are accustomed to entering dates this way, so I want to try and validate the input while not making them "learn" something new. I have the following event handler code I hook up to date fields to test the input:
Dim DateText As String = String.Empty
Dim ValidDates As New List(Of Date)
Dim DateFormats() As String = {"Mdyy", "Mddyy", "MMdyy", "MMddyy", "Mdyyyy", "Mddyyyy", "MMdyyyy", "MMddyyyy"}
If TypeOf sender Is System.Windows.Forms.TextBox Then
Dim CurrentField As System.Windows.Forms.TextBox = CType(sender, System.Windows.Forms.TextBox)
If CurrentField.Text IsNot Nothing AndAlso Not String.IsNullOrEmpty(CurrentField.Text.Trim) Then
DateText = CurrentField.Text.Trim.ReplaceCharacters(CharacterType.Punctuation)
End If
For Each ValidFormat As String In DateFormats
Dim DateBuff As Date
If Date.TryParseExact(DateText, ValidFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, DateBuff) Then
If Not ValidDates.Contains(DateBuff) Then
ValidDates.Add(DateBuff)
End If
End If
Next ValidFormat
If ValidDates.Count > 1 Then
CurrentField.SelectAll()
CurrentField.HideSelection = False
MessageBox.Show("The date you entered is ambiguous." & vbCrLf & vbCrLf &
"Please enter two digits for the month, two digits for the day and" & vbCrLf &
"two digits for the year." & vbCrLf & vbCrLf &
"For example, today's date should be entered as either " & Now.ToString("MMddyy") & vbCrLf &
" or " & Now.ToString("MM/dd/yy") & ".",
"AMBIGUOUS DATE ENTERED", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
CurrentField.HideSelection = True
e.Cancel = True
ElseIf ValidDates.Count < 1 Then
CurrentField.SelectAll()
CurrentField.HideSelection = False
MessageBox.Show("The date you entered was not valid." & vbCrLf & vbCrLf &
"Please enter two digits for the month, two digits for the day and" & vbCrLf &
"two digits for the year." & vbCrLf & vbCrLf &
"For example, today's date should be entered as either " & Now.ToString("MMddyy") & vbCrLf &
" or " & Now.ToString("MM/dd/yy") & ".",
"INVALID INPUT FORMAT", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
CurrentField.HideSelection = True
e.Cancel = True
Else
CurrentField.ForeColor = SystemColors.WindowText
CurrentField.BackColor = SystemColors.Window
End If
End If
This validation method only seems to work correctly if the format includes a two-digit month and two-digit day. If I try to use any of the single-digit formats (e.g., Mddyy, MMdyyyy, etc.), TryParseExact always returns False, and the date is never added to the List(Of Date).
Here are some "hard-coded" tests I went through trying to get to the source of the problem. I've used some intentionally ambiguous dates, as well as some definitively unambiguous ones:
If Date.TryParseExact("1223", "Mdyy", CultureInfo.InvariantCulture, DateTimeStyles.None, TempDate) Then
Console.WriteLine($"success: 1223 -> {TempDate.ToString("M/d/yyyy")}")
Else
Console.WriteLine("failed (1223)")
End If
'failed (1223)
If Date.TryParseExact("12123", "Mddyy", CultureInfo.InvariantCulture, DateTimeStyles.None, TempDate) Then
Console.WriteLine($"success: 12123 -> {TempDate.ToString("M/d/yyyy")}")
Else
Console.WriteLine("failed (12123)")
End If
'failed (12123)
If Date.TryParseExact("012123", "MMddyy", CultureInfo.InvariantCulture, DateTimeStyles.None, TempDate) Then
Console.WriteLine($"success: 012123 -> {TempDate.ToString("M/d/yyyy")}")
Else
Console.WriteLine("failed (012123)")
End If
'success: 012123 -> 1/21/2023
If Date.TryParseExact("1122023", "MMdyyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, TempDate) Then
Console.WriteLine($"success: 1122023 -> {TempDate.ToString("M/d/yyyy")}")
Else
Console.WriteLine("failed (1122023)")
End If
'failed (1122023)
If Date.TryParseExact("72521", "Mddyy", CultureInfo.InvariantCulture, DateTimeStyles.None, TempDate) Then
Console.WriteLine($"success: 72521 -> {TempDate.ToString("M/d/yyyy")}")
Else
Console.WriteLine("failed (72521)")
End If
'failed (72521)
If Date.TryParseExact("072521", "MMddyy", CultureInfo.InvariantCulture, DateTimeStyles.None, TempDate) Then
Console.WriteLine($"success: 072521 -> {TempDate.ToString("M/d/yyyy")}")
Else
Console.WriteLine("failed (072521)")
End If
'success: 072521 -> 7/25/2021
If Date.TryParseExact("3312019", "Mddyyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, TempDate) Then
Console.WriteLine($"success: 3312019 -> {TempDate.ToString("M/d/yyyy")}")
Else
Console.WriteLine("failed (3312019)")
End If
'failed (3312019)
If Date.TryParseExact("05201975", "MMddyyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, TempDate) Then
Console.WriteLine($"success: 05201975 -> {TempDate.ToString("M/d/yyyy")}")
Else
Console.WriteLine("failed (05201975)")
End If
'success: 05201975 -> 5/20/1975
If Date.TryParseExact("432013", "Mdyyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, TempDate) Then
Console.WriteLine($"success: 432013 -> {TempDate.ToString("M/d/yyyy")}")
Else
Console.WriteLine("failed (432013)")
End If
'failed (432013)
I've seen several posts complaining of "unusual behavior" with the TryParseExact() method, but I've not been able to find anything that explains why this is actually happening. I know that I've used some of these parsing methods in the past, but I don't recall ever having this much trouble getting a simple parse to work.
I thought the whole point of using the TryParseExact() method was so that I could tell the parser specifically where the data elements were in the string and get a valid value back. Am I missing or overlooking something here?
MY "SOLUTION":
Based on the explanation from the accepted answer as well as the additional details in the accepted answer from How to convert datetime string in format MMMdyyyyhhmmtt to datetime object?, I believe I've come up with a sort of "work-around" solution that enables me to achieve my goal of allowing my users to continue doing things the way they are used to while still providing the validation I'm looking for.
Added a new List(Of String) variable where I store the possible formats for a given input string (I already limit input to numeric, -, or / only)
Added a Select Case to inject separators (/) into the string at specific positions based on the string's length
Changed the DateFormats() array to use format strings to use in TryParseExact() that include separators (/)
With this, I can test each of those values for valid dates and make my determination from there.
Here's the updated method:
Public Sub ValidateDateField(ByVal sender As Object, ByVal e As CancelEventArgs)
Dim DateText As String = String.Empty
Dim ValidDates As New List(Of Date)
Dim DateFormats() As String = {"M/d/yy", "M/dd/yy", "MM/d/yy", "MM/dd/yy", "M/d/yyyy", "M/dd/yyyy", "MM/d/yyyy", "MM/dd/yyyy"}
Dim FormattedDates As New List(Of String)
If TypeOf sender Is System.Windows.Forms.TextBox Then
Dim CurrentField As System.Windows.Forms.TextBox = CType(sender, System.Windows.Forms.TextBox)
If CurrentField.Text IsNot Nothing AndAlso Not String.IsNullOrEmpty(CurrentField.Text.Trim) Then
'ReplaceCharacters() is a custom extension method
DateText = CurrentField.Text.Trim.ReplaceCharacters(CharacterType.Punctuation)
Select Case DateText.Length
Case < 4
CurrentField.SelectAll()
CurrentField.HideSelection = False
MessageBox.Show("The date you entered was not valid." & vbCrLf & vbCrLf &
"Please enter two digits for the month, two digits for the day and" & vbCrLf &
"two digits for the year." & vbCrLf & vbCrLf &
"For example, today's date should be entered as either " & Now.ToString("MMddyy") & vbCrLf &
" or " & Now.ToString("MM/dd/yy") & ".",
"INVALID INPUT FORMAT", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
CurrentField.HideSelection = True
e.Cancel = True
Exit Sub
Case 4
FormattedDates.Add(DateText.Insert(1, "/"c).Insert(3, "/"c))
Case 5
FormattedDates.Add(DateText.Insert(1, "/"c).Insert(4, "/"c))
FormattedDates.Add(DateText.Insert(2, "/"c).Insert(4, "/"c))
Case 6
FormattedDates.Add(DateText.Insert(1, "/"c).Insert(3, "/"c))
FormattedDates.Add(DateText.Insert(2, "/"c).Insert(5, "/"c))
Case 7
FormattedDates.Add(DateText.Insert(1, "/"c).Insert(4, "/"c))
FormattedDates.Add(DateText.Insert(2, "/"c).Insert(4, "/"c))
Case 8
FormattedDates.Add(DateText.Insert(2, "/"c).Insert(5, "/"c))
Case Else
CurrentField.SelectAll()
CurrentField.HideSelection = False
MessageBox.Show("The date you entered was not valid." & vbCrLf & vbCrLf &
"Please enter two digits for the month, two digits for the day and" & vbCrLf &
"two digits for the year." & vbCrLf & vbCrLf &
"For example, today's date should be entered as either " & Now.ToString("MMddyy") & vbCrLf &
" or " & Now.ToString("MM/dd/yy") & ".",
"INVALID INPUT FORMAT", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
CurrentField.HideSelection = True
e.Cancel = True
Exit Sub
End Select
For Each TempDate As String In FormattedDates
For Each ValidFormat As String In DateFormats
Dim DateBuff As Date
If DateTime.TryParseExact(TempDate, ValidFormat, System.Globalization.CultureInfo.CurrentCulture, DateTimeStyles.None, DateBuff) Then
If Not ValidDates.Contains(DateBuff) Then
ValidDates.Add(DateBuff)
End If
End If
Next ValidFormat
Next TempDate
If DateText.Trim.Length > 0 Then
If ValidDates.Count > 1 Then
CurrentField.SelectAll()
CurrentField.HideSelection = False
MessageBox.Show("The date you entered is ambiguous." & vbCrLf & vbCrLf &
"Please enter two digits for the month, two digits for the day and" & vbCrLf &
"two digits for the year." & vbCrLf & vbCrLf &
"For example, today's date should be entered as either " & Now.ToString("MMddyy") & vbCrLf &
" or " & Now.ToString("MM/dd/yy") & ".",
"AMBIGUOUS DATE ENTERED", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
CurrentField.HideSelection = True
e.Cancel = True
ElseIf ValidDates.Count < 1 Then
CurrentField.SelectAll()
CurrentField.HideSelection = False
MessageBox.Show("The date you entered was not valid." & vbCrLf & vbCrLf &
"Please enter two digits for the month, two digits for the day and" & vbCrLf &
"two digits for the year." & vbCrLf & vbCrLf &
"For example, today's date should be entered as either " & Now.ToString("MMddyy") & vbCrLf &
" or " & Now.ToString("MM/dd/yy") & ".",
"INVALID INPUT FORMAT", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
CurrentField.HideSelection = True
e.Cancel = True
Else
CurrentField.ForeColor = SystemColors.WindowText
CurrentField.BackColor = SystemColors.Window
End If
End If
End If
End If
End Sub
The documentation is clear about this,
If you do not use date or time separators in a custom format pattern,
use the invariant culture for the provider parameter and the widest
form of each custom format specifier. For example, if you want to
specify hours in the pattern, specify the wider form, "HH", instead of
the narrower form, "H".

Access GOTO with other class in vb

How can i access goto with other class. the first code as my first class and the bottom code was my second class. i want to execute that line of class1 using goto by the second class.Heres my code maybe someone will understand what i mean.
Class1
Next4sides: 'My label here
'MsgBox(ObjectFunction.count)
If ObjectFunction.count = 1 Then
Me.Size = New Size(506, 200)
CreateObject.AddTextBox()
CreateObject.AddLabel()
CreateObject.lbl.Text = "Square"
CreateObject.txtbox.Text = "Enter length side"
CreateObject.txtbox.Name = "txtlengthside"
cmbox.Visible = False
ElseIf ObjectFunction.count = 2 Then
CreateObject.AddTextBox()
CreateObject.AddTwoTextBox()
CreateObject.lbl.Text = "Rectangle"
CreateObject.txtbox.Text = "Enter width"
CreateObject.txtbox.Name = "txtrecwidth"
CreateObject.txtbox1.Text = "Enter height"
CreateObject.txtbox1.Name = "txtrecheight"
End If
I want to access the label "Next4sides:" from this class2
If count = 1 Then
If (String.Compare(CType(Form1.Controls("txtlengthside"), TextBox).Text, "return", True) <> 0) Then
If e.KeyChar.Equals(Microsoft.VisualBasic.ChrW(Keys.Return)) Then
Shape.setSquare(CType(Form1.Controls("txtlengthside"), TextBox).Text)
MsgBox("Type Return In The Box to Return to main menu" & vbNewLine & vbNewLine & "Answer" & vbNewLine & "Area: " & Shape.getTriangle() & vbNewLine & vbNewLine & "Next is Rectangle")
count = count + 1
CreateObject.txtbox.Dispose()
'FROM THIS LINE I WANT TO ACCESS THE LABEL USING GoTo
End If
Else
Application.Restart()
End If

Error when I set a radio button to be checked by default

I have a radio button in my VB.NET dll that I wan't to be checked by default. There is a total of 3 radio buttons in this group. Under its properties I set Checked = true. I verified the code was there, this is all the form generated code for the radio button:
Me.rdbProductPC.AutoSize = True
Me.rdbProductPC.Checked = True
Me.rdbProductPC.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.rdbProductPC.Location = New System.Drawing.Point(49, 12)
Me.rdbProductPC.Name = "rdbProductPC"
Me.rdbProductPC.Size = New System.Drawing.Size(45, 17)
Me.rdbProductPC.TabIndex = 1
Me.rdbProductPC.TabStop = True
Me.rdbProductPC.Text = "P&&C"
Me.rdbProductPC.UseVisualStyleBackColor = True
For some reason I get this error when I start the application:
An error occurred creating the form. See Exception.InnerException for details. The error is: ExecuteReader requires an open and available Connection. The connection's current state is closed.
Nothing has changed besides the one line adjusting the checked value. Any idea what could be causing this?
This is the code for my GetProducts() method. The error arises after the call to ExecuteReader() but I cannot see the code for this. If my g_strSQL = pc_mis_busunit_product_relate_summary it executes fine. But when g_strSQL = pc_mis_busunit_product_relate_summary '','','N' it errors out.
That being said, if I leave the radio button unchecked by default and then check it later while the program is running it will go into this same method and g_strSQL will look like pc_mis_busunit_product_relate_summary '','','N' and it will work fine.
Private Sub GetProducts(ByVal ProductList As ListBox)
Dim g_strSQL As String
ProductList.Items.Clear()
lstProductSel.Items.Clear()
lstProduct.Enabled = True
g_strSQL = String.Empty
objcmd.Connection = ControlConnection
'Clear location combo box
Select Case intProduct
Case Product.Summary
g_strSQL = g_strSQL & "pc_mis_busunit_product_relate_summary "
Case Product.Detail
g_strSQL = "SELECT DISTINCT b.dtl_prod_cd, rtrim(ltrim(b.dtl_prod_desc))"
g_strSQL = g_strSQL & " FROM product_detail_ref b "
g_strSQL = g_strSQL & " ORDER BY rtrim(ltrim(b.dtl_prod_desc)) "
Case Else
Exit Sub
End Select
If p_and_C <> String.Empty Then
g_strSQL = g_strSQL & "'" & String.Empty & "','" & String.Empty & "','" & p_and_C & "'"
End If
If g_strSQL <> "" Then
objcmd.CommandText = g_strSQL
rsProducts = objcmd.ExecuteReader()
End If
'Process results from query
If rsProducts.HasRows = False Then
rsProducts.Close()
Exit Sub
Else
' This nested if will check which radio button is selected and add the corresponding
' 'all' entry to the top of the lstProduct box
If rdbProductPC.Checked = True Then
ProductList.Items.Add(PAndCConstants.ALL_P_AND_C)
ElseIf rdbProductNonPC.Checked = True Then
ProductList.Items.Add(PAndCConstants.ALL_NON_P_AND_C)
Else
ProductList.Items.Add(PAndCConstants.ALL)
End If
ProductList.SelectedIndex = 0
While rsProducts.Read()
ProductList.Items.Add(rsProducts(0))
End While
ProductList.SetSelected(0, True)
rsProducts.Close()
End If
rsProducts = Nothing
End Sub

How to use timer in vb.net

I have this code:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim num As String
Dim message As String
Dim name As String
message = txtMessage.Text
Dim count As Integer = Me.TblContactsBindingSource.Count
If i < TblContactsDataGridView.Rows.Count - 1 Then 'stay within bounds
i = i + 1 ' for all rows except Row0
TblContactsDataGridView.Rows(i - 1).DefaultCellStyle.BackColor = Color.White ' restore previous highlight
TblContactsDataGridView.Rows(i).DefaultCellStyle.BackColor = Color.Bisque 'new highlight
num = Me.TblContactsDataGridView.Rows(i).Cells(1).Value.ToString()
name = Me.TblContactsDataGridView.Rows(i).Cells(0).Value.ToString()
If SerialPort1.IsOpen() Then
SerialPort1.Write("AT" & vbCrLf)
SerialPort1.Write("AT+CMGF=1" & vbCrLf)
SerialPort1.Write("AT+CMGS=" & Chr(34) & num & Chr(34) & vbCrLf)
SerialPort1.Write(message & Chr(26))
MessageBox.Show("Message has been successfully sent to " & vbNewLine & name & " (" & num & ") ", "Message Sent", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Else 'next row is off the bottom so
'i = 0 'reset index
'TblSmsDataGridView.Rows(TblSmsDataGridView.Rows.Count - 1).DefaultCellStyle.BackColor = Color.White 'restore bottom row
'TblSmsDataGridView.Rows(i).DefaultCellStyle.BackColor = Color.Bisque 'highlight top row
End If
In a command button I have this:
Timer1.Interval = 2000
Timer1.Enabled = True 'no need to enable it and start it; one or t'other
What happen is, the message box appears over and over. How can i trigger message box to automatically close once it is finished? I commented the code in the "else" because the it repeats over and over.
You have to use a custom message box. Normal message box wont do the thing you wanted. It will pop up every 2 second. best choice is to make a new form and show it as a message box. :)
You need to set timer1.enabled = false in the timer1.tick handler.

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.