如何正确退出Excel

时间:2017-08-26 05:31:40

标签: vb.net

我正在尝试从Excel打印收据,但无法这样做。我试过反向释放,但我似乎无法找到遗漏的东西。请帮忙!谢谢!

这是我到目前为止所做的:

Imports Excel = Microsoft.Office.Interop.Excel

Public Class Form1

#Region "dim"
    Dim exeDir As New IO.FileInfo(Reflection.Assembly.GetExecutingAssembly.FullName)
    Dim xlPath = IO.Path.Combine(exeDir.DirectoryName, "SampleReceipt.xls")
    Dim app As Excel.Application = Nothing
    Dim books As Excel.Workbooks = Nothing
    Dim book As Excel.Workbook = Nothing
    Dim sheets As Excel.Sheets = Nothing
    Dim sheet As Excel.Worksheet = Nothing
    Dim cell As Excel.Range = Nothing
#End Region

    Private Sub NAR(ByVal o As Object)
        Try
            System.Runtime.InteropServices.Marshal.ReleaseComObject(o)
        Catch ex As Exception
            o = Nothing
        Finally

        End Try
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Try
            app = New Excel.Application()
            books = app.Workbooks
            book = books.Open(xlPath)
            sheets = book.Sheets
            sheet = book.Sheets(1)
            cell = sheet.Range("A1")
            cell.Value = "Lorem Ipsum"
            book.SaveAs("C:\Temp\ExcelBook.xls")
            book.Close()
            app.Quit()
        Finally
            NAR(cell)
            NAR(sheet)
            NAR(sheets)
            NAR(book)
            NAR(books)
            NAR(app)
        End Try
    End Sub
End Class

1 个答案:

答案 0 :(得分:0)

这是一个猜测,但我不认为你的NAR方法完美地完成了这项工作。

你有这个:

Private Sub NAR(ByVal o As Object)
    Try
        System.Runtime.InteropServices.Marshal.ReleaseComObject(o)
    Catch ex As Exception
        o = Nothing
    Finally

    End Try
End Sub

现在,如果Exception ReleaseComObjectException提出,那么你只是吞下它 - 我认为你想看看这个例外是什么。你真的应该只处理你可以从中恢复的异常。处理顶级ReleaseComObject确实是一种反模式。因此,如果Nothing提出异常,那么找出它是什么并专门处理它。

接下来,如果您确实有例外,那么您尝试将引用设置为Nothing,但您只是将参考的副本设置为o 。您使用ByVal传递ByRef。原始参考文献未被触及。您想在Nothing中传递它。试试吧。

此外,可能需要在释放组件后将引用设置为Catch - 因此将其移出ReleaseComObject

最后,FinalReleaseComObject上的help docs说明了这一点:

  

如果要调用此方法以确保在确定的时间释放COM组件,请考虑使用FinalReleaseComObject方法。 ReleaseComObject将释放基础COM组件,无论它重新进入CLR的次数如何。每次COM组件重新进入CLR时,RCW的内部引用计数加1。因此,您可以在循环中调用FinalReleaseComObject方法,直到返回的值为零。这实现了与Private Sub NAR(ByRef o As Object) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(o) o = Nothing End Sub 方法相同的结果。

我会尝试这三件事。

试试这段代码:

o = Nothing

并且,如果您要处理特定的异常,则只处理异常处理,但保留def rot13(mess): alphabet = 'abcdefghijklmnopqrstuvwxyz' encrypted = '' for char in mess: if char == ' ': encrypted = encrypted + ' ' else: rotated_index = alphabet.index(char) + 13 if rotated_index < 26: encrypted = encrypted + alphabet[rotated_index] else: encrypted = encrypted + alphabet[rotated_index % 26] return encrypted def main(): print(rot13('abcde')) print(rot13('nopqr')) print(rot13(rot13('since rot thirteen is symmetric you should see this message'))) if __name__ == "__main__": main() 不在处理代码中。