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