Excel stays in memory after VB.NET mail merge

191 views Asked by At

Trying to do a mail merge using VB.NET and Excel as a datasource and Word document as a main document.

No matter what I've tried, EXCEL.EXE *32 stays running in the Task Manager. I need it to quit so I can re-use the same Excel file as a datasource for subsequent merges in the same program.

Here is how the code is called:

        SourceFile = CreateSourceFile(Queue, F.SelectedPath)

This leads to my function CreateSourceFile:

Public Function CreateSourceFile(ByVal Queue As String, ByVal PathToSave As String)
    'Creates suit data source file and returns the full path to the file location
    Dim fileDest As String
    ProcessDate = Date.Now().ToString("MM.dd.yy")
    fileDest = PathToSave & "\" & ProcessDate & " " & Queue & " Suit Data.xlsx"

    Dim oXL As New Excel.Application
    Dim oBooks As Excel.Workbooks = oXL.Workbooks
    Dim oMyBook As Excel.Workbook = oXL.Workbooks.Add
    Dim oMySheet As Excel.Worksheet

    frmPleaseWait.Label1.Text = "Exporting suit data to Excel. Please wait."
    ShowFormCentered(frmLegal, frmPleaseWait)

    oMySheet = oXL.ActiveSheet
    oMyBook = oXL.ActiveWorkbook

    Try
        'Begin exporting to Excel
        Using CONN As New SqlConnection(ConnStr)
            Dim SuitData As New DataTable
            Dim dt As DataTable = SuitData
            Dim dc As System.Data.DataColumn

            Dim colIndex As Integer = 0
            Dim rowIndex As Integer = 0
            Dim dr As System.Data.DataRow
            Dim Qry As String

            Qry = "EXEC sp_Custom_IA_POWERHOUSE_PullLegalDocData " & Queue

            Dim cmd As New SqlCommand(Qry, CONN)
            Dim adp As New SqlDataAdapter(cmd)
            adp.Fill(SuitData)

            'Set headers from datatable
            For Each dc In dt.Columns
                colIndex += 1
                oMySheet.Cells(1, colIndex) = dc.ColumnName
            Next

            'Get data rows (dr) from datatable
            For Each dr In dt.Rows
                rowIndex += 1
                colIndex = 0
                For Each dc In dt.Columns
                    colIndex += 1
                    oMySheet.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName)
                Next
            Next
        End Using

        'Autofit worksheet cells
        oMySheet.Columns.AutoFit()

        'Append extension to filename if necessary
        If Microsoft.VisualBasic.Right(fileDest, 5) <> ".xlsx" Then
            fileDest = fileDest & ".xlsx"
        End If

        'Remove previously existing file if re-running same file on same day
        If System.IO.File.Exists(fileDest) Then
            System.IO.File.Delete(fileDest)
        End If

        oMyBook.SaveAs(fileDest)

    Catch ex As Exception
        MsgBox(ex.Message)
    Finally
        'Release and close objects
        oMyBook.Close()
        oXL.Workbooks.Close()
        oXL.Quit()

        releaseObject(oMySheet)
        releaseObject(oMyBook)
        releaseObject(oXL)

    End Try

    Return fileDest

End Function

...which then leads into my garbage collection routine:

Public Sub releaseObject(ByVal obj As Object)
    Try
        Dim CheckIt As Integer
        CheckIt = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
        While CheckIt > 0
            CheckIt = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
        End While
        obj = Nothing
    Catch ex As Exception
        MsgBox(ex.Message)
    Finally
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Try
End Sub

What have I missed? Any ideas how to get EXCEL.EXE *32 out of memory? I do NOT want to just kill all Excel processes as has been suggested before. Not only do the answerers indicate that this is not a good solution, but people use Excel all day long at our company, and if we killed all Excel processes, it could interfere with other work the end user is doing.

Am open to suggestions and extend my thanks in advance!

EDIT: I have already found and reviewed Excel application not quitting after calling quit however the final suggestion there was to use GC.Collect(). After adding that to my garbage collection routine, I still have the same issue. Please do not close this question as a duplicate of the link mentioned above. Thank you.

1

There are 1 answers

0
LegalEagle On

Sorceri found the solution in the comments above: oBooks was declared and set but never released.

Thanks Sorceri!!