我有一张包含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
答案 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)