Как прочитать все элементы Excel в Listview без использования циклов? - PullRequest
0 голосов
/ 12 марта 2020

Можно ли прочитать все элементы в элементах Excel без использования циклов? У меня почти 20 тысяч строк в моем Excel, это занимает слишком много времени, чтобы поместить элементы в 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)

Ответы [ 2 ]

1 голос
/ 14 марта 2020

Идея в том, чтобы ускорить обновление пользовательского интерфейса.

Создайте список ListViewItem и добавляйте к нему на каждой итерации вашего l oop. Разрешите fromdate и todate один раз за пределами l oop. Мы хотим новый элемент на каждой итерации, поэтому я переместил Dim из newitem в l oop.

. Я думаю, что было бы лучше оставить эти данные в качестве дат для сравнения. Это сэкономит 20 000 конверсий .ToString для excelvalue, если предположить, что это значение даты, но я оставил этот код в покое. Посмотрите на это, если ваш код все еще слишком медленный.

Далее мы обновляем пользовательский интерфейс за одну операцию. BeginUpdate...EndUpdate предотвращает перекрашивание интерфейса при каждом добавлении. .AddRange добавляет весь массив сразу.

В общем, я думаю, что было бы быстрее использовать провайдера OleDb для Excel и перетащить все ваши данные в DataTable, используя ADO.net. Тогда l oop в строках таблицы данных. Опять же, это то, на что нужно обратить внимание, если ваш код все еще работает медленно.

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 голосов
/ 12 марта 2020

Вы можете использовать массивы для чтения диапазонов данных непосредственно из Excel гораздо быстрее, чем зацикливание.

dim ValArray As Object(,)
ObjRange = xlWorkSheet.UsedRange

ValArray = ObjRange.Value2

Тогда у вас будут данные в массиве VB. NET, который намного быстрее l oop через.

Затем вы можете через него пройти l oop следующим образом:

For i = 0 To valArray.GetUpperBound(0)
    Debug.print(valArray(i,0))
    Debug.print(valArray(i,1))
    'etc...
Next

Это должно быть довольно быстро по сравнению, возможно, в 10-20 раз.

...