如何在不使用循环的情况下将所有Excel项目读取到Listview?

问题描述 投票:0回答:2

是否可以在不使用循环的情况下读取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)
vb.net office-interop
2个回答
1
投票

这里的想法是加快用户界面的更新。

创建ListViewItem的列表,并在循环的每次迭代中添加到其中。在循环外再次解析fromdatetodate。我们希望在每次迭代中都有一个新项目,因此,我在循环内移动了Dimnewitem

我认为最好将此日期数据保留为比较日期。假设这是一个日期值,它将为.ToString保存20,000次转换excelvalue,但我只保留了该代码。如果您的代码仍然太慢,请查看此内容。

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

[通常,我认为使用OleDb提供程序作为Excel并使用DataTable将所有数据拉入ADO.net会更快。然后在数据表的行上循环。同样,如果您的代码仍然很慢,可以考虑一下。

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()

0
投票

您可以使用数组直接从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倍。

© www.soinside.com 2019 - 2024. All rights reserved.