所以我在SSIS中有一个脚本任务,该脚本任务可以打开,刷新,关闭和保存Excel文件。它使用Visual Basic做到这一点。它可以完美地工作,并且完全可以实现我想要的功能。但是,我无法关闭Excel实例本身,并且我一直在试图找出原因,数小时。这是当前代码:
Public Sub Main()
'On Error GoTo Quit
Dim excel As New Microsoft.Office.Interop.Excel.Application
Dim wb As Microsoft.Office.Interop.Excel.Workbook
excel.DisplayAlerts = False
wb = excel.Workbooks.Open("FilePath")
wb.Sheets("Sheet Name").Cells(2, 18).Value = "thru " & IIf((Month(DateAdd("D", -1, Today)) < 10), "0" & Month(DateAdd("D", -1, Today)), Month(DateAdd("D", -1, Today))) & "/" & Format(Convert.ToDateTime(DateAdd("D", -1, Today)), "dd") & "/" & Format(Convert.ToDateTime(DateAdd("D", -1, Today)), "yyyy")
wb.Sheets("Sheet Name").PivotTables("PivotTable").PivotCache.Refresh()
wb.Sheets("Sheet Name").PivotTables("PivotTable").PivotCache.Refresh()
wb.Sheets("Sheet Name").PivotTables("PivotTable").PivotCache.Refresh()
wb.Sheets("Sheet Name").PivotTables("PivotTable").PivotCache.Refresh()
wb.Sheets("Sheet Name").PivotTables("PivotTable").PivotCache.Refresh()
wb.Sheets("Sheet Name").PivotTables("PivotTable").PivotCache.Refresh()
'Choose arrow based on criteria
If wb.Sheets("Sheet Name").Cells(13, 16).Value > wb.Sheets("Summary").Cells(13, 14).Value Then
wb.Sheets("Sheet Name").Shapes("Shape").Copy()
wb.Sheets("Sheet Name").Cells(12, 13).Select()
wb.Sheets("Sheet Name").Paste()
Else
wb.Sheets("Sheet Name").Shapes("Shape").Copy()
wb.Sheets("Sheet Name").Cells(12, 13).Select()
wb.Sheets("Sheet Name").Paste()
End If
wb.Sheets("Sheet Name").Shapes("Shape").Delete()
wb.Sheets("Sheet Name").Shapes("Shape").Delete()
wb.Sheets("Sheet Name").Cells(2, 2).Select()
wb.SaveAs("FilePath")
wb.Close()
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb)
excel.DisplayAlerts = True
excel.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel)
'wb = Nothing
'excel = Nothing
'GC.Collect()
Dts.TaskResult = ScriptResults.Success
'Quit: excel.Quit()
End Sub
谁能弄清楚为什么它不能关闭实例?
谢谢
答案 0 :(得分:3)
您正在泄漏大量的COM对象,这就是原因。
wb = excel.Workbooks.Open("path")
这会泄漏Workbooks
集合对象。
wb.Sheets("Summary").Cells(2, 18).Value = something
这会泄漏Sheets
集合对象,从其中检索到的Worksheet
对象以及从该Range
调用中获得的Cells
对象。
wb.Sheets("Summary").Shapes("Down Arrow 3").Copy()
同样,泄漏Sheets
集合,检索到的Worksheet
实例,Shapes
集合和检索到的Shape
对象。
这是COM和.NET之间的互操作:您不在这里的VBA领域,也不在进程内。
您不能像这样链接成员电话。您需要保留对您访问的每个COM对象的引用,并正确释放它。
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb)
那是工作簿,...但是现在有运行时可调用包装(RCW)与它们的基础COM对象断开连接,在托管内存中徘徊- 是使EXCEL.EXE进程保持活动的原因:这些COM对象不再可用,也没有释放它们的地方。
拆分链接的成员呼叫。
Dim wbSheets As Microsoft.Office.Interop.Excel.Worksheets = wb.Sheets
Dim summarySheet As Microsoft.Office.Interop.Excel.Worksheet =wbSheets("Summary")
'...
然后也释放它们:
System.Runtime.InteropServices.Marshal.ReleaseComObject(wbSheets)
System.Runtime.InteropServices.Marshal.ReleaseComObject(summarySheet)
'...
对于所有 。然后该过程应该干净退出。