none
Terminar proceso de excel desde vb.net

    Pregunta

  • Hola muchas gracias por su ayuda, tengo un pequeño problema al intentar cerrar por completo un archivo de excel que se crea se modifica, se guarda y se cierra desde vb.net, el procedimiento que uso es el siguiente:

                Dim ApExcel = New Microsoft.Office.Interop.Excel.Application
                Dim Libro = ApExcel.Workbooks.Add
    
    
                With ApExcel
                    .Visible = True
                    
    
                    .ActiveWorkbook.Sheets.Add.Name = "Tabla" 
                    .ActiveWorkbook.Sheets("Tabla").cells(1, 1).value = "NOMBRE DE LA TABLA"
    
                    SaveFileDialog1.DefaultExt = "*.xlsx"
                    SaveFileDialog1.FileName = "Tabla1"
                    SaveFileDialog1.Filter = "Archivos de Excel (*.xlsx)|*.xlsx"
                    SaveFileDialog1.ShowDialog()
    
                    .ActiveWorkbook.SaveAs(SaveFileDialog1.FileName)
    
                End With
    
                Libro = Nothing
                ApExcel.Quit()
                ApExcel = Nothing

    El problema que tengo es que se queda ejecutándo un proceso de excel en el administrador de procesos, alguna recomendación o linea de código que pueda agregar o modificar para poder terminar bien el proceso de este archivo?

    Muchas gracias, saludos.




    • Editado Vilag miércoles, 31 de agosto de 2016 15:38
    miércoles, 31 de agosto de 2016 15:33

Respuestas

  • Para que observes que desaparece el proceso de Excel del Administrador de tareas, aquí tienes adaptado el código fuente que has mostrado en tu mensaje:

    Imports Microsoft.Office.Interop
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Dim fileName As String = String.Empty
    
            ' Configurar el cuadro de diálogo Guardar cómo
            Using sfd As New SaveFileDialog()
                sfd.DefaultExt = "*.xlsx"
                sfd.FileName = "Tabla1"
                sfd.Filter = "Archivos de Excel (*.xlsx)|*.xlsx"
                Dim dr As DialogResult = sfd.ShowDialog()
                If (dr = DialogResult.OK) Then
                    fileName = sfd.FileName
                End If
            End Using
    
            If (fileName.Length = 0) Then
                ' No se ha seleccionado archivo alguno.
                ' Abandonar el procedimiento.
                Return
            End If
    
            ' Declarar explícitamente los objetos de Excel que se van a utilizar.
            '
            Dim apExcel As Excel.Application = Nothing
            Dim libros As Excel.Workbooks = Nothing
            Dim libro As Excel.Workbook = Nothing
            Dim hojas As Excel.Sheets = Nothing
            Dim hoja As Excel.Worksheet = Nothing
            Dim celdas As Excel.Range = Nothing
            Dim celda As Excel.Range = Nothing
    
            Try
                ' Referenciar la aplicación de Excel.
                apExcel = New Excel.Application
    
                ' Hacemos visible la aplicación.
                apExcel.Visible = True
    
                ' Referenciar la colección de libros de trabajo.
                libros = apExcel.Workbooks
    
                ' Creamos un nuevo libro de trabajo de Excel 
                ' añadiéndolo a la colección de libros.
                libro = libros.Add()
    
                ' Referenciamos la colección de hojas de calculo
                ' correspondientes al libro de trabajo actual.
                '
                hojas = libro.Worksheets
    
                ' Añadimos a la colección de hojas una nueva
                ' hoja de cálculo llamada Tabla.
                '
                hoja = DirectCast(hojas.Add(), Excel.Worksheet)
                hoja.Name = "Tabla"
    
                ' Referenciar la colección de celdas de la hoja.
                celdas = DirectCast(hoja.Cells, Excel.Range)
    
                ' Referenciar la celda donde se va a escribir.
                celda = DirectCast(celdas(1, 1), Excel.Range)
                celda.Value = "NOMBRE DE LA TABLA"
    
                ' Guardar el libro de trabajo.
                libro.SaveAs(fileName)
    
            Catch ex As Exception
                ' Se ha producido un error.
                MessageBox.Show(ex.Message)
    
            Finally
                ' Liberar el objeto Excel.Range utilizado
                ReleaseComObject(celda)
    
                ' Liberar la colección de celdas
                ReleaseComObject(celdas)
    
                ' Liberamos la colección de hojas de cálculo.
                ReleaseComObject(hojas)
    
                ' Liberamos la hoja de cálculo añadida.
                ReleaseComObject(hoja)
    
                If (Not libro Is Nothing) Then
                    ' Si procede, indicamos que el libro ya ha sido guardado.
                    '
                    If (Not libro.Saved) Then
                        libro.Saved = True
                    End If
    
                    ' Cerramos el libro de trabajo.
                    '
                    libro.Close()
    
                    ' Liberamos el objeto Workbook
                    '
                    ReleaseComObject(libro)
                End If
    
                ' Liberar la colección de libros de trabajo (Workbooks)
                ReleaseComObject(libros)
    
                If (Not apExcel Is Nothing) Then
                    ' Cerramos Excel.
                    '
                    apExcel.Quit()
    
                    ' Liberamos el objeto Application.
                    '
                    ReleaseComObject(apExcel)
                End If
    
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Disminuye el recuento de referencias del contenedor RCW (Contenedor al que se
        ''' puede llamar en tiempo de ejecución) especificado, asociado al objeto COM
        ''' indicado. 
        ''' </summary>
        ''' <param name="obj">Objeto COM que se va a liberar.</param>
        ''' <remarks></remarks>
        Friend Sub ReleaseComObject(obj As Object)
    
            ' Ver en la ayuda de MSDN: Contenedor al que se puede llamar
            ' en tiempo de ejecución
    
            ' Una aplicación de Office no se cierra después de la automatización desde Visual Studio. NET
            ' Office application does not quit after automation from Visual Studio .NET client
            ' http://support.microsoft.com/kb/317109
    
            If (obj Is Nothing) Then Return
    
            Try
                While (System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) > 0)
                    ' Sin implementación
                End While
    
            Catch
                ' Deshechamos devolver la posible excepción
                ' si no es un objeto COM válido.
    
            Finally
                obj = Nothing
    
            End Try
    
        End Sub
    

    Fíjate que hay que referenciar explícitamente cada objeto de Excel que ha sido utilizado para posteriormente liberar su referencia mediante una llamada al método ReleaseComObject comentado.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta Vilag viernes, 2 de septiembre de 2016 19:03
    miércoles, 31 de agosto de 2016 17:08
    Moderador
  • "Vilag" escribió:

    > modifique mi codigo de la siguiente manera pero aun no consigo
    > terminar todos los procesos, estoy haciendo algo mal?
    >
    > ApExcel.Quit()
    > System.Runtime.InteropServices.Marshal.ReleaseComObject(ApExcel)

    Como te he indicado en mi respuesta anterior, te falta llamar al método ReleaseComObject para pasarle cada uno de los objetos de Excel que has utilizado; no basta con pasarle únicamente el objeto Excel.Application (ApExcel).

    ¿Has probado el ejemplo que te he indicado anteriormente? Lo que tienes que hacer es probarlo, TAL CUAL APARECE, que para eso lo he adaptado a tus necesidades, y observarás que desaparece el proceso de Excel del Administrador de tareas. Comprendo que es un engorro referenciar explícitamente cada objeto de Excel que se utilice para poder liberar su referencia, pero es lo que hay. ;-)


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta Vilag miércoles, 31 de agosto de 2016 18:42
    miércoles, 31 de agosto de 2016 18:11
    Moderador
  • "Vilag" escribió:

    > ya probé el código incluso lo hice en un form nuevo y me sigue
    > apareciendo un proceso en el administrador.

    Siento decirte que yo no puedo reproducir lo que comentas, siempre y cuando te hayas limitado a ejecutar el ejemplo indicado, TAL CUAL APARECE EN EL MENSAJE DE RESPUESTA, sin modificar ni una sola línea del mismo, declarando explícitamente como local TODAS las variables que hacen referencia a los distintos objetos de Excel.

    Ahora bien, si has introducido en el código del ejemplo alguna modificación que hace que se cree un nuevo objeto, ese nuevo objeto también tendrás que liberarlo mediante una llamada al método ReleaseComObject.

    Quiero pensar que ANTES de ejecutar el código del ejemplo, te has asegurado bien que NO EXISTE en el Administrador de tareas ningún proceso de Excel ejecutándose actualmente. Si es así, ciérralo y posteriormente ejecutas el ejemplo.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta Vilag viernes, 2 de septiembre de 2016 19:03
    jueves, 1 de septiembre de 2016 7:15
    Moderador

Todas las respuestas

  • "Vilag" preguntó:

    > El problema que tengo es que se queda ejecutándo un proceso de excel en
    > el administrador de procesos, alguna recomendación o linea de código que
    > pueda agregar o modificar para poder terminar bien el proceso de este archivo?

    Hola:

    Aparte de cerrar el libro de trabajo y llamar al método Quit del objeto Excel.Application, tienes que llamar al método Marshal.ReleaseComObject por cada objeto de Excel que hayas utilizado, para que éste pueda ser liberado y desaparezca el proceso de Excel del Administrador de Tareas.

    Te dejo algunos enlaces donde aparecen ejemplos de llamada al método ReleaseComObject:

    Cómo exportar a Excel el contenido de un objeto DataTable

    Cerrar proceso Excel al finalizar una importacion a aplicacion vb.net

    Exportar a cvs

    Borrar una hoja en Excel

    Y si realizas una búsqueda por tu buscador preferido, seguramente te aparecerán más enlaces. ;-)

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    miércoles, 31 de agosto de 2016 15:52
    Moderador
  • Para que observes que desaparece el proceso de Excel del Administrador de tareas, aquí tienes adaptado el código fuente que has mostrado en tu mensaje:

    Imports Microsoft.Office.Interop
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Dim fileName As String = String.Empty
    
            ' Configurar el cuadro de diálogo Guardar cómo
            Using sfd As New SaveFileDialog()
                sfd.DefaultExt = "*.xlsx"
                sfd.FileName = "Tabla1"
                sfd.Filter = "Archivos de Excel (*.xlsx)|*.xlsx"
                Dim dr As DialogResult = sfd.ShowDialog()
                If (dr = DialogResult.OK) Then
                    fileName = sfd.FileName
                End If
            End Using
    
            If (fileName.Length = 0) Then
                ' No se ha seleccionado archivo alguno.
                ' Abandonar el procedimiento.
                Return
            End If
    
            ' Declarar explícitamente los objetos de Excel que se van a utilizar.
            '
            Dim apExcel As Excel.Application = Nothing
            Dim libros As Excel.Workbooks = Nothing
            Dim libro As Excel.Workbook = Nothing
            Dim hojas As Excel.Sheets = Nothing
            Dim hoja As Excel.Worksheet = Nothing
            Dim celdas As Excel.Range = Nothing
            Dim celda As Excel.Range = Nothing
    
            Try
                ' Referenciar la aplicación de Excel.
                apExcel = New Excel.Application
    
                ' Hacemos visible la aplicación.
                apExcel.Visible = True
    
                ' Referenciar la colección de libros de trabajo.
                libros = apExcel.Workbooks
    
                ' Creamos un nuevo libro de trabajo de Excel 
                ' añadiéndolo a la colección de libros.
                libro = libros.Add()
    
                ' Referenciamos la colección de hojas de calculo
                ' correspondientes al libro de trabajo actual.
                '
                hojas = libro.Worksheets
    
                ' Añadimos a la colección de hojas una nueva
                ' hoja de cálculo llamada Tabla.
                '
                hoja = DirectCast(hojas.Add(), Excel.Worksheet)
                hoja.Name = "Tabla"
    
                ' Referenciar la colección de celdas de la hoja.
                celdas = DirectCast(hoja.Cells, Excel.Range)
    
                ' Referenciar la celda donde se va a escribir.
                celda = DirectCast(celdas(1, 1), Excel.Range)
                celda.Value = "NOMBRE DE LA TABLA"
    
                ' Guardar el libro de trabajo.
                libro.SaveAs(fileName)
    
            Catch ex As Exception
                ' Se ha producido un error.
                MessageBox.Show(ex.Message)
    
            Finally
                ' Liberar el objeto Excel.Range utilizado
                ReleaseComObject(celda)
    
                ' Liberar la colección de celdas
                ReleaseComObject(celdas)
    
                ' Liberamos la colección de hojas de cálculo.
                ReleaseComObject(hojas)
    
                ' Liberamos la hoja de cálculo añadida.
                ReleaseComObject(hoja)
    
                If (Not libro Is Nothing) Then
                    ' Si procede, indicamos que el libro ya ha sido guardado.
                    '
                    If (Not libro.Saved) Then
                        libro.Saved = True
                    End If
    
                    ' Cerramos el libro de trabajo.
                    '
                    libro.Close()
    
                    ' Liberamos el objeto Workbook
                    '
                    ReleaseComObject(libro)
                End If
    
                ' Liberar la colección de libros de trabajo (Workbooks)
                ReleaseComObject(libros)
    
                If (Not apExcel Is Nothing) Then
                    ' Cerramos Excel.
                    '
                    apExcel.Quit()
    
                    ' Liberamos el objeto Application.
                    '
                    ReleaseComObject(apExcel)
                End If
    
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Disminuye el recuento de referencias del contenedor RCW (Contenedor al que se
        ''' puede llamar en tiempo de ejecución) especificado, asociado al objeto COM
        ''' indicado. 
        ''' </summary>
        ''' <param name="obj">Objeto COM que se va a liberar.</param>
        ''' <remarks></remarks>
        Friend Sub ReleaseComObject(obj As Object)
    
            ' Ver en la ayuda de MSDN: Contenedor al que se puede llamar
            ' en tiempo de ejecución
    
            ' Una aplicación de Office no se cierra después de la automatización desde Visual Studio. NET
            ' Office application does not quit after automation from Visual Studio .NET client
            ' http://support.microsoft.com/kb/317109
    
            If (obj Is Nothing) Then Return
    
            Try
                While (System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) > 0)
                    ' Sin implementación
                End While
    
            Catch
                ' Deshechamos devolver la posible excepción
                ' si no es un objeto COM válido.
    
            Finally
                obj = Nothing
    
            End Try
    
        End Sub
    

    Fíjate que hay que referenciar explícitamente cada objeto de Excel que ha sido utilizado para posteriormente liberar su referencia mediante una llamada al método ReleaseComObject comentado.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta Vilag viernes, 2 de septiembre de 2016 19:03
    miércoles, 31 de agosto de 2016 17:08
    Moderador
  • Hola Enrique M. Montejo te agradezco la atencion que me has brindado, modifique mi codigo de la siguiente manera pero aun no consigo terminar todos los procesos, estoy haciendo algo mal?

    Saludos

      Dim ApExcel = New Microsoft.Office.Interop.Excel.Application
                Dim Libro As Microsoft.Office.Interop.Excel.Workbook
                Libro = ApExcel.Workbooks.Add
                Dim XSheet As Microsoft.Office.Interop.Excel.Worksheet
    
                XSheet = Libro.Worksheets(1)
    
                With ApExcel
                    .Visible = True
    
                   XSheet.Cells(2, 1).value = "NOMBRE DE LA TABLA"
    
      
                    SaveFileDialog1.DefaultExt = "*.xlsx"
                    SaveFileDialog1.FileName = "TABLA1"
                    SaveFileDialog1.Filter = "Archivos de Excel (*.xlsx)|*.xlsx"
                    SaveFileDialog1.ShowDialog()
    
                    .ActiveWorkbook.SaveAs(SaveFileDialog1.FileName)
    
    
                End With
    
                ApExcel.DisplayAlerts = False
                ApExcel.Quit()
                System.Runtime.InteropServices.Marshal.ReleaseComObject(ApExcel)
    
                XSheet = Nothing
                Libro = Nothing
                ApExcel = Nothing



    • Editado Vilag miércoles, 31 de agosto de 2016 17:19
    miércoles, 31 de agosto de 2016 17:15
  • "Vilag" escribió:

    > modifique mi codigo de la siguiente manera pero aun no consigo
    > terminar todos los procesos, estoy haciendo algo mal?
    >
    > ApExcel.Quit()
    > System.Runtime.InteropServices.Marshal.ReleaseComObject(ApExcel)

    Como te he indicado en mi respuesta anterior, te falta llamar al método ReleaseComObject para pasarle cada uno de los objetos de Excel que has utilizado; no basta con pasarle únicamente el objeto Excel.Application (ApExcel).

    ¿Has probado el ejemplo que te he indicado anteriormente? Lo que tienes que hacer es probarlo, TAL CUAL APARECE, que para eso lo he adaptado a tus necesidades, y observarás que desaparece el proceso de Excel del Administrador de tareas. Comprendo que es un engorro referenciar explícitamente cada objeto de Excel que se utilice para poder liberar su referencia, pero es lo que hay. ;-)


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta Vilag miércoles, 31 de agosto de 2016 18:42
    miércoles, 31 de agosto de 2016 18:11
    Moderador
  • Una disculpa no me había percatado de la respuesta anterior, probare el código y les comparto mis resultados.

    Muchas gracias

    SAludos

    miércoles, 31 de agosto de 2016 18:43
  • Hola Enrique ya probé el código incluso lo hice en un form nuevo y me sigue apareciendo un proceso en el administrador.

    Saludos

    miércoles, 31 de agosto de 2016 18:59
  • "Vilag" escribió:

    > ya probé el código incluso lo hice en un form nuevo y me sigue
    > apareciendo un proceso en el administrador.

    Siento decirte que yo no puedo reproducir lo que comentas, siempre y cuando te hayas limitado a ejecutar el ejemplo indicado, TAL CUAL APARECE EN EL MENSAJE DE RESPUESTA, sin modificar ni una sola línea del mismo, declarando explícitamente como local TODAS las variables que hacen referencia a los distintos objetos de Excel.

    Ahora bien, si has introducido en el código del ejemplo alguna modificación que hace que se cree un nuevo objeto, ese nuevo objeto también tendrás que liberarlo mediante una llamada al método ReleaseComObject.

    Quiero pensar que ANTES de ejecutar el código del ejemplo, te has asegurado bien que NO EXISTE en el Administrador de tareas ningún proceso de Excel ejecutándose actualmente. Si es así, ciérralo y posteriormente ejecutas el ejemplo.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta Vilag viernes, 2 de septiembre de 2016 19:03
    jueves, 1 de septiembre de 2016 7:15
    Moderador
  • Gracias Enrique, efectivamente he comprobado que no exista ningún procesos en el administrador antes de ejecutar el código, lo utilice tal y como me lo enviaste sin hacer alguna modificación, sigo analizando el código para ver en donde puede estar mi error en cuanto lo encuentre o encuentre alguna solución te la comparto.

    Saludos

    viernes, 2 de septiembre de 2016 18:51
  • Enrique te agradezco el tiempo y atención para mi problema, no se como ni porque en mis pruebas anteriores me seguía apareciendo un proceso pero he intentado nuevamente y ya me funciona a la perfección, no se si era necesario reiniciar el programa o que pasaba pero ya esta funcionando bien, una vez mas muchas gracias.

    Saludos

    viernes, 2 de septiembre de 2016 19:06