0

我正在创建一个简单的程序,可用于保存联系人及其联系人的信息。我在保存/加载功能和插入的联系人总数方面遇到问题。大多数代码取自“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

任何帮助/提示表示赞赏,如果您发布更正的代码块,请解释它是如何工作的/出了什么问题,谢谢。

4

1 回答 1

2

您正在尝试使用流阅读器作为函数的参数AddCustomer- 这不起作用。事实上,你不能StreamReader以你声明它的方式使用 a - 你必须像这样实例化一个:

 Dim sr as New StreamReader
 Dim line as String
 line = sr.ReadLine()

等等。有关更多详细信息,请参阅文档

在任何情况下,如果您尝试从逗号分隔的文件中读取客户数据,例如这样:

C:\test.text --- 包含:

Sam, Bond, sambond@msn.com, 9541032163
Merry, Jackson, merryjackson@msn.com, 8872101103
Rachel, Smith, rachelsmith@msn.com, 4839078565

然后你必须做这样的事情来读取值 - 注意我们必须以AddCustomer声明函数的方式传递参数(即:四个字符串!):

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

在你的情况下,它永远不会结束。调用 toSleep也是完全没有必要的。你永远不应该让 UI 线程休眠!您需要在这里做的就是:

txtTotal.Text = myCustomers.Count.ToString()

就是这样 - 没有 Do/Loop,没有睡眠。任务完成。

另请参阅:Do..Loop (MSDN)

于 2013-06-05T16:05:19.823 回答