我正在创建一个简单的程序,可用于保存联系人的联系人和信息。我在插入的联系人的保存/加载功能和总计数方面遇到了问题。大多数代码来自“TheNewBoston”的教程,因为我喜欢它,我尝试添加更多功能。这是源代码:
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", "sambond@msn.com", "9541032163")
AddCustomer("Merry", "Jackson", "merryjackson@msn.com", "8872101103")
AddCustomer("Rachel", "Smith", "rachelsmith@msn.com", "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
任何帮助/提示都表示赞赏,如果您发布更正后的代码块,请解释它是如何工作的/哪些是错误的,谢谢。
答案 0 :(得分:2)
您正在尝试使用流阅读器作为AddCustomer
函数的参数 - 这不起作用。实际上,你不能以你声明它的方式使用StreamReader
- 你必须实例化这样的一个:
Dim sr as New StreamReader
Dim line as String
line = sr.ReadLine()
等等。有关详细信息,请参阅documentation。
在任何情况下,如果您尝试从逗号分隔的文件中读取客户数据,例如:
C:\ test.text ---包含:
Sam, Bond, sambond@msn.com, 9541032163 Merry, Jackson, merryjackson@msn.com, 8872101103 Rachel, Smith, rachelsmith@msn.com, 4839078565
然后你必须做这样的事情来读取值 - 注意我们必须以声明函数的方式将参数传递给AddCustomer
(即:四个字符串!):< / p>
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
文本字段解析器读取字符串数组并自动将值分隔为数组列。如果数据 TAB 分开,那么您只需更改分隔符,如
Rdr.Delimiters = New String() {"vbTab"}
这是一个数组参数,因此您甚至可以混合使用空格,制表符,逗号等。只需将它们添加到列表Rdr.Delimiters = New String() {"vbTab", " ", ","}
。
使用文本字段解析器很不错,因为它可以读取制表符或逗号分隔值,这些值由Excel之类的东西生成。请注意我在上面的代码中没有显示任何异常处理。在文件格式不正确,无法读取等情况下,将一些部分包含在try / except块中可能是谨慎的。
请参阅:TextFieldParser (MSDN)了解更多信息
修改强>
我看到我错过了这个问题的第二部分。首先,我建议将泛型用于您的客户列表
Dim myCustomers As New List(Of Customer)
由于很多原因,这样做更好(阅读泛型/集合以获取更多信息)。最重要的是,它们为您提供了类型安全性。此外,您还可以在搜索和排序等方面获得许多其他好处。
关于你的循环:
Do
'total2 = myCustomers.Count.ToString()
'txtTotal.Text = total2
txtTotal.Text = myCustomers.Count.ToString()
System.Threading.Thread.Sleep(5000)
Loop
这将永远不会终止(Do
部分没有任何条件,因此它将永远循环!)。通常Do
循环就像
Do while x < 10
x = x + 1
DoSomething()
Loop
在你的情况下它永远不会结束。拨打Sleep
也是完全没必要的。你永远不应该睡觉UI线程!你需要做的就是:
txtTotal.Text = myCustomers.Count.ToString()
就是这样 - 没有Do / Loop,没有睡眠。完成工作。
另请参阅:Do..Loop (MSDN)