使用多线程点击 VBA 运行中的消息提示框

业务场景

使用 win32com 运行 Excel 中的宏运算(VBA),会遇到 VBA 运行的最后一步会弹出消息提示框,需点击这个消息提示框之后,VBA 才能运行结束,所以在运行 VBA 之后加入 Try 组件去点击时无法点击的,所以考虑使用多线程来实现。

流程代码

import ubpa.iautomation as iautomation
import threading
import pythoncom
import time
#点击消息提示框按钮
def cilck_ok():
	while True:
        # Try异常
        try:
            # 鼠标点击
            iautomation.WinSearchDepth=2
            selectorJson = {"selector":[{"ControlType":"按钮","ControlTypeID":"0xC350","Index":"1"},
		{"ControlType":"对话框","ControlTypeID":"0xC370","Index":"1"}]}
            iautomation.do_click(win_class=r'XLMAIN',win_name=r'aaaa.xlsm - Excel',selector=selectorJson,button=r'left',curson=r'center',offsetX=0,offsetY=0,times=1,run_mode=r'unctrl',waitfor=3)
            time.sleep(1)
            # Break中断
            break
        except Exception as e:
        
            pass
        finally:
            pass
			
#VBA运行代码
def run_vba(path):
    '''
    一定要添加pythoncom.CoInitialize() 
    一定要添加pythoncom.CoInitialize()
    一定要添加pythoncom.CoInitialize()
    重要的事情说三遍
    '''
    #CoInitialize是 Windows提供的API函数,用来告诉 Windows以单线程的方式创建com对象
    pythoncom.CoInitialize()
    #载入Excel
    xlApp=win32com.client.Dispatch("Excel.Application")
    #设置是否打开Excel
    xlApp.Visible=True
    #设置是否显示警告和消息框
    xlApp.DisplayAlerts=False
    xlwb=xlApp.Workbooks.Open(path,False)
    #macro1为VBA方法名称
    xlwb.Application.Run('macro1')
    xlwb.Save()
    xlwb.Close()
    xlApp.Quit()

#线程启动代码
def start_thread(path): 
    #创建线程数组
    threads = []
    #创建线程t1,target:调用的函数,args:函数中需要的参数
    t1 = threading.Thread(target=run_vba,args=(path,))
    #添加线程t1到线程数组
    threads.append(t1)
    #创建线程t2
    t2 = threading.Thread(target=cilck_ok)
    #添加线程t2到线程数组
    threads.append(t2)
    for t in threads:
        '''
        setDaemon(True)将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序
        会被无限挂起。子线程启动后,父线程也继续执行下去,当父线程执行完后,没有等待子线程,
        直接就退出了,同时子线程也一同结束。
        '''
	t.setDaemon(True)
	#开始线程活动
	t.start() 
    
    for t in threads:
	#join()方法,用于等待线程终止。join()的作用是,在子线程完成运行之前,这个子线程的父线程将一直被阻塞
	t.join()