按小时段划分时间跨度/持续时间

时间:2014-01-07 21:16:48

标签: vb.net

我有一张包含3列的Excel工作表

User  order    time

AAA   20      8:00:02

AAA   30      9:00:10

AAA    12     11:20:00

BBB   10      9:30:30

BBB    5        12:30:00

BBB    8        17:00:00

关于如何按小时总结订单的任何想法,例如:从8到10h,用户AAA处理了多少订单。

以下是我的代码的一部分

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim timepick As System.DateTime = System.DateTime.Now.AddDays(-1)
    DateTimePicker1.CustomFormat = "yyyy-MM-dd"
    TextBox1.Text = DateTimePicker1.Text
    TextBox2.Text = timepick.ToShortDateString.ToString()

    Using cn As New OleDbConnection With {.ConnectionString = String.Format(ConnectionNoHeader, FileName)}
        cn.Open()
        Dim cmd As OleDbCommand = New OleDbCommand(
            <Text>
                SELECT 
                 order
                     time,
                          user, 
                                date
                    FROM [<%= SheetName %>$] 
        WHERE date =#<%= TextBox2.Text %>#
            </Text>.Value,
        cn)

        Dim dt As New DataTable
        dt.Load(cmd.ExecuteReader)
        dt.AcceptChanges()

        DataGridView1.DataSource = dt

        Dim dict As Dictionary(Of String, List(Of DataRow)) = dt.AsEnumerable() _
        .GroupBy(Function(x) x.Field(Of String)("USER"), Function(y) y) _
        .ToDictionary(Function(x) x.Key, Function(y) y.ToList())


        datasource.Columns.Add("Date", GetType(String))
        datasource.Columns.Add("USERID", GetType(String))
        datasource.Columns.Add("Number_of_orders", GetType(Integer))
        datasource.Columns.Add("8-10h", GetType(Int32))
        datasource.Columns.Add("10-12h", GetType(Int32))
        datasource.Columns.Add("12-14h", GetType(Int32))
        datasource.Columns.Add("14-16h", GetType(Date))
        datasource.Columns.Add("16-18h", GetType(Date))
        datasource.Columns.Add("18-20h", GetType(Date))
        datasource.Columns.Add("20-22h", GetType(Date))

        For Each id As String In dict.Keys
           Dim rows As List(Of DataRow) = dict(id)

            Dim currenttime = From row In rows
                                 Let timeofday = row.Field(Of Date)("time")
                                   Where timeofday.Hour >= 8 AndAlso timeofday.Hour <= 10
                                   Select timeofday
            Dim orderDates As List(Of Date) = currenttime.ToList()

            Dim currenttime1 = From row In rows
                                 Let Timeofday = row.Field(Of Date)("time")
                                   Where Timeofday.Hour >= 10 AndAlso Timeofday.Hour <= 12
                                   Select Timeofday
            Dim orderDates1 As List(Of Date) = currenttime1.ToList()


            Dim currenttime2 = From row In rows
                                Let timeofday = row.Field(Of Date)("time")
                                  Where timeofday.Hour >= 12 AndAlso timeofday.Hour <= 14
                                  Select timeofday
            Dim orderDates2 As List(Of Date) = currenttime1.ToList()


            Dim newRow As DataRow = datasource.Rows.Add
            newRow.ItemArray = {TextBox2.Text, id, orderDates.Count, orderDates1.Count, orderDates2.Count}
        Next id

        DataGridView2.DataSource = datasource    
    End Using
End Sub

1 个答案:

答案 0 :(得分:3)

您可以使用LINQ:

Dim rowsBetween8and10 = From row In dataTable1
                        Let time = row.Field(of TimeSpan)("TIME")
                        Where time.Hours >= 8 AndAlso time.Hours <= 10

现在,您可以使用For Each枚举行,或使用ToList / ToArray从查询中创建集合。


修改:根据您的评论:

  

我已尝试使用For Each rw In rowsBetween8和10 Dim   orderdate As New List(Of TimeSpan)orderdate.Add(rw)Next。我正在考虑   add(rw)下的错误,你不能将匿名类型anonyme转换为timepan?

您可以选择TimeSpan,然后使用ToList

Dim ordersBetween8and10 =
    From row In dataTable1
    Let time = row.Field(Of TimeSpan)("TIME")
    Where time.Hours >= 8 AndAlso time.Hours <= 10
    Select time
Dim orderDates As List(Of TimeSpan) = ordersBetween8and10.ToList()

或者,要直接回答您的问题,您必须先从匿名类型中选择TimeSpan(在顶部的原始查询中,使用LINQ的方法语法):

Dim orderDates As List(Of TimeSpan) = rowsBetween8and10.
    Select(Function(x) x.time).
    Tolist()
根据您的评论

修改,您可以使用TimeOfDay属性和TimeSpan.FromHours代替Hours

Dim rowsBetween8and10 =
    From row In dataTable1
    Let time = row.Field(Of Date)("time").TimeOfDay
    Where time >= TimeSpan.FromHours(8) AndAlso time < TimeSpan.FromHours(10)

Dim rowsBetween10and12 =
    From row In dataTable1
    Let time = row.Field(Of Date)("time").TimeOfDay
    Where time >= TimeSpan.FromHours(10) AndAlso time < TimeSpan.FromHours(12)