Reputation: 17
I'm creating a simple program that could be used to save contacts and information on its contact. I have trouble with the save/load functions and the total count of inserted contacts. Most code is taken from a tutorial of "TheNewBoston" and since I liked it I try to add more features. Here is the source code:
Public Class Form1
Dim myCustomers As New ArrayList
Dim FILE_NAME As String = "C:\test.txt"
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
AddCustomer("Sam", "Bond", "[email protected]", "9541032163")
AddCustomer("Merry", "Jackson", "[email protected]", "8872101103")
AddCustomer("Rachel", "Smith", "[email protected]", "4839078565")
'DOESN'T WORK''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If System.IO.File.Exists(FILE_NAME) = True Then
'AddCustomer.System.IO.StreamReader(FILE_NAME)
'or
AddCustomer(System.IO.StreamReader(FILE_NAME))
Else
MessageBox.Show("File does not exist.")
End If
End Sub
'Public variables
Private Structure Customer
Public FirstName As String
Public LastName As String
Public Email As String
Public Phone As Decimal
'Does Name = First&Last Name
Public ReadOnly Property Name() As String
Get
Return FirstName & " " & LastName
End Get
End Property
'Shows the customers in the listbox properly overriding the default ToString function
Public Overrides Function ToString() As String
Return Name
End Function
End Structure
'Declaring and connecting to type Customer
Private objCustomer As Customer
Private objNewCustomer As Customer
'Makes customer format
Private Sub AddCustomer(ByVal firstName As String, ByVal lastName As String, ByVal email As String, ByVal phone As Decimal)
'declares objNewCustomer with the type of customer for use
Dim objNewCustomer As Customer
'Connects the Customer's 4 things to objNewCustomer
objNewCustomer.FirstName = firstName
objNewCustomer.LastName = lastName
objNewCustomer.Email = email
objNewCustomer.Phone = phone
'Adds to myCustomers array list the objNewCustomer
myCustomers.Add(objNewCustomer)
'Adds customer Name to list
listCustomers.Items.Add(objNewCustomer.ToString())
End Sub
'Avoids customer select error
Private ReadOnly Property SelectedCustomer() As Customer
Get
If listCustomers.SelectedIndex <> -1 Then
Return CType(myCustomers(listCustomers.SelectedIndex), Customer)
End If
End Get
End Property
'Enables select customer
Private Sub listCustomers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles listCustomers.SelectedIndexChanged
DisplayCustomer(SelectedCustomer)
End Sub
'Loads the customers' information
Private Sub DisplayCustomer(ByVal cust As Customer)
txtName.Text = cust.Name
txtFirstName.Text = cust.FirstName
txtLastName.Text = cust.LastName
txtEmail.Text = cust.Email
txtPhone.Text = cust.Phone
End Sub
'Add User (pops up new window)
Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
Form2.Show()
'System.IO.File.WriteAllText("C:\test.txt", Textbox1.Text)
End Sub
'WORKS
Private Sub btnTotal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTotal.Click
txtTotal.Text = myCustomers.Count.ToString()
End Sub
'Private Total2 As Integer
'experimenting
'Private Sub DisTotal(ByVal Total As Integer)
' Do
' 'total2 = myCustomers.Count.ToString()
' 'txtTotal.Text = total2
' txtTotal.Text = Total
' System.Threading.Thread.Sleep(5000)
' Loop
'End Sub
Private Sub listTotal_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
Total = myCustomers.Count
'DOESN'T WORK''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Do
'total2 = myCustomers.Count.ToString()
'txtTotal.Text = total2
txtTotal.Text = myCustomers.Count.ToString()
System.Threading.Thread.Sleep(5000)
Loop
End Sub
Private Total As Integer
'DOESN'T WORK''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
Dim writer As New IO.StreamWriter(FILE_NAME)
Try
writer.Write("")
writer.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
writer.Close()
End Try
End Sub End Class
Any help/hint appreciated and also if you post corrected code blocks please explain how it works/what was wrong too, thanks.
Upvotes: 0
Views: 1198
Reputation: 31463
You are trying to use a stream reader as arguments to your AddCustomer
function - this will not work. In fact, you can't use a StreamReader
in the manner you are declaring it at all - you have to instantiate one like this :
Dim sr as New StreamReader
Dim line as String
line = sr.ReadLine()
and so on. See the documentation for more details.
In any case, if you are trying to read customer data from a comma-separated file, for example like this :
C:\test.text --- contains :
Sam, Bond, [email protected], 9541032163 Merry, Jackson, [email protected], 8872101103 Rachel, Smith, [email protected], 4839078565
Then you would have to do something like this to read the values in -- note that we have to pass the arguments to AddCustomer
in the way that the function is declared (ie: four strings!) :
If System.IO.File.Exists(FILE_NAME) Then
'Using creates an instance and disposes it for you when you leave the block
Using Rdr As New Microsoft.VisualBasic.FileIO.TextFieldParser(FILE_NAME)
'Indicates the values are delimited (separated by a special character)
Rdr.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
'Defines the array of special characters that separate fields
Rdr.Delimiters = New String() {","}
'Declare a string array to hold the data from each line
Dim currentRow As String()
'Read lines until you reach the end of the file
While (Not Rdr.EndOfData)
'For each line, read and parse the data
currentRow = Rdr.ReadFields()
'Data are stored with zero-based index
Dim firstName As String = currentRow(0)
Dim lastName As String = currentRow(1)
Dim emailAdd As String = currentRow(2)
Dim phNum As String = currentRow(3)
AddCustomer(firstName, lastName, emailAdd, phNum)
End While
End Using
Else
MessageBox.Show("File does not exist.")
End If
The text field parser reads to a string array and automatically separates the values into array columns for you. If the data is TAB separated then you simply would change the delimiter as in
Rdr.Delimiters = New String() {"vbTab"}
This is an array parameter so you can even do a mix of spaces, tabs, commas, etc. Just add them to the list like Rdr.Delimiters = New String() {"vbTab", " ", ","}
.
Using a text field parser is nice because it can read in tab or comma separated values as generated by something like Excel. Take care that I have not shown any exception handling in the above code. It is probably prudent to wrap a few of those sections in try/except blocks in the case that the file is not correctly formatted, can't be read, etc.
see : TextFieldParser (MSDN) for more information
EDIT
I see I missed the second part of this question. First, I would suggest using generics for your customer list
Dim myCustomers As New List(Of Customer)
This is much nicer for a lot of reasons (read up on generics/collections for more info). Of primary importance, they give you type-safety. Also you get a lot of other goodies in terms of searching and sorting, etc.
As for your loop :
Do
'total2 = myCustomers.Count.ToString()
'txtTotal.Text = total2
txtTotal.Text = myCustomers.Count.ToString()
System.Threading.Thread.Sleep(5000)
Loop
This will never terminate (there are no conditions on the Do
part, so it will just keep looping forever!). Usually Do
loops are done like
Do while x < 10
x = x + 1
DoSomething()
Loop
In your case it will never end. The call to Sleep
is also completely unnecessary. You should never, ever sleep the UI thread! All you need to do here is :
txtTotal.Text = myCustomers.Count.ToString()
That's it - no Do/Loop, no sleep. Job done.
See also : Do..Loop (MSDN)
Upvotes: 2