2009-10-09 5 views
0

Мне нужно создать около 800 файлов excel из базы данных доступа.медленный экспорт из доступа к excel

Для первых 10-15 из них он работает хорошо, несколько секунд/файл excel, но он постоянно занимает больше времени, в 150-м файле excel он занимает 10 минут.

Вот мой код:

Он делает это для каждого nrliste в таблице доступа (около 800 из них)

Dim lista = From ls In Liste _ 
         Where ls!Concatenare = nrliste(i) _ 
        Select ls 
      Dim table = lista.CopyToDataTable 
      Dim DataArr(table.Rows.Count, 30) 

      For x = 0 To table.Rows.Count - 1 
       For y = 0 To 30 
        DataArr(x, y) = table.Rows(x).Item(y) 
       Next 
      Next 


      Dim filetocopy As String 
      Dim newcopy As String 
      Dim tempname As String = nrliste(i).ToString 
      Dim filename As String = "LISTA INV OBI(MF) LA 30.09.2009_" & tempname.Replace("#", "_") 
      filetocopy = Environment.CurrentDirectory & "\MACHETA.xls" 
      newcopy = FolderBD.SelectedPath & "\" & filename & ".xls" 
      If System.IO.File.Exists(newcopy) = True Then 
       System.IO.File.Delete(newcopy) 
       System.IO.File.Copy(filetocopy, newcopy) 
      Else 
       System.IO.File.Copy(filetocopy, newcopy) 
      End If 

      'excel file 
      Dim xlWBook As Excel.Workbook = xlApp.Workbooks.Open(newcopy) 
      Dim xlSheet As Excel.Worksheet = CType(xlWBook.Worksheets("Lista inventar OBI de natura MF"), Excel.Worksheet) 

      'insereaza liniile necesare 
      For n = 11 To ((lista.Count - 1) + 11) 
       With xlSheet 
        .Rows(n).Insert(Excel.XlDirection.xlDown, 1) 
       End With 
      Next 

      'copiaza datele 

      With xlSheet 

       .Range(.Cells(11, 1), .Cells(table.Rows.Count + 11, 31)).Value = DataArr 

      End With 
+0

См. Измененный ответ от меня ниже. Благодаря!! – shahkalpesh

ответ

1

Вместо Ряды Вставьте я хотел бы попробовать CopyFromRecordset сделать весь набор записей. Конечно, вам придется существенно переработать свою логику.

Но что еще более важно, где вы закрываете объект электронной таблицы Excel, как только вы закончите с ним?

+0

ok, с копией из набора записей Я экспортировал около 400 файлов за 4 минуты, это очень быстрый метод, спасибо – Iulian

0

я не знаю, но я хотел бы посмотреть на то, как много файлов в конечном итоге открываются в Excel все одновременно. Вы закрываете файлы после того, как закончите писать им? Возможно, это держит их открытыми, поэтому к тому моменту, когда 150-й рабочий лист открыт, он может изо всех сил пытаться использовать память. Кроме того, я бы сказал, попробуйте выполнить код в отладчике и посмотреть, какой бит медленный (или медленнее с течением времени) - это поможет сузить причину проблемы.

+0

спасибо за предложение, я ступил с отладчиком и это занимает много времени в этом Linq заявление: Dim Lista = От Ls В Liste _ Где Ls Concatenare = nrliste (I) _ Выберите Ls This! где происходит получение строк из таблицы доступа для экспорта. У меня нет идей, как я могу сделать это быстрее. – Iulian

1

Вы закрываете книгу после того, как закончите с ней (внутри цикла)?

xlWBook.Close 
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWBook) 

Посмотрите на this нить, что объясняет необходимость освобождения всех COM-интерфейсов.

EDIT: Я видел ваши комментарии в ответ на информацию @ 1800.

Dim lista = From ls In Liste _ 
         Where ls!Concatenare = nrliste(i) _ 
        Select ls 

Что делает этот запрос linq?

EDIT2: Попробуйте запустить SQL внутри MS-Access, чтобы узнать, как он работает? Кроме того, я предлагаю отказаться от LINQ на данный момент & использовать простой старый объект команды ADO.net с параметризованным запросом.

В качестве альтернативы простой путанице можно было бы вытащить все записи (где ID между минимальным и максимальным значением) в DataTable и отфильтровать их в памяти и сделать какую-то прямую передачу (без использования массива и избежать записи значений строка за строкой, ячейка по ячейке).

Я попробую и выясню, если это возможно. (т. е. использовать отфильтрованный набор данных и записать его в файл excel).

Надеюсь, что дает вам несколько подсказок о том, как действовать.

+0

он выбирает данные из таблицы доступа, где concatenare (столбец в таблице доступа) = liste (i) (критерии выбора - i идет от 0 до 768) – Iulian

+0

спасибо за предложения, я собираюсь попробовать их как можно скорее как я могу – Iulian

1

Вы можете попробовать использовать передаточную DoCmd таблицу, так как это должно быть быстрее

DoCmd.Transferspreadsheet .... 

Тогда вы всегда можете открыть файл с помощью автоматизации Excel после

+0

У меня есть другое приложение, где я использую таблицу переноса документов docmd, но мне кажется медленнее, я собираюсь дать ему попробовать. – Iulian

+0

Он должен быть быстрее, поскольку это не последовательная, а пакетная операция. И у вас нет накладных расходов на автоматизацию второго супертяжелого приложения Office - он записывает файл напрямую с помощью Jet/ACE. –

-1

быстрый взгляд на ваш код делает меня вопрос вызов .Rows (n) .Insert (Excel.XlDirection.xlDown, 1) для каждой строки. Вы должны иметь возможность вызвать Insert once для всех строк. Вставка строк на листе стоит дорого, даже если вы просто вставляете 1 строку - особенно если вы вставляете в большой рабочий лист или в книгу со многими формулами.

обычно ускоряет такие приложения, как ваши (вы можете увидеть некоторые цитаты, подтверждающие это here - в правой части страницы). SpreadsheetGear также имеет метод IRange.CopyFromDataTable, поэтому вам не придется копировать данные во временный массив.API SpreadsheetGear аналогичен API-интерфейсу Excel, поэтому преобразование вашего кода прямолинейно. Вы можете скачать бесплатную пробную версию here, если хотите попробовать.

Отказ от ответственности: У меня есть SpreadsheetGear ООО

+0

В чем преимущество вашей продукции над TransferSpreadsheet для такого случая, когда автоматизация не используется для специального форматирования выходных данных? –

+0

Мне кажется, что каждый набор записей вставляется в верхнюю часть книги (я мог ее неправильно понять) из VB.NET. Мой ответ на этот оригинальный пост. Я не знаком с DoCmd.TransferSpreadsheet, поэтому я не могу комментировать, как SpreadsheetGear сравнивается с ним. –

+0

Я не видел ответа здесь, когда он был изначально опубликован. Я склоняюсь к нулю, потому что это показывает, что исходный ответ был проворным, поскольку плакат исповедует полное незнание альтернативного решения. –

Смежные вопросы