如何在不使用循环的情况下将所有 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 的列表,并在循环的每次迭代中添加到它。在循环外解析 fromdatetodate。我们希望每次迭代都有一个新项目,所以我将 newitemDim 移到了循环中。

我觉得还是把这个日期数据留作比较日期比较好。假设这是一个日期值,它将为 excelvalue 节省 20,000 次转换 .ToString,但我单独留下了该代码。如果您的代码仍然太慢,请查看此内容。

接下来我们通过一次操作更新用户界面。 BeginUpdate...EndUpdate 防止 UI 在每次添加时重新绘制。 .AddRange 一次添加整个数组。

一般来说,我认为使用 ExcelOleDb 提供程序并使用 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()