如何在不使用循环的情况下将所有 Excel 项读取到 Listview?
How to read all Excel items to Listview without using looping?
是否可以在不使用循环的情况下读取 excel 项中的所有项?我的 excel 中有将近 2 万行,将这些项目放入 Listview 中花费的时间太长。
这是我当前的代码:
xlWorkBook = xlApp.Workbooks.Open(FileName)
xlWorkSheet = xlWorkBook.Worksheets("ExportedFromDatGrid")
xlApp.Sheets("ExportedFromDatGrid").activate()
xlApp.Range("A2").Activate()
Dim cCount As Integer
Dim azr As Microsoft.Office.Interop.Excel.Range
azr = xlWorkSheet.UsedRange
For cCount = 2 To azr.Rows.Count
Dim newitem As New ListViewItem()
Dim excelvalue As String = (Format(azr.Cells(cCount, 2).value, "yyyy-MM-dd"))
Dim fromdate As String
fromdate = dtpFrom.Value.ToString("yyyy-MM-dd")
Dim todate As String
todate = dtpTo.Value.ToString("yyyy-MM-dd")
'MessageBox.Show(fromdate & "FROM - << TO- >>>>" & todate)
If ((excelvalue >= fromdate) And (excelvalue <= todate)) Then
newitem.Text = "CGC-" & azr.Cells(cCount, 1).value.ToString
newitem.SubItems.Add(Format(azr.Cells(cCount, 2).value, "yyyy-MM-dd HH:mm:00"))
newitem.SubItems.Add(azr.Cells(cCount, 3).value.ToString)
newitem.SubItems.Add(azr.Cells(cCount, 4).value.ToString)
newitem.SubItems.Add(azr.Cells(cCount, 5).value.ToString)
lvAll.Items.Add(newitem)
End If
Next
xlWorkBook.Close()
xlApp.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(azr)
您可以使用数组直接从 Excel 读取数据范围,这比循环要快得多。
dim ValArray As Object(,)
ObjRange = xlWorkSheet.UsedRange
ValArray = ObjRange.Value2
然后您将在 VB.NET 数组中获得数据,循环速度要快得多。
然后你可以像这样遍历它
For i = 0 To valArray.GetUpperBound(0)
Debug.print(valArray(i,0))
Debug.print(valArray(i,1))
'etc...
Next
相比之下,这应该是相当快的,可能是 10-20 倍。
这里的想法是加快用户界面的更新。
创建一个 ListViewItem
的列表,并在循环的每次迭代中添加到它。在循环外解析 fromdate
和 todate
。我们希望每次迭代都有一个新项目,所以我将 newitem
的 Dim
移到了循环中。
我觉得还是把这个日期数据留作比较日期比较好。假设这是一个日期值,它将为 excelvalue
节省 20,000 次转换 .ToString
,但我单独留下了该代码。如果您的代码仍然太慢,请查看此内容。
接下来我们通过一次操作更新用户界面。 BeginUpdate...EndUpdate
防止 UI 在每次添加时重新绘制。 .AddRange
一次添加整个数组。
一般来说,我认为使用 Excel
的 OleDb
提供程序并使用 ADO.net
将所有数据拉入 DataTable
会更快。然后在数据行 table 上循环。同样,如果您的代码仍然很慢,则需要考虑这一点。
Dim lst As New List(Of ListViewItem)
Dim fromdate = dtpFrom.Value.ToString("yyyy-MM-dd")
Dim todate = dtpTo.Value.ToString("yyyy-MM-dd")
For cCount = 2 To azr.Rows.Count
Dim excelvalue As String = (Format(azr.Cells(cCount, 2).value, "yyyy-MM-dd"))
If ((excelvalue >= fromdate) And (excelvalue <= todate)) Then
Dim newitem As New ListViewItem()
If ((excelvalue >= fromdate) And (excelvalue <= todate)) Then
newitem.Text = "CGC-" & azr.Cells(cCount, 1).value.ToString
newitem.SubItems.Add(Format(azr.Cells(cCount, 2).value, "yyyy-MM-dd HH:mm:00"))
newitem.SubItems.Add(azr.Cells(cCount, 3).value.ToString)
newitem.SubItems.Add(azr.Cells(cCount, 4).value.ToString)
newitem.SubItems.Add(azr.Cells(cCount, 5).value.ToString)
lst.Add(newitem)
End If
Next
xlWorkBook.Close()
xlApp.Quit()
lvAll.BeginUpdate()
lvAll.Items.AddRange(lst.ToArray)
lvAll.EndUpdate()
在调用它的代码中你需要添加
GC.Collect()
GC.WaitForPendingFinalizers()
是否可以在不使用循环的情况下读取 excel 项中的所有项?我的 excel 中有将近 2 万行,将这些项目放入 Listview 中花费的时间太长。
这是我当前的代码:
xlWorkBook = xlApp.Workbooks.Open(FileName)
xlWorkSheet = xlWorkBook.Worksheets("ExportedFromDatGrid")
xlApp.Sheets("ExportedFromDatGrid").activate()
xlApp.Range("A2").Activate()
Dim cCount As Integer
Dim azr As Microsoft.Office.Interop.Excel.Range
azr = xlWorkSheet.UsedRange
For cCount = 2 To azr.Rows.Count
Dim newitem As New ListViewItem()
Dim excelvalue As String = (Format(azr.Cells(cCount, 2).value, "yyyy-MM-dd"))
Dim fromdate As String
fromdate = dtpFrom.Value.ToString("yyyy-MM-dd")
Dim todate As String
todate = dtpTo.Value.ToString("yyyy-MM-dd")
'MessageBox.Show(fromdate & "FROM - << TO- >>>>" & todate)
If ((excelvalue >= fromdate) And (excelvalue <= todate)) Then
newitem.Text = "CGC-" & azr.Cells(cCount, 1).value.ToString
newitem.SubItems.Add(Format(azr.Cells(cCount, 2).value, "yyyy-MM-dd HH:mm:00"))
newitem.SubItems.Add(azr.Cells(cCount, 3).value.ToString)
newitem.SubItems.Add(azr.Cells(cCount, 4).value.ToString)
newitem.SubItems.Add(azr.Cells(cCount, 5).value.ToString)
lvAll.Items.Add(newitem)
End If
Next
xlWorkBook.Close()
xlApp.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(azr)
您可以使用数组直接从 Excel 读取数据范围,这比循环要快得多。
dim ValArray As Object(,)
ObjRange = xlWorkSheet.UsedRange
ValArray = ObjRange.Value2
然后您将在 VB.NET 数组中获得数据,循环速度要快得多。
然后你可以像这样遍历它
For i = 0 To valArray.GetUpperBound(0)
Debug.print(valArray(i,0))
Debug.print(valArray(i,1))
'etc...
Next
相比之下,这应该是相当快的,可能是 10-20 倍。
这里的想法是加快用户界面的更新。
创建一个 ListViewItem
的列表,并在循环的每次迭代中添加到它。在循环外解析 fromdate
和 todate
。我们希望每次迭代都有一个新项目,所以我将 newitem
的 Dim
移到了循环中。
我觉得还是把这个日期数据留作比较日期比较好。假设这是一个日期值,它将为 excelvalue
节省 20,000 次转换 .ToString
,但我单独留下了该代码。如果您的代码仍然太慢,请查看此内容。
接下来我们通过一次操作更新用户界面。 BeginUpdate...EndUpdate
防止 UI 在每次添加时重新绘制。 .AddRange
一次添加整个数组。
一般来说,我认为使用 Excel
的 OleDb
提供程序并使用 ADO.net
将所有数据拉入 DataTable
会更快。然后在数据行 table 上循环。同样,如果您的代码仍然很慢,则需要考虑这一点。
Dim lst As New List(Of ListViewItem)
Dim fromdate = dtpFrom.Value.ToString("yyyy-MM-dd")
Dim todate = dtpTo.Value.ToString("yyyy-MM-dd")
For cCount = 2 To azr.Rows.Count
Dim excelvalue As String = (Format(azr.Cells(cCount, 2).value, "yyyy-MM-dd"))
If ((excelvalue >= fromdate) And (excelvalue <= todate)) Then
Dim newitem As New ListViewItem()
If ((excelvalue >= fromdate) And (excelvalue <= todate)) Then
newitem.Text = "CGC-" & azr.Cells(cCount, 1).value.ToString
newitem.SubItems.Add(Format(azr.Cells(cCount, 2).value, "yyyy-MM-dd HH:mm:00"))
newitem.SubItems.Add(azr.Cells(cCount, 3).value.ToString)
newitem.SubItems.Add(azr.Cells(cCount, 4).value.ToString)
newitem.SubItems.Add(azr.Cells(cCount, 5).value.ToString)
lst.Add(newitem)
End If
Next
xlWorkBook.Close()
xlApp.Quit()
lvAll.BeginUpdate()
lvAll.Items.AddRange(lst.ToArray)
lvAll.EndUpdate()
在调用它的代码中你需要添加
GC.Collect()
GC.WaitForPendingFinalizers()