es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Intentando abrir archivos de Excel con win32com.client.dispatch cuando los manipuladores de archivos ya están ocupados.

Actualmente estoy tratando de hacer que algunos de mis scripts de Python que acceden regularmente a archivos de Excel sean un poco más robustos.

Tengo parte de mi código que se ve así:

filename = temp.xlsm
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(filename, ReadOnly=1)
xl.Application.Run(macro1)
xl.Application.Run(macro2)
xl.Workbooks(1).Close(SaveChanges=1)
xl.Application.Quit()
xl=0

La mayoría de las veces, mis macros y la ejecución de este código funcionarían perfectamente bien, sin embargo, como estoy modificando constantemente mi código VBA macro incrustado, habrá momentos en los que mis macros fallarán y, debido a esto, mi archivo está en uso por una tarea en segundo plano de Excel. La única forma de resolver este conflicto es utilizar el Explorador de procesos de Windows para encontrar el proceso que tiene el archivo en uso y luego cerrar el proceso excel.exe.

¿Hay alguna manera de modificar mi código anterior para que, si el archivo está en uso, este script de Python cierre automáticamente el proceso en segundo plano de Excel y luego lo ejecute nuevamente? O cuando se ejecuten los macro1,2,3,4 y no se completen correctamente, que la tarea en segundo plano de Excel se cierre en ese punto…

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, existen formas de hacer que tus scripts de Python que acceden a archivos de Excel sean más robustos. Una solución posible es utilizar un bloque try-except para capturar cualquier error que pueda ocurrir mientras se ejecutan las macros y luego utilizar el módulo “subprocess” para finalizar el proceso “excel.exe” antes de volver a ejecutar el script. Aquí tienes un ejemplo:

    import subprocess
    
    nombre_archivo = "temp.xlsm"
    
    try:
        # abrir Excel y ejecutar macros
        xl = win32com.client.Dispatch("Excel.Application")
        xl.Workbooks.Open(nombre_archivo, ReadOnly=1)
        xl.Application.Run("macro1")
        xl.Application.Run("macro2")
        xl.Workbooks(1).Close(SaveChanges=1)
        xl.Application.Quit()
        xl = None
    except:
        # si ocurre un error, finalizar el proceso de Excel y volver a ejecutar el script
        cmd = 'taskkill /f /im excel.exe'
        subprocess.call(cmd, shell=True)
        exec(open(__file__).read())
    

    Este código utiliza un bloque try-except para capturar cualquier error que pueda ocurrir mientras se ejecutan las macros. Si ocurre un error, el código utiliza el módulo “subprocess” para ejecutar un comando que finaliza el proceso “excel.exe”. Después de eso, el código vuelve a ejecutarse llamando a “exec(open(file).read())”.

    Otra solución posible es utilizar el módulo “win32api” para comprobar si el identificador de archivo está en uso antes de abrir el archivo de Excel. Aquí tienes un ejemplo:

    import win32api
    
    nombre_archivo = "temp.xlsm"
    
    while True:
        try:
            # comprobar si el identificador de archivo está en uso
            win32api.OpenFile(nombre_archivo, win32api.O_RDWR|win32api.O_EXCL)
        except:
            # si el identificador de archivo está en uso, finalizar el proceso de Excel e intentar nuevamente
            cmd = 'taskkill /f /im excel.exe'
            subprocess.call(cmd, shell=True)
            continue
        else:
            # abrir Excel y ejecutar macros
            xl = win32com.client.Dispatch("Excel.Application")
            xl.Workbooks.Open(nombre_archivo, ReadOnly=1)
            xl.Application.Run("macro1")
            xl.Application.Run("macro2")
            xl.Workbooks(1).Close(SaveChanges=1)
            xl.Application.Quit()
            xl = None
            break
    

    Este código utiliza un bucle while para verificar si el identificador de archivo está en uso antes de abrir el archivo de Excel. Si el identificador de archivo está en uso, el código utiliza el módulo “subprocess” para ejecutar un comando que finaliza el proceso “excel.exe” y luego intenta nuevamente. Una vez que el identificador de archivo no está en uso, el código abre Excel y ejecuta las macros como antes.

Comments are closed.