2016-10-28 2 views
1

Ich habe eine Anwendung erstellt, die ein paar Excel-Tabellen in VB.NET erstelltExcel im Task-Manager geöffnet bleibt, nachdem in VB.NET Schließen

Ausgabe I in renne ist, dass ich nicht Excel vollständig bekommen Verlassen.

ich erstellen und die Arbeitsmappe in VB.NET mit Excel versteckt bevölkern, wird der Prozess (Microsoft Excel) zeigt im Hintergrund Prozesse im Task-Manager

nach Beendigung des Vorgangs ich Excel sichtbar zu machen und der Prozess geht zu Apps.

Wenn ich dann Excel schließe, wird der Prozess wieder zu einem Hintergrundprozess.

Irgendeine Idee, was ich falsch mache?

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 2016.10.31:

Ok, jetzt bin ich wirklich verwirrt.

Nimmt man die Vorschläge unter diesem Code kann ich Excel vollständig mit einer Einschränkung zu beenden:

 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 

aber mein Code ist die Schaffung von zwei Arbeitsmappen. Der Code zum Erstellen jeder Arbeitsmappe ist bis auf SQL identisch. Wenn ein Benutzer chkA ankreuzt, funktioniert der Bereinigungscode NICHT. Wenn sie ChkB überprüfen, funktioniert es. Und wenn sie beide überprüfen, funktioniert es nicht. Ich habe den vollständigen Code für die unten enthalten:

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 
+0

Was so etwas wie 'oExcel.Quit über Aufruf()' –

+1

und Außerdem ist dies ein Duplikat von [Wie säubere ich Excel-Interop-Objekte richtig?] (http://stackoverflow.com/questions/158706/how-to-properly-clean-up-excel-interop-objects) –

Antwort

1

Leider hat die Variablen nichts Einstellung nicht den Prozess Griff im Fall von Interop Excel lösen ... Aber wenn Sie explizit freigeben jeder COM-Objekt Referenz zeichnen Sie instanziiert haben, sollte der Prozess nicht hängen bleiben, sobald Excel vom Benutzer geschlossen wurde. Wenn ich den folgenden Code lief und Excel geschlossen, wurde der Prozess nicht mehr hängen (links ich oRange aus, da es noch nichts festgelegt wurde, und ein Objekt freisetzt, die nichts ist eine Ausnahme auslöst):

Public Class Form1 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     Dim oExcel As Excel.Application = Nothing 
     Dim oWorkbook As Excel.Workbook = Nothing 
     Dim oWorksheet As Excel.Worksheet = 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 

     System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorksheet) 
     System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorkbook) 
     System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel) 
     Me.Close() 
    End Sub 
End Class 
+0

Aktualisiert mein OP mit ein paar neuen Informationen – Tom

+1

Ich warf Ihren bearbeiteten Code in ein Programm und lief es (ohne die SQL von co Urse) und ich war nicht in der Lage, das Problem zu reproduzieren, die Excel-Prozesse würden schließen, sobald ich Excel geschlossen habe. Ich bin nicht sicher, warum sie an Ihrem PC hängen ... – soohoonigan

+0

Danke für den Versuch, ich habe keine Ahnung, warum ich dieses Verhalten erlebe. Hoffe, jemand anderes kann hereinspielen. – Tom

2

Sie benötigen das Excel-Objekt nach der Verwendung entsorgen und freigeben.

Ein einfacher Code, den ich verwende, um Excel auch im Task-Manager zu schließen:

Private Sub releaseObject(ByVal obj As Object) Try System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) obj = Nothing Catch ex As Exception obj = Nothing Finally GC.Collect() End Try End Sub

Es funktioniert auf meiner Bewerbung

+0

Mein OP mit einigen neuen Informationen aktualisiert – Tom

Verwandte Themen