I've created an application that creates a couple of Excel spreadsheets in VB.NET
Issue I'm running into is that I cannot get Excel to completely quit.
I create and populate the workbooks in VB.NET with Excel hidden, the process (Microsoft Excel) shows in background processes in Task Manager
Once complete I make Excel visible and the process moves to Apps.
Then when I close Excel, the process goes back to being a background process.
Any idea what I am doing wrong?
Code:
Dim oExcel As Excel.Application = Nothing
Dim oWorkbook As Excel.Workbook = Nothing
Dim oWorksheet As Excel.Worksheet = Nothing
Dim oRange As Excel.Range = Nothing
oExcel = CreateObject("Excel.Application")
oExcel.DisplayAlerts = False
oExcel.Visible = False
oWorkbook = oExcel.Workbooks.Add
oWorksheet = oWorkbook.ActiveSheet
'Populate, format, etc.
oWorkbook.SaveAs(Me.txtExportLocation.Text & "\sales.xlsx")
oExcel.Visible = True
oRange = Nothing
oWorksheet = Nothing
oWorkbook = Nothing
ReleaseObject(oExcel)
Public Sub ReleaseObject(ByVal obj As Object)
Dim iValue As Integer = 0
Try
Do
iValue = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Loop While iValue > 0
Catch ex As Exception
RaiseError("", "modGeneral." & "." & System.Reflection.MethodBase.GetCurrentMethod().Name, Err.Number, Err.Description)
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
UPDATE 10/31/2016:
Ok, now I'm really confused.
Taking the suggestions below using this code I can get Excel to completely quit with one caveat:
GC.Collect()
GC.WaitForPendingFinalizers()
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorksheet) : oWorksheet = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorkbook) : oWorkbook = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel) : oExcel = Nothing
However, my code is creating two workbooks. The code to create each workbook is identical except for the SQL. If a user ticks chkA the clean-up code does NOT work. If they check chkB it does work. And if they check both, it doesn't work. I have included the full code for this below:
Private Sub btnExport_Click(sender As Object, e As EventArgs) Handles btnExport.Click
Dim oExcel As Excel.Application = Nothing
Dim oWorkbook As Excel.Workbook = Nothing
Dim oWorksheet As Excel.Worksheet = Nothing
Dim drSystem As SqlClient.SqlDataReader = Nothing
Dim sSQL As String = ""
Dim iRowCount As Integer = 2
Try
If Not Me.chkA.Checked And Not Me.chkB.Checked Then
MsgBox("Select A, B or both before continuing.", vbInformation)
Exit Try
End If
Me.Cursor = Cursors.WaitCursor
Me.lblStatus.Text = "Exporting sales..."
oExcel = CreateObject("Excel.Application")
oExcel.DisplayAlerts = False
oExcel.Visible = False
If Me.chkA.Checked Then
oWorkbook = oExcel.Workbooks.Add
oWorksheet = oWorkbook.ActiveSheet
oWorksheet.Cells(1, 1).Value = "Ship date"
oWorksheet.Cells(1, 2).Value = "Customer"
oWorksheet.Cells(1, 3).Value = "Invoice"
oWorksheet.Cells(1, 4).Value = "Purchase order"
oWorksheet.Cells(1, 5).Value = "Railcar"
oWorksheet.Cells(1, 6).Value = "Weight"
oWorksheet.Cells(1, 7).Value = "Total"
oWorksheet.Cells(1, 8).Value = "Member purchase order"
sSQL = "SELECT FORMAT(i.ship_date, N'MM/dd/yyyy') AS ship_date, "
sSQL += "i.customer_no, "
sSQL += "i.invoice_number, "
sSQL += "i.customer_purchase_order_no, "
sSQL += "r.railcar_number, "
sSQL += "r.weight, "
sSQL += "r.total, "
sSQL += "i.member + N'-' + i.member_purchase_order_no AS member_purchase_order_no "
sSQL += "FROM Invoices i "
sSQL += "JOIN Railcars r "
sSQL += "ON i.invoice_number = r.invoice_number "
sSQL += "WHERE i.ship_date BETWEEN N'" & Format(Me.dtpStartDate.Value, "MM/dd/yyyy") & "' AND N'" & Format(Me.dtpEndDate.Value, "MM/dd/yyyy") & "' AND "
sSQL += "invoice_type = N'A' "
sSQL += "ORDER BY i.customer_no, "
sSQL += "i.ship_date, "
sSQL += "r.railcar_number"
drSystem = modGeneral.drRunSQL(sSQL, CommandType.Text)
Do While drSystem.Read
oWorksheet.Cells(iRowCount, 1).Value = drSystem("ship_date")
oWorksheet.Cells(iRowCount, 2).Value = drSystem("customer_no")
oWorksheet.Cells(iRowCount, 3).Value = drSystem("invoice_number")
oWorksheet.Cells(iRowCount, 4).Value = drSystem("customer_purchase_order_no")
oWorksheet.Cells(iRowCount, 5).Value = drSystem("railcar_number")
oWorksheet.Cells(iRowCount, 6).Value = drSystem("weight")
oWorksheet.Cells(iRowCount, 7).Value = drSystem("total")
oWorksheet.Cells(iRowCount, 8).Value = drSystem("member_purchase_order_no")
iRowCount += 1
Loop
drSystem.Close()
With oWorksheet.Range("A1", "J1")
.Font.Bold = True
.EntireColumn.AutoFit()
End With
oWorksheet.Range("D1").EntireColumn.HorizontalAlignment = Excel.Constants.xlLeft
With oWorksheet.Range("F1")
.EntireColumn.HorizontalAlignment = Excel.Constants.xlRight
.EntireColumn.NumberFormat = "#,##0.00_);(#,##0.00)"
End With
With oWorksheet.Range("G1")
.EntireColumn.HorizontalAlignment = Excel.Constants.xlRight
.EntireColumn.NumberFormat = "#,##0.00_);(#,##0.00)"
End With
oWorkbook.SaveAs(Me.txtExportLocation.Text & "\sales-a.xlsx")
End If
If Me.chkB.Checked Then
iRowCount = 2
oWorkbook = oExcel.Workbooks.Add
oWorksheet = oWorkbook.ActiveSheet
oWorksheet.Cells(1, 1).Value = "Ship date"
oWorksheet.Cells(1, 2).Value = "Customer"
oWorksheet.Cells(1, 3).Value = "Invoice"
oWorksheet.Cells(1, 4).Value = "Purchase order"
oWorksheet.Cells(1, 5).Value = "Railcar"
oWorksheet.Cells(1, 6).Value = "Weight"
oWorksheet.Cells(1, 7).Value = "Total"
oWorksheet.Cells(1, 8).Value = "Member purchase order"
sSQL = "SELECT FORMAT(i.ship_date, N'MM/dd/yyyy') AS ship_date, "
sSQL += "i.customer_no, "
sSQL += "i.invoice_number, "
sSQL += "i.customer_purchase_order_no, "
sSQL += "r.railcar_number, "
sSQL += "r.weight, "
sSQL += "r.total, "
sSQL += "i.member + N'-' + i.member_purchase_order_no AS member_purchase_order_no "
sSQL += "FROM mxInvoices i "
sSQL += "JOIN mxRailcars r "
sSQL += "ON i.invoice_number = r.invoice_number "
sSQL += "WHERE i.ship_date BETWEEN N'" & Format(Me.dtpStartDate.Value, "MM/dd/yyyy") & "' AND N'" & Format(Me.dtpEndDate.Value, "MM/dd/yyyy") & "' AND "
sSQL += "invoice_type = N'B' "
sSQL += "ORDER BY i.customer_no, "
sSQL += "i.ship_date, "
sSQL += "r.railcar_number"
drSystem = modGeneral.drRunSQL(sSQL, CommandType.Text)
Do While drSystem.Read
oWorksheet.Cells(iRowCount, 1).Value = drSystem("ship_date")
oWorksheet.Cells(iRowCount, 2).Value = drSystem("customer_no")
oWorksheet.Cells(iRowCount, 3).Value = drSystem("invoice_number")
oWorksheet.Cells(iRowCount, 4).Value = drSystem("customer_purchase_order_no")
oWorksheet.Cells(iRowCount, 5).Value = drSystem("railcar_number")
oWorksheet.Cells(iRowCount, 6).Value = drSystem("weight")
oWorksheet.Cells(iRowCount, 7).Value = drSystem("total")
oWorksheet.Cells(iRowCount, 8).Value = drSystem("member_purchase_order_no")
iRowCount += 1
Loop
drSystem.Close()
With oWorksheet.Range("A1", "J1")
.Font.Bold = True
.EntireColumn.AutoFit()
End With
oWorksheet.Range("D1").EntireColumn.HorizontalAlignment = Excel.Constants.xlLeft
With oWorksheet.Range("F1")
.EntireColumn.HorizontalAlignment = Excel.Constants.xlRight
.EntireColumn.NumberFormat = "#,##0.00_);(#,##0.00)"
End With
With oWorksheet.Range("G1")
.EntireColumn.HorizontalAlignment = Excel.Constants.xlRight
.EntireColumn.NumberFormat = "#,##0.00_);(#,##0.00)"
End With
oWorkbook.SaveAs(Me.txtExportLocation.Text & "\sales-b.xlsx")
End If
oExcel.Visible = True
GC.Collect()
GC.WaitForPendingFinalizers()
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorksheet) : oWorksheet = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorkbook) : oWorkbook = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel) : oExcel = Nothing
Catch ex As Exception
RaiseError("", Me.Name & "." & System.Reflection.MethodBase.GetCurrentMethod().Name, Err.Number, Err.Description)
Finally
If Not drSystem Is Nothing Then
If Not drSystem.IsClosed Then drSystem.Close()
End If
End Try
Me.lblStatus.Text = ""
Me.Cursor = Cursors.Default