-1

I have a form with a button and a label. I also have a text file with the following contents:

Bob:Available:None:0
Jack:Available:None:0
Harry:Available:None:0
Becky:Unavailable:Injured:8
Michael:Available:None:0
Steve:Available:None:0
Annie:Unavailable:Injured:12
Riley:Available:None:0

The values in the text file are:

person-name:available-or-unavailable:sick-or-injured:months-they-will-be-unavailable

What I would like to do is to have the user click the button and a random (available) person will be selected from the text file. The label's text will then say:

personname & " has gotten injured and will be unavailable for 10 months."

I would then like to overwrite the text file with the corresponding values for that particular person. For example that person's second value will now be "Unavailable", the third value will be "Injured" and the fourth value will be 10.

I hope this makes sense.

I don't have any code, as I literally have no idea how to do this. Any help would be much appreciated!

Word Rearranger
  • 1,306
  • 1
  • 16
  • 25
  • This question is much too broad: the idea is to have a specific problem which needs solving. As a start, I suggest you make a class with meaningful names for the data in a line. Then parse the file into a list of that class. – Andrew Morton Jan 25 '19 at 23:02
  • If you want to do anything random in .NET, it pretty much always means using the `Random` class. You create a single instance and use it to generate a random number as required. You then use that number in whatever way is appropriate for your application. In your case, that would mean creating a list of some sort containing your people and then using the random number as an index into that list. I leave the specifics up to you. – jmcilhinney Jan 25 '19 at 23:56
  • Thanks, apologies for it being too broad. I’m not sure how else to simplify it. Perhaps i should change the question to just reading the random (available) names from the text file, and posting another question re the changing of the values. – Braden Putt Jan 26 '19 at 00:05

1 Answers1

0

Explanations and code in line.

Private r As New Random
Private RandomIndex As Integer
Private dt As New DataTable

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    AddColumnsToDataTable()
    FillDataTable()
End Sub

Private Sub AddColumnsToDataTable()
    'Need to prepare the table to receive the data
    dt.Columns.Add("Name")
    dt.Columns.Add("Available")
    dt.Columns.Add("Injury")
    dt.Columns.Add("Months")
End Sub

Private Sub FillDataTable()
    'ReadAllLines returns an array of lines in the text file
    Dim lines = File.ReadAllLines("workers.txt")
    'Loop through each line in the lines array
    For Each line As String In lines
        '.Split returns an array based on splitting the line
        'by the colon. The c following ":" tells the compiler
        'that this is a Char which the split function requires.
        Dim items = line.Split(":"c)
        'We can add a row to the data table all at once by
        'passing in an array of objects.
        'This consists of the elements of the items array
        dt.Rows.Add(New Object() {items(0), items(1), items(2), items(3)})
    Next
    'Now we have an in memory DataTable that contains all the data from the text file.
End Sub

Private Function GetRandomWorker() As String
    'A list of all the row indexes that are available
    Dim AvailableList As New List(Of Integer)
    For i As Integer = 0 To dt.Rows.Count - 1
        'Loop through all the data in the date table row by row
        If dt.Rows(i)("Available").ToString = "Available" Then
            'Add only the row indexes that are Available
            AvailableList.Add(i)
        End If
    Next
    'Get a random index to use on the list of row indexes in IndexList
    If AvailableList.Count = 0 Then
        'No more workers left that are Available
        Return ""
    End If
    'Get a random number to use as an index for the available list
    Dim IndexForList = r.Next(AvailableList.Count)
    'Selects a row index based on the random index in the list of Available
    RandomIndex = AvailableList(IndexForList)
    'Now use the index to get information from the row in the data table
    Dim strName = dt.Rows(RandomIndex)("Name").ToString
    Return strName
End Function

Private Sub SaveDataTable()
    'Resave the whole file if this was a real app you would use a database
    Dim sb As New StringBuilder
    'A string builder keeps the code from creating lots of new strings
    'Strings are immutable (can't be changed) so every time you think you are
    'changing a string, you are actually creating a new one.
    'The string builder is mutable (changable)
    For Each row As DataRow In dt.Rows
        'The ItemsArray returns an array of objects containing all the 
        'values in each column of the data table.
        Dim rowValues = row.ItemArray
        'This is a bit of Linq magic that turns the values into strings
        Dim strRowValues = From s In rowValues
                           Select DirectCast(s, String)
        'Now that we have strings we can use the String.Join with the colon
        'to get the format of the text file
        sb.AppendLine(String.Join(":", strRowValues))
    Next
    'Finally we change the StringBuilder to a real String
    'The workers.txt is stored in the Bin\Debug directory so it is current directory
    'no additional path required
    File.WriteAllText("workers.txt", sb.ToString)
End Sub

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    SaveDataTable()
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim WorkerName As String = GetRandomWorker()
    If WorkerName = "" Then
        MessageBox.Show("There are no available workers")
        Return
    End If
    Label1.Text = $"{WorkerName} has gotten injured and will be unavailable for 10 months."
    dt.Rows(RandomIndex)("Available") = "Unavailable"
    dt.Rows(RandomIndex)("Injury") = "Injured"
    dt.Rows(RandomIndex)("Months") = "10"
End Sub
Mary
  • 14,926
  • 3
  • 18
  • 27