Results 1 to 5 of 5

Thread: Problem with this code, removing a line from an array

  1. #1

    Thread Starter
    New Member
    Join Date
    Mar 2012
    Posts
    4

    Problem with this code, removing a line from an array

    Code:
    Imports System.IO
    Public Class Form6
        Private Sub SearchBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchBtn.Click
    
            Dim alltext() As String = System.IO.File.ReadAllLines("C:\Users\Parent\Documents\Visual Studio 2008\Projects\Members.txt")
            Dim lookfor As String = IDFilter.Text & ","
            For Each line As String In Filter(alltext, lookfor)
                If line.StartsWith(IDFilter.Text) Then
                    MemberDetails.Text = line
                End If
            Next
    
        End Sub
    End Class
    I'm using text files as an array to store and remove information, however I do not know know how to adapt this code so the line I search for is removed.

    My text files are set up as such:
    021,Donovan,56 Eynesford Crescent,Bexleyheath,CT5 1TR,09/08/1967,13 March 2012,Bronze
    062,Fredrikson,6 Freil Road,Gravesend,CT9 1RB,12/06/1995,13 March 2012,Silver

    So I can search and locate the ID, in these cases 021 or 062, but I want to be able to remove the line I want, once it's been found. Can anyone help?

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Problem with this code, removing a line from an array

    Typically, the way you would do this would be to remove the line from the array, then re-write the wholoe text file, as ugly as that likely sounds. Deleting items from an array isn't all that easy, either, but deleting items from a List IS! Therefore, one option would be to move the array into a list:
    Code:
    Dim myList as New List(of String)
    myList.AddRange(alltext)
    Then do your work with the list, which has a Remove and RemoveAt method. You would then write the whole thing back to the file when done.

    That seems kind of painful, frankly, and there may be an easier way while still using a text file. However, your data doesn't really look like it is structured all that well for a text file. You clearly have multiple fields for each line. Therefore, you might consider using a datatable to hold the information. This would be much easier to search, add to, delete from, display (it would bind well to a DataGridView), and so forth. Furthermore, you can then store the data as an XML file (which is text with a bunch of tags larded on) with one simple method .WriteXML. You can also read the file into the datatable with ReadXML.
    My usual boring signature: Nothing

  3. #3
    PowerPoster kaliman79912's Avatar
    Join Date
    Jan 2009
    Location
    Ciudad Juarez, Chihuahua. Mexico
    Posts
    2,593

    Re: Problem with this code, removing a line from an array

    Obvioulsy Shaggy's solution is more complete and professional than what I am proposing here, but this one may be faster to code.

    It is not possible to delete a line from a text file just like that. You, as Shaggy said, need to rewrite the file. So, why not write the new one while searching your array? or reading the original file line by line?

    vb.net Code:
    1. Dim alltext() As String = System.IO.File.ReadAllLines("C:\Users\Parent\Documents\Visual Studio 2008\Projects\Members.txt")
    2. Dim lookfor As String = IDFilter.Text & ","
    3. Dim sw As New streamwriter("C:\MyFile")
    4.  
    5. For Each line As String In Filter(alltext, lookfor)
    6.     If line.StartsWith(IDFilter.Text) Then
    7.         MemberDetails.Text = line
    8.     Else
    9.         sw.WriteLine(line)
    10.     End If
    11. Next
    More important than the will to succeed, is the will to prepare for success.

    Please rate the posts, your comments are the fuel to keep helping people

  4. #4
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: Problem with this code, removing a line from an array

    Quote Originally Posted by Shaggy Hiker View Post
    Code:
    Dim myList as New List(of String)
    myList.AddRange(alltext)
    You could also do it as:-
    vbnet Code:
    1. Dim myList as List(of String) = alltext.ToList
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  5. #5
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,684

    Re: Problem with this code, removing a line from an array

    The following is based off the format of the two lines shown in your initial question so if this is not correct the code below will not work.

    Staying with your current format you could create a class (in this case named Member) that hold each member which is obtained using TextFieldParser into a List(Of Member) which becomes the source of a BindingSource component.

    In the code below place a ComboBox on the form named ComboBox1 (of course later rename it to something like cboMember) and set DropDownStyle to DropDownList.

    Place two buttons on your form, cmdSave and cmdRemoveMember along with a label named Label1.

    Use the code below for the form where you placed the controls above. Note the form name, if your form is another name adjust as needed.
    Code:
    Public Class Form1
        WithEvents bsMembers As New BindingSource
        Private MembersFile As String = IO.Path.Combine(Application.StartupPath, "Members.txt")
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            If IO.File.Exists(MembersFile) Then
                Dim MemberList As New List(Of Member)
                Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(MembersFile)
    
                    MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
                    MyReader.Delimiters = New String() {","}
                    Dim Row As String()
    
                    ' If you are writing the file then all should be good here.
                    ' If you are not writing the file then assertion would be wise.
                    While Not MyReader.EndOfData
    
                        Row = MyReader.ReadFields()
    
                        MemberList.Add( _
                            New Member With _
                            { _
                                .Identifier = Row(0), _
                                .Column2 = Row(1), _
                                .Column3 = Row(2), _
                                .Column4 = Row(3), _
                                .Column5 = Row(4), _
                                .Column6 = Row(5), _
                                .Column7 = Row(6), _
                                .Column8 = Row(7) _
                            } _
                        )
    
                    End While
                End Using
    
                bsMembers.DataSource = (From T In MemberList Select T Order By T.Identifier).ToList
    
                If bsMembers.Count > 0 Then
                    cmdRemoveMember.Enabled = True
                    ComboBox1.DisplayMember = "Identifier"
                    ComboBox1.DataSource = bsMembers
                Else
                    cmdRemoveMember.Enabled = False
                End If
    
                cmdSave.DataBindings.Add("Enabled", cmdRemoveMember, "Enabled")
            Else
                cmdSave.Enabled = False
                cmdRemoveMember.Enabled = False
                My.Dialogs.InformationDialog("Failed to locate '" & MembersFile & "'")
            End If
        End Sub
        Private Sub bsMembers_PositionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles bsMembers.PositionChanged
            If bsMembers.Current IsNot Nothing Then
                Label1.Text = String.Concat("Color: ", CType(bsMembers.Current, Member).Column8)
            End If
        End Sub
        Private Sub cmdRemoveMember_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRemoveMember.Click
            Dim Item = (From T In bsMembers.Cast(Of Member)() Where T.Identifier = ComboBox1.Text).FirstOrDefault
            If Item IsNot Nothing Then
                If My.Dialogs.Question("Remove current member?") Then
                    bsMembers.Remove(Item)
                    cmdRemoveMember.Enabled = bsMembers.Count > 0
                End If
            End If
        End Sub
        Private Sub cmdSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSave.Click
            Dim sb As New System.Text.StringBuilder
    
            For Each Member As Member In CType(bsMembers.DataSource, List(Of Member))
                sb.AppendLine(Member.ToString)
            Next
    
            IO.File.WriteAllText(MembersFile, sb.ToString)
            My.Dialogs.InformationDialog("Members have been saved to disk.")
    
        End Sub
    End Class
    Create a class module and name it member.vb, place the code below in. You will need to tweak the properties as indicated as I did this in VS2010.
    Code:
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks>
    ''' The first property is VS2008 or higher while the remaining properties are
    ''' VS2010 hence you will need to alter Column2 thru Column8 to the same as  Identifier
    ''' column format for a property.
    ''' </remarks>
    Public Class Member
        Private mIdentifier As String
        Public Property Identifier As String
            Set(ByVal value As String)
                mIdentifier = value
            End Set
            Get
                Return mIdentifier
            End Get
        End Property
        Public Property Column2 As String
        Public Property Column3 As String
        Public Property Column4 As String
        Public Property Column5 As String
        Public Property Column6 As String
        Public Property Column7 As String
        Public Property Column8 As String
        Public Sub New()
        End Sub
        Public Overrides Function ToString() As String
            Return _
                Identifier & "," & _
                Column2 & "," & _
                Column3 & "," & _
                Column4 & "," & _
                Column5 & "," & _
                Column6 & "," & _
                Column7 & "," & _
                Column8
        End Function
    End Class
    Create a code module and name it My_Dialogs.vb, place the code below into it.
    Code:
    Namespace My
        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Never)> _
        Partial Friend Class _Dialogs
            ''' <summary>
            ''' Ask question with NO as the default button
            ''' </summary>
            ''' <param name="Text"></param>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Function Question(ByVal Text As String) As Boolean
                Return (MessageBox.Show(Text, My.Application.Info.Title, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) = MsgBoxResult.Yes)
            End Function
            Public Function Question(ByVal Text As String, ByVal Title As String) As Boolean
                Return (MessageBox.Show(Text, Title, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) = MsgBoxResult.Yes)
            End Function
            ''' <summary>
            ''' Shows text in dialog with information icon
            ''' </summary>
            ''' <param name="Text">Message to display</param>
            ''' <remarks></remarks>
            Public Sub InformationDialog(ByVal Text As String)
                MessageBox.Show(Text, My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Information)
            End Sub
        End Class
        <Global.Microsoft.VisualBasic.HideModuleName()> _
        Friend Module KSG_Dialogs
            Private instance As New ThreadSafeObjectProvider(Of _Dialogs)
            ReadOnly Property Dialogs() As _Dialogs
                Get
                    Return instance.GetInstance()
                End Get
            End Property
        End Module
    End Namespace
    Place Members.txt into the same folder as the project executable i.e. Bin\Debug.

    Build/run the project. The remove button when depressed will ask for confirmation to remove the current member. Pressing Yes will remove the member from the list but to ensure it is saved you must press the Save button. If you reply No (the default on the confirmation) nothing changes.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width