从访问excel缓慢导出
我必须从访问数据库中生成大约800个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
而不是行插入我会尝试CopyFromRecordset做一个完整的logging集。 当然,你必须大幅度修改你的逻辑。
但更重要的是,一旦完成了Excel电子表格对象的closures,你在哪里?
您可以尝试使用Docmd传输电子表格,因为这应该更快
DoCmd.Transferspreadsheet ....
然后,您可以随时使用Excel自动化打开文件
你完成之后(循环内)是否closures工作簿?
xlWBook.Close System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWBook)
看看这个线程,解释了释放所有COM接口的需求。
编辑:我看到您的意见,在@ 1800信息回复。
Dim lista = From ls In Liste _ Where ls!Concatenare = nrliste(i) _ Select ls
这个linq查询是做什么的?
编辑2:尝试在MS-Access内运行SQL,看看它是如何执行的? 此外,我会build议现在放弃LINQ&使用普通的旧ADO.net命令对象与参数化查询。
或者,一个简单而愚蠢的方法是将所有logging(其中最小值和最大值之间的ID)拖到DataTable中,并将其过滤到内存中,并进行某种直接传输(不使用数组并避免逐行写入值,逐个细胞)。
我会试着找出,如果可能的话。 (即使用过滤的数据集,并将其写入Excel文件)。
希望给你一些关于如何进行的提示。
我不知道,但我会看看你有多less文件同时在Excel中打开。 一旦你写完文件,你会closures这些文件吗? 也许是让它们保持开放,所以到第150个工作表打开的时候,它可能会在内存使用上挣扎。 另外,我会说,尝试在debugging器中逐步debugging代码,看看哪个位慢(或者随着时间变慢),这将有助于缩小问题的原因。
快速查看你的代码,让我质疑对每行的调用.Rows(n).Insert(Excel.XlDirection.xlDown,1)。 您应该可以为所有行调用Insert一次。 即使插入1行,在工作表中插入行也很昂贵,特别是插入到大型工作表或许多公式的工作簿时。
SpreadsheetGear for .NET通常可以加快应用程序的运行速度(例如,您可以在页面的右侧看到一些引用来确认这一点 )。 SpreadsheetGear也有一个IRange.CopyFromDataTable方法,因此您不必将数据复制到临时数组。 SpreadsheetGear API类似于Excel的API,因此转换代码非常简单。 如果您想试用,可以在这里下载免费试用版。
免责声明:我自己的SpreadsheetGear LLC