[英]Can I suppress message box from VBA using xlwings?
我正在使用 xlwings(python 3.7)從 VBA 調用宏。 運行時,宏會填充一個消息框
我想知道是否有辦法從xlwings端抑制它(例如根本不顯示消息框或自動單擊確定)(無法更改宏,鎖定)。 我當前的設置如下所示:
app = xw.apps.active # open application instance
app.visible = False # Excel application not visible
app.display_alerts = False # supress alert messages
app.screen_updating = False # supress screen updates
謝謝!
由於您無法更改宏,因此左側選項是自動單擊“確定”按鈕。 顯然,您不能在主進程中執行此操作,因為一旦出現消息框就會卡住。 因此,您需要創建一個子線程來同時執行此操作,從而使主進程從卡住中恢復。 總之,你需要兩件事:
threading.Thread
pywin32
、 pywinauto
或PyAutoGUI
。 當您使用xlwings
時,應該已經將pywin32
作為依賴項安裝。 因此,例如在這里使用它。
整個過程如下:
import xlwings as xw
from listener import MsgBoxListener
# start child thread
listener = MsgBoxListener('Message-box-title-in-your-case', 3)
listener.start()
# main process as you did before
app = xw.apps.active # open application instance
app.visible = False # Excel application not visible
app.display_alerts = False # supress alert messages
app.screen_updating = False # supress screen updates
...
# stop listener thread
listener.stop()
其中MsgBoxListener
是捕獲和關閉消息框的子線程:
title
是消息框的標題,隱藏在您的屏幕截圖中interval
是檢測是否存在消息框的頻率# listener.py
import time
from threading import Thread, Event
import win32gui
import win32con
class MsgBoxListener(Thread):
def __init__(self, title:str, interval:int):
Thread.__init__(self)
self._title = title
self._interval = interval
self._stop_event = Event()
def stop(self): self._stop_event.set()
@property
def is_running(self): return not self._stop_event.is_set()
def run(self):
while self.is_running:
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)
if __name__=='__main__':
t = MsgBoxListener('Microsoft Excel', 1)
t.start()
time.sleep(10)
t.stop()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.