如何隔离列表项以执行其他数据操作?

时间:2016-02-23 18:45:44

标签: vb.net

我正在编写一个程序来帮助我们的人力资源部门输入工资单。 SQL查询输出一个包含以下数据的文件:

1,E,REG,40.0000000
10,E,REG,11.5000000
10,E,REG,11.0000000
10,E,REG,5.5000000
10,E,REG,.0000000
10,E,REG,2.5000000
10,E,REG,3.5000000
10,E,REG,6.0000000
10,E,OT,5.5000000
10,E,OT,9.5000000

在VB中,我创建了一个名为Employee

的类
Public Class Employee
     Public Property empNo As Integer
     Public Property eCode As String
     Public Property webCode As String
     Public Property hrsWork As Decimal

End Class

我已经能够从文件中获取信息并将其加载到列表中

Dim allEmployees = From line In System.IO.File.ReadLines("C:\file\testout.txt")
                       Let Columns = line.Split(","c)
                       Where Columns.Length = 4
                       Let empNum = Integer.Parse(Columns(0).Trim())
                       Let eCode = Columns(1)
                       Let webCode = Columns(2)
                       Let hrsWrk = Decimal.Parse(Columns(3))
                       Select New Employee With {.empNo = empNum, .eCode = eCode, .webCode = webCode, .hrsWork = hrsWrk}
Dim EmpList As List(Of Employee) = allEmployees.ToList()

我接下来需要做的是,查看此列表,然后按照编号,然后通过webCode(REG,OT等)获取各个员工,并总结他们的工作时间。完成后,我需要将它们输出回一个HR文件,HR可以导入我们的工资单系统。

输出文件必须如下所示:

1,E,REG,40.0000000
10,E,REG,40.0000000
10,E,OT,15.0000000

等整个文件。

我真的被困在如何隔离每个员工继续。 有什么建议吗?

2 个答案:

答案 0 :(得分:0)

我认为您正在寻找的是FOR EACH循环。

Using myWriter as new system.io.streamwriter("<Path to your output file>")
    For Each tempemployee as Employee in EmpList
         mywriter.writeline(tempemployee.empno, tempemployee.eCode, tempemployee.webCode, tempemployee.hrsWork)   
    Next
End Using

上面的代码将编写一个文本文件,其中包含您要查找的输出格式。为了解释,循环的每次迭代都会使tempmployee成为一个新的价值.....例如,如果你有3名员工,那么循环的第一次通过将有第一个雇员,那么第二次,就业是现在的雇员第二个,然后是第三个。

答案 1 :(得分:0)

您可以在使用循环读取数据时聚合数据。首先,为了使循环更简单并且作为个人偏好,我使Employee类足够聪明以创建自己:

Public Class Employee
    ...properties
    Public Sub New(items As String())
        empNo = Int32.Parse(items(0))
        eCode = items(1)
        webCode = items(2)
        hrsWork = Decimal.Parse(items(3))
    End Sub
End Class

代码将拆分数据传递给它并让它分配值。循环:

Dim eList As New List(Of Employee)
Dim line As String
Dim data() As String
Dim EmpId As Int32

Using sr As New StreamReader("C:\Temp\empsql.csv")
    Do Until sr.EndOfStream
        line = sr.ReadLine
        data = line.Split(","c)

        EmpId = Int32.Parse(data(0))
        ' find an emp with matching number and this "webcode"
        Dim oldemp = eList.
                 Where(Function(w) w.empNo = EmpId AndAlso w.webCode = data(2)).
                 FirstOrDefault()

        ' if emp does not exist, create one
        If oldemp Is Nothing Then
            Dim Emp = New Employee(data)
            eList.Add(Emp)
        Else
            ' add the current hours
            oldemp.hrsWork += Decimal.Parse(data(3))
        End If
    Loop
End Using

或者,您可以处理您创建的原始数据的集合,而不是创建稍后必须删除的项目,一个额外的步骤可以增加已读取的任何记录的小时数。测试结果:

For Each emp In eList
    Console.WriteLine("{0}  {1}   {2}   {3}", emp.empNo, emp.eCode,
                      emp.webCode, emp.hrsWork)
Next

结果:

1  E   REG   40.0000000
10  E   REG   40.0000000
10  E   OT   15.0000000

要将其写回来,你可以做同样的事情,除了在格式字符串中添加逗号并写入文件而不是调试窗口。

请注意,String.Split不适合解析CSV。它可以在几个常见的事情上失败。 TextFieldParser更加健壮,请参阅示例链接。鉴于源和内容你可能是安全的,但值得一提的是其他人。