小爬之前已經就“Python驅動SAP GUI完成自動化”問題寫過幾篇文章,其核心都是恰當運用SAP GUI Scripting API中元素的屬性和方法,來操縱SAP session的元素。下面來看看兩個新場景下的新問題。
常見場景一:
我們先來看看對象的changeable屬性怎么為我所用來解決特定的問題。
如上圖所示,菜單欄的“基本清單(B)”項 字體為淺灰色,對應的屬性其實就是changeable=False,黑色字體的項則表示changeable=True。我們可以使用工具Tracker的 Analyser模塊掃描下整個sap session會話,結果如下:
工具得到的結果,changeable屬性勾選了的元素,正好對應頁面中菜單欄子菜單為“淺灰色字體”的子元素。
最近,小爬給同事寫的一個自動化腳本,需要根據Faglb03來查找總賬項目,好好的腳本,在用戶電腦上不可用。經仔細對比發現,部分用戶的SAP GUI對應事務代碼下的 清單模式 跟我的不一樣。只要用戶依次點擊了 SAP菜單欄的“設置”、“切換清單(I)”,切換到對應的清單模式,我寫的腳本便可以順利執行。
那么問題就轉化為:如何知道用戶的SAP界面當前使用的哪類清單模式呢?
思路一:
可以借助,Python中的try……except模塊來查找某個清單模式下的元素,當找不到該元素出錯時,我們就可以在except中執行“切換清單”的語句。
思路二:
小爬觀察到,“切換清單”之前 和之后,對應的 SAP “設置”菜單的子項“基本清單(B)”,其屬性 changeable由 False變為了True:我們只要捕獲該屬性,便知道是否需要執行“切換清單”,見下圖標紅處字體顏色可知:
此處的Python代碼示例如下:
# 判斷changeable屬性后,決定是否點擊“切換清單”,來統一用戶界面顯示狀態 If session.findById("wnd[0]/mbar/menu[5]/menu[0]").changeable = True: session.findById("wnd[0]/mbar/menu[5]/menu[8]").Select() # 點擊切換清單
常見場景二:
我們如何捕獲SAP中,某個界面輸入過濾條件后的一長串結果值,如下圖:
上面兩張圖中,step1的傳參步驟都可以通過SAP的腳本錄制功能得到可用的代碼,問題是step2,假如我想獲得所有過濾條件后的總賬科目數據,放入剪貼板,該怎么辦?
我們同樣可以有兩種思路:
思路一:
通過錄制腳本的過程中,點擊“總賬科目”列某一行,就可以根據捕獲的腳本代碼知道元素的ID,然后根據

要使用findAllByName 方法,我們需要知道這些元素的Name和Type,這個可以用 Tracker 工具的analyser掃描后得到,見下圖:
從上圖可知,我們需要的總賬科目編號就是 某個元素的文本,這些元素的共性:Type為GuiLabel (30),而Name為空。有了這些分析,我們就可以用如下的代碼,拿到所有的總賬科目編號,形成列表,最后再push到系統的剪貼板里,供后面的步驟使用:
import sys, win32com.client import win32api,win32con,win32gui,time import win32clipboard as w def get_text(): # 獲取剪貼板中內容 w.OpenClipboard() copy_text = w.GetClipboardData(win32con.CF_TEXT) w.CloseClipboard() return copy_text def set_text(astring): #復制內容到剪切板 w.OpenClipboard() w.EmptyClipboard() d=w.SetClipboardData(win32con.CF_TEXT,astring) w.CloseClipboard() SapGuiAuto = win32com.client.GetObject("SAPGUI") if not type(SapGuiAuto) == win32com.client.CDispatch: return application = SapGuiAuto.GetScriptingEngine if not type(application) == win32com.client.CDispatch: SapGuiAuto = None return connection = application.Children(0) if not type(connection) == win32com.client.CDispatch: application = None SapGuiAuto = None return session = connection.Children(0) if not type(session) == win32com.client.CDispatch: connection = None application = None SapGuiAuto = None return subjects=[] groupMembers=session.ActiveWindow.findAllByName("","GuiLabel (30)") for groupMember in groupMembers: if groupMember.text.startswith("6"): subjects.append(groupMember.text) subjects_string="\r\n".join(subjects).encode()
tips:上面代碼中 set_text(astring)方法可以把 字符串傳給系統的剪貼板,get_text()方法可以獲取剪貼板內容,我們完全可以手工Ctrl+Y & Ctrl+C的方法將這些總賬科目批量復制到剪貼板中,利用 get_text()方法 得到系統中數據的呈現格式,然后利用 set_text(astring)來構造剪貼板內容。
如果您在使用 Python來實現 SAP GUI的一些自動化操作,也遇到過類似的問題場景,上面的對象changeable屬性,findAllByName方法結合Tracker的analyser工具,就提供了一套很好的解決思路,小伙伴們,趕緊動手試試吧!