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.
Sorceri found the solution in the comments above: oBooks was declared and set but never released.
Thanks Sorceri!!