[英]Handling VBA popup message boxes in Microsoft Excel
我需要用 Python 自动化 Excel 文件,问题是 Excel 中有宏,单击宏按钮时会弹出一个弹出窗口:
弹出消息框本身有一个按钮,我必须单击它才能继续。 我已经尝试过使用 Python 中的 Win32com 和 Win32 API 库,但在文档中找不到任何解决方案。
我的代码如下:
ms_excel_app = win32.gencache.EnsureDispatch('Excel.Application')
ms_excel_app.Visible = True
ms_excel_app.DisplayAlerts = False
template_file = r"C:\Templates_for_test\macro_test.xlsm"
ms_excel_file =ms_excel_app.Workbooks.Open(template_file)
ms_excel_file.DisplayAlerts = False
excel_sheet = ms_excel_file.ActiveSheet
# Opening a template file
ms_excel_file = ms_excel_app.Workbooks.Open(template_file)
spread_sheet = ms_excel_file.ActiveSheet
# Click on 'Current date and time' macro button
ms_excel_app.Application.Run("Sheet1.CommandButton1_Click")
# TODO verify verify timestamp and click ok- popup appears verify date and time format : dd/mm/yyyy hh:mm:ss
timestamp_message = time.strftime("%d/%m/%Y %H:%M:%S")
我想要做的是识别屏幕截图中的弹出窗口,然后单击“确定”按钮
有点晚了,因为我遇到了同样的情况,所以只发布一个解决方案。
消息框使 Excel 应用程序卡住并相应地阻止您的主进程。 所以,一个通用的解决方案:
当您使用pywin32
,它还可用于捕获和关闭消息框。 一个Thread
类来完成这项工作:
# ButtonClicker.py
import time
from threading import Thread, Event
import win32gui, win32con
class ButtonClicker(Thread):
def __init__(self, title:str, interval:int):
Thread.__init__(self)
self._title = title
self._interval = interval
self._stop_event = Event()
def stop(self):
'''Stop thread.'''
self._stop_event.set()
@property
def stopped(self):
return self._stop_event.is_set()
def run(self):
while not self.stopped:
try:
time.sleep(self._interval)
self._close_msgbox()
except Exception as e:
print(e, flush=True)
def _close_msgbox(self):
# find the top window by title
hwnd = win32gui.FindWindow(None, self._title)
if not hwnd: return
# find child button
h_btn = win32gui.FindWindowEx(hwnd, None,'Button', None)
if not h_btn: return
# show text
text = win32gui.GetWindowText(h_btn)
print(text)
# click button
win32gui.PostMessage(h_btn, win32con.WM_LBUTTONDOWN, None, None)
time.sleep(0.2)
win32gui.PostMessage(h_btn, win32con.WM_LBUTTONUP, None, None)
time.sleep(0.2)
最后,您的代码可能如下所示:
from ButtonClicker import ButtonClicker
# 1. start a child thread
# ButtonClicker instance tries to catch window with specified `title` at a user defined frequency.
# In your case, the default title for Excel message box is `Microsoft Excel`.
listener = ButtonClicker("Microsoft Excel", 3)
listener.start()
# 2. do your work with Excel file as before
# though it might be blocked by message box, the concurrent child thread will close it
ms_excel_app = win32.gencache.EnsureDispatch('Excel.Application')
ms_excel_app.Visible = True
ms_excel_app.DisplayAlerts = False
template_file = r"C:\Templates_for_test\macro_test.xlsm"
...
# 3. close the child thread finally
listener.stop()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.