none
Excel con Interop RRS feed

  • Domanda

  • Ciao,

    per fare una prova, sto aprendo una webform (completamente vuota) il cui codice Vb crea un foglio Excel.

    Va tutto bene, il file viene creato regolarmente, solo che andando in gestione attività Windows rimane sempre attivo EXCEL.EXE-

    Facendo la release dell'applicativo non dovrebbe scomparire? Allego il codice che utilizzo e la finestra delle attività

    Grazie in anticipo

    Bruno

    Imports Excel = Microsoft.Office.Interop.Excel
    
    Public Class Test_Excel
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
            Dim xlApp As Excel.Application
            Dim xlWorkBook As Excel.Workbook
            Dim xlWorkSheet As Excel.Worksheet
    
            xlApp = New Excel.Application
            xlWorkBook = xlApp.Workbooks.Add
            xlWorkSheet = xlWorkBook.Worksheets("Foglio1")
            xlApp.Worksheets(1).Name = "Test_Excel"
            With xlWorkSheet
                .Application.Cells(1, 1).Value = "1A"
                .Application.Cells(1, 2).Value = "1B"
                .Application.Cells(2, 1).Value = "2A"
                .Application.Cells(2, 2).Value = "2B"
                .Application.Columns("A:B").AutoFit
            End With
            xlWorkBook.SaveAs("C:\Users\Desktop\Desktop\Test.xlsx")
            xlWorkBook.Close()                                      '
            xlApp.Quit()                                            '
            releaseObject(xlApp)                                    '
            releaseObject(xlWorkBook)                               '
            releaseObject(xlWorkSheet)
    
        End Sub
    
        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
    
    End Class
    

    martedì 4 aprile 2017 12:55

Risposte

  • Ciao,

    se cerchi in giro, sembra che sia un problema comune. La soluzione migliore è quella di non salvare direttamente il file, ma di aprirlo a video. Così che sia l'utente a chiuderlo.

    Se non puoi, come nel mio caso, puoi rintracciare il processo excel che hai aperto e chiudere solo quello (non è una soluzione elegante però).

    Process[] prs = Process.GetProcesses();
    List<int> excelPID = new List<int>();
    foreach (Process p in prs)
       if (p.ProcessName == "EXCEL")
           excelPID.Add(p.Id);
    
    .... // creazione foglio excel
    
    prs = Process.GetProcesses();
    foreach (Process p in prs)
       if (p.ProcessName == "EXCEL" && !excelPID.Contains(p.Id))
           p.Kill();
    Michele

    • Contrassegnato come risposta Bruno1953 sabato 15 aprile 2017 04:38
    • Contrassegno come risposta annullato Bruno1953 sabato 15 aprile 2017 04:52
    • Proposto come risposta Renato Marzaro []Moderator sabato 15 aprile 2017 18:06
    • Contrassegnato come risposta Bruno1953 giovedì 20 aprile 2017 07:57
    venerdì 14 aprile 2017 20:12

Tutte le risposte

  • Ciao Bruno1953,

    problema annoso di utilizzo InterOp

    il mio consiglio è di evitare

    System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)

    ma di eseguire dopo

         xlWorkBook.SaveAs("C:\Users\Desktop\Desktop\Test.xlsx")
            xlWorkBook.Close()                                      '
            xlApp.Quit() 

    questo codice

        GC.Collect()    
        GC.WaitForPendingFinalizers()
        GC.Collect()    
        GC.WaitForPendingFinalizers()

    o meglio ancora

        Do
            GC.Collect()
            GC.WaitForPendingFinalizers()
        Loop While Marshal.AreComObjectsAvailableForCleanup

    Ciao


    Renato Marzaro

    Microsoft MVP .NET

    http://community.visual-basic.it/renato


    martedì 4 aprile 2017 16:42
    Moderatore
  • Ciao Renato,

    Innanzitutto grazie.

    Ho fatto la modifica ed eseguito più volte il test.

    La prima volta che eseguo il processo rimane sempre nell'elenco, poi ripetendolo subito senza chiudere l'applicazione il nuovo processo viene eliminato quasi sempre, ma qualche volta rimane e quindi vengono elencati 2 processi ecc.

    Grazie ancora e ciao

    Bruno

    Imports System.Runtime.InteropServices
    Imports Excel = Microsoft.Office.Interop.Excel
    
    Public Class Test_Excel
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
            Dim xlApp As Excel.Application
            Dim xlWorkBook As Excel.Workbook
            Dim xlWorkSheet As Excel.Worksheet
    
            xlApp = New Excel.Application
            xlWorkBook = xlApp.Workbooks.Add
            xlWorkSheet = xlWorkBook.Worksheets("Foglio1")
            xlApp.Worksheets(1).Name = "Test_Excel"
            With xlWorkSheet
                .Application.Cells(1, 1).Value = "1A"
                .Application.Cells(1, 2).Value = "1B"
                .Application.Cells(2, 1).Value = "2A"
                .Application.Cells(2, 2).Value = "2B"
                .Application.Columns("A:B").AutoFit
            End With
            xlWorkBook.SaveAs("C:\Users\Desktop\Desktop\Test.xlsx")
            xlWorkBook.Close()
            xlApp.Quit()
            Do
                GC.Collect()
                GC.WaitForPendingFinalizers()
            Loop While Marshal.AreComObjectsAvailableForCleanup
    
        End Sub
    
    End Class
    

    mercoledì 5 aprile 2017 08:19
  • Ciao,

    se cerchi in giro, sembra che sia un problema comune. La soluzione migliore è quella di non salvare direttamente il file, ma di aprirlo a video. Così che sia l'utente a chiuderlo.

    Se non puoi, come nel mio caso, puoi rintracciare il processo excel che hai aperto e chiudere solo quello (non è una soluzione elegante però).

    Process[] prs = Process.GetProcesses();
    List<int> excelPID = new List<int>();
    foreach (Process p in prs)
       if (p.ProcessName == "EXCEL")
           excelPID.Add(p.Id);
    
    .... // creazione foglio excel
    
    prs = Process.GetProcesses();
    foreach (Process p in prs)
       if (p.ProcessName == "EXCEL" && !excelPID.Contains(p.Id))
           p.Kill();
    Michele

    • Contrassegnato come risposta Bruno1953 sabato 15 aprile 2017 04:38
    • Contrassegno come risposta annullato Bruno1953 sabato 15 aprile 2017 04:52
    • Proposto come risposta Renato Marzaro []Moderator sabato 15 aprile 2017 18:06
    • Contrassegnato come risposta Bruno1953 giovedì 20 aprile 2017 07:57
    venerdì 14 aprile 2017 20:12
  • Grazie   
    sabato 15 aprile 2017 04:18
  • Ciao,

    potresti anche utilizzare una delle tante librerie per creare file Excel senza avere bisogno di Excel?

    Io ho spesso usato questa 

    Così non hai la necessità di avere Excel sul server ;)

    sabato 15 aprile 2017 09:34
  • Grazie anche a te.

    Provo una delle due soluzioni. Ci metterò un po' perché mi sto arrangiando da solo, ma per essere onesto ho delle basi poco .... solide.

    Grazie ancora

    sabato 15 aprile 2017 11:59