首页 > 解决方案 > 从文本文件中选择随机人并更改相应的值

问题描述

我有一个带有按钮和标签的表单。我还有一个包含以下内容的文本文件:

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

文本文件中的值为:

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

我想做的是让用户单击按钮,然后从文本文件中选择一个随机(可用的)人。然后标签的文本会说:

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

然后,我想用该特定人的相应值覆盖文本文件。例如,该人的第二个值现在是"Unavailable",第三个值是"Injured",第四个值是10

我希望这是有道理的。

我没有任何代码,因为我真的不知道该怎么做。任何帮助将非常感激!

标签: vb.nettext-filesfile-manipulation

解决方案


解释和代码一致。

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

推荐阅读