Экземпляр Excel для сценария SSIS не закрывается - PullRequest
0 голосов
/ 19 декабря 2018

Итак, у меня есть задача «Сценарий» в 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

Может кто-нибудь выяснить, почему это не закроет экземпляр?

Спасибо

1 Ответ

0 голосов
/ 19 декабря 2018

Вы теряете тонну 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)
'...

Для все они .Тогда процесс должен завершиться чисто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...