2

我在这里查看了一些关于在我的程序运行后摆脱 excel 实例的提示,但这些建议似乎都不起作用。当我最初运行它时,它将创建一个 excel 实例,但是当程序仍在运行时,我通过单击按钮重新运行此代码;它将创建另一个 excel 实例,但这一次它删除了它创建的实例,只留下了最初运行程序时创建的实例。

到目前为止,我所拥有的代码是这样的:(截至 2012 年 9 月 14 日的更新代码)

Private Sub GetBatchFileContents()

    Dim xlApp As Excel.Application
    Dim xlWB As Excel.Workbook
    Dim xlWS As Excel.Worksheet
    Dim xlRan As Excel.Range
    Dim xlVal(,) As Object
    Dim lastRow As Int32

    xlApp = New Excel.Application()
    xlWB = xlApp.Workbooks.Open(TextBox1.Text.ToString(), _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing)
    xlWS = xlWB.Worksheets.Item(1)
    lastRow = xlWS.Cells(xlWS.Rows.Count, 1).End(Excel.XlDirection.xlUp).Row
    xlRan = xlWS.Range(xlWS.Cells(1, 1), xlWS.Cells(lastRow, 130))
    xlVal = xlRan.Value2()
    ReleaseObj(xlRan)
    ReleaseObj(xlWS)
    xlWB.Close(False, Type.Missing, Type.Missing)
    ReleaseObj(xlWB)
    xlApp.Quit()
    ReleaseObj(xlApp)

End Sub

Private Sub ReleaseObj(ByRef obj As Object)

    Try
        Marshal.FinalReleaseComObject(obj)
    Catch ex As Exception
        Stop
    Finally
        obj = Nothing
    End Try

    GC.Collect()
    GC.WaitForPendingFinalizers()
    GC.Collect()

End Sub

提前感谢您的反馈!

4

2 回答 2

1

我遇到了与您描述的非常相似的问题。通过使用此示例代码,它对我有用

' set all Excel related  objects to nothing
columnHeaders = Nothing
range = Nothing
endCell = Nothing
startCell = Nothing
excelSheet = Nothing
excelSheets = Nothing
excelWorkbook.Close()
excelWorkbook = Nothing
excelApp.Quit()
' release com ressources 
 Marshal.FinalReleaseComObject(excelApp)  ' !

excelApp = Nothing
GC.Collect()
GC.WaitForPendingFinalizers()

参见MSDN FinalReleaseComObject _ReleaseComObject

编辑

Private Sub GetBatchFileContents()
    Dim xlApp As Excel.Application
    Dim xlWB As Excel.Workbook
    Dim xlWS As Excel.Worksheet
    Dim xlRan As Excel.Range
    Dim xlVal(,) As Object
    Dim lastRow As Int32

    xlApp = New Excel.Application()
    xlWB = xlApp.Workbooks.Open(TextBox1.Text.ToString(), _
                                Type.Missing, Type.Missing,  Type.Missing,  Type.Missing,  Type.Missing, _
                                Type.Missing,  Type.Missing,  Type.Missing, Type.Missing, Type.Missing, _
                                Type.Missing,  Type.Missing, Type.Missing,  Type.Missing)
    xlWS = xlWB.Worksheets.Item(1)

    ' original
    'lastRow = xlWS.Cells(xlWS.Rows.Count, 1).End(Excel.XlDirection.xlUp).Row

    ' new
    Dim range1 As Excel.Range
    range1 = xlWS.Cells(xlWS.Rows.Count, 1)
    Dim range2 As Excel.Range
    range2 = range1.End(Excel.XlDirection.xlUp)
    lastRow = range2.Row
    ReleaseObj(range1)
    ReleaseObj(range2)

    ' original
    'xlRan = xlWS.Range(xlWS.Cells(1, 1), xlWS.Cells(lastRow, 130))

    ' new
    Dim range1_1 As Excel.Range
    range1_1 = xlWS.Cells(1, 1)
    Dim rangeLastRow_130 As Excel.Range
    rangeLastRow_130 = xlWS.Cells(lastRow, 130)
    xlRan = xlWS.Range(range1_1, rangeLastRow_130)
    ReleaseObj(range1_1)
    ReleaseObj(rangeLastRow_130)

    ' unchanged
    xlVal = xlRan.Value2()
    ReleaseObj(xlRan)
    ReleaseObj(xlWS)
    xlWB.Close(False, Type.Missing, Type.Missing)
    ReleaseObj(xlWB)
    xlApp.Quit()
    ReleaseObj(xlApp)
End Sub

我更改了您的代码以将每个可能的 COM 实例分配给一个变量显式释放它!但由于它在我的计算机上运行良好,我无法对其进行测试。

此外,我发现一篇文章描述了可能导致您所描述行为的原因。

您的 Excel 加载了一个托管的 AddIn(Shared AddIn or VSTO AddIn),这违反了规则。在您的应用程序自动化 Excel 应用程序后,Excel 应用程序无法正确退出,因为加载的 AddIn 有一些未释放的基础 RCW。在这种情况下,即使您的自动化客户端终止,Excel 也不会退出。因此,解决此类问题的一个步骤是禁用所有插件以隔离根本原因。'(有关完整详细信息,请参阅文章)

请让我知道我的建议是否适合您!

于 2012-09-13T19:55:10.553 回答
0

我所做的基本概要。我在 Workbooks 功能的大图中将这个逻辑合并到了 Lock Down 过程中。我必须关闭 Echo,否则最终用户会在两个实例之间获得华丽的交互,因为我激活了一个工作簿/工作表,然后移动到另一个工作簿/工作表。您一定可以在这里使用一些东西;)。

这就是我在项目中使用的所有内容srcwb.Close SaveChanges:=False,它关闭了文件。我过去所做的是获得一个对象引用,Application这样我就可以获得实例的系统 ID 并从应用程序中关闭它。这当然是假设您拥有代码隐藏的 VBA/项目控制权,而不仅仅是平面数据文件。

否则,您将必须在父文件中创建一个集合对象,并在您打开一个新实例时将该应用程序实例存储在集合中,然后定期运行该集合并验证该实例是否处于活动状态。

于 2012-09-20T16:14:45.860 回答