2013-06-05 2 views
0

연락처 및 연락처 정보를 저장하는 데 사용할 수있는 간단한 프로그램을 만들고 있습니다. 기능을 저장 /로드하고 총계가 개의 연락처가 삽입 된 문제가 있습니다. 대부분의 코드는 "TheNewBoston"자습서에서 가져온 것입니다. 이후에 더 많은 기능을 추가하려고합니다. 여기에 소스 코드 :vb.net 파일 및 기타 문제 저장 /로드

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 

어떤 도움/힌트가 감사하고 코드 블록을 수정 게시 할 경우에도 그것이 어떻게 작동하는지 설명해주십시오 /도 무엇이 잘못된 것인지, 감사합니다.

+0

exectly does not work? 메시지 상자에 어떤 오류가 표시됩니까? 스트림 작성기를 사용하는 대신 [텍스트 작성자] (http://msdn.microsoft.com/en-us/library/system.io.textwriter.aspx)를 확인해보십시오. . –

+0

먼저 '고객'을 하드 코딩하지 않아야합니다. 그래서 .txt로 저장하고 앱 시작시로드하려고합니다. 둘째, 버튼을 클릭하여 삽입 한 총 '고객'을 표시 할 수 있었지만 앱 시작시 버튼없이 표시하려고했습니다. 오류가 표시되지 않습니다. – Jim

답변

2

AddCustomer 함수의 인수로 스트림 판독기를 사용하려고합니다. 작동하지 않습니다. 사실, 당신은 당신이 전혀를 선언하는 방식으로 StreamReader을 사용할 수 없습니다 - 당신은이 같은 하나의 인스턴스를 가지고 등등

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

하고 있습니다. 자세한 내용은 documentation을 참조하십시오. 어떤 경우

,이 같은 예를 들어, 쉼표로 구분 된 파일에서 고객 데이터를 읽으려고하는 경우 :

C : \ test.text --- 포함

Sam, Bond, [email protected], 9541032163 
Merry, Jackson, [email protected], 8872101103 
Rachel, Smith, [email protected], 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과 같은 것으로 생성 된 것으로 읽을 수 있기 때문에 유용합니다. 위의 코드에서 예외 처리를 보여주지 않았 음을 유의하십시오. 그것은 파일이 올바르게 포맷되지 않은 경우 블록을 제외/시도에 그 부분의 몇 가지를 포장하는 아마 신중, 읽을 수없는 등

참조 : 자세한 내용은 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() 

아니요, 아니요/반복, 잠이 없습니다. 작업 완료.

다음을 참조하십시오.

+0

흠, 고마워요. 고마워요. 내 질문은 : "While (Not Rdr.EndOfData)"의 목적은 무엇입니까? - 대답했습니다. – Jim

+0

@Jim - Rdr은 파일을 읽는 객체입니다. 파일을 만들면 파일의 시작 부분에 파일 포인터가 있습니다 (파일의 현재 위치). 'Rdr.ReadFields()'를 호출하면 파일의 한 줄을 읽고 그 위치로 파일 포인터를 전진시킵니다. 해당 라인의 데이터를 파싱 한 후에는 'While' 루프의 맨 위로 되돌아와 파일 포인터가 파일의 끝에 도달했는지 확인합니다. 그렇지 않다면 파일의 끝 부분 ('EndOfData')에 도달 할 때까지 작업을 반복하고 계속해서 다음 줄을 읽습니다. –

+0

아하, 알 겠어. 정보 가 왜 작동하지 않는 당신이 어떤 생각을 가지고 있습니까 " txtTotal.Text = myCustomers.Count.ToString() System.Threading.Thread.Sleep (5000) 루프를 수행합니다"? 또한 링크에 대한 감사. – Jim