python驅動SAP完成數據導出(二)

  在上一篇 python驅動SAP完成數據導出(一)中,我們提到了數據導出前,SAP佈局的重要性,如何識別當前佈局模式,以及如何切換到想要的佈局。本篇小爬將着重講講數據導出的注意事項。

我們可以通過如下方式進行導出:

 

 

 

 

 

 

 其中方法一與方法三並無本質差別,最終都是可以腳本錄製或者快捷鍵(Ctrl+Shift+F7)得到,點擊導出按鈕後,界面【選擇電子表格】如下:

 

 

 但是假如用戶曾經勾選過上圖中的【始終使用選定的格式】,那麼則不會彈出上圖所示窗口,直接進入如下界面:

 

 

 

 注意一:

  如果用戶執行操作前沒有點擊【腳本錄製】,則會彈出如下windows【另存爲】界面:

 

 

 

由於該界面是windows系統窗體,無法通過腳本錄製得到自動化腳本代碼,所以我們務必要提前進行腳本錄製動作,才能確保文件保存的界面可通過錄制腳本得到代碼。

注意二:

  如果我們一開始選擇的方法二 進行數據導出,則無論用戶是否勾選【始終使用選定的格式】選項,SAP均會彈出【選擇電子表格】界面。

 

  因此,爲了避免操作界面不一致帶來的代碼兼容問題,小爬建議大家使用方法二來執行數據導出。

最後的導出界面,用戶可以設置保存的路徑和文件名,最後基於各自的情況點擊【生成】或者【替代】按鈕(【替代】按鈕,意味着如果設定目錄中如果提前有同名文件,則會被新文件覆蓋)。

  點擊完導出後,SAP會默認調用Excel進程,生成一個Excel文件,持續往該文件中傳輸值,待傳輸完畢後,SAP左下角會有消息顯示:已傳輸***個字節。且該Excel文件會被excel自動打開。

 

  那麼問題來了,如果我們要通過腳本批量下載多個報表數據,則SAP會自動創建並打開N個excel文件,此舉很有可能導致系統內存緊張甚至excel文件崩潰。因此我們有必要及時自動關閉Excel文件。這該如何處理呢?

顯然,我們必須藉助於windows系統api來實現,python下就必須依託於pywin32庫。同時我們還要藉助SPY++提前捕獲窗口信息。

 

 

 

 

   可以看到當系統是否隱藏了文件擴展名,最後窗口標題是有差別的,而FindWindow函數本身不支持基於窗口標題模糊查找,我們代碼裏不得不特殊化處理。

基於前文提到的方法二導出的,具體的示例代碼如下(FB03爲例):

 1 import sys, win32com.client,os,win32gui,win32con,time
 2 def Main():
 3   try:
 4     SapGuiAuto = win32com.client.GetObject("SAPGUI")
 5     application = SapGuiAuto.GetScriptingEngine
 6     connection = application.Children(0)
 7     if connection.DisabledByServer == True:
 8       print("Scripting is disabled by server")
 9       application = None
10       SapGuiAuto = None
11       return
12 
13     session = connection.Children(0)
14     if session.Busy == True:
15       print("Session is busy")
16       session = None
17       connection = None
18       application = None
19       SapGuiAuto = None
20       return
21 
22     if session.Info.IsLowSpeedConnection == True:
23       print("Connection is low speed")
24       session = None
25       connection = None
26       application = None
27       SapGuiAuto = None
28       return
29 
30     session.findById("wnd[0]").maximize()
31     session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").contextMenu()
32     session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").selectContextMenuItem("&XXL")
33     session.findById("wnd[1]/tbar[0]/btn[0]").press()
34     session.findById("wnd[1]/usr/ctxtDY_PATH").text = os.getcwd() #保存路徑
35     session.findById("wnd[1]/usr/ctxtDY_FILENAME").text = "reportList.xlsx" #保存文件名
36     session.findById("wnd[1]/tbar[0]/btn[11]").press() #點擊【替代】,覆蓋可能的原文件
37     sapInfo=session.findById("wnd[0]/sbar").text #由於SAP腳本自身的特性,當程序讀到左下角消息時,意味着數據已經傳輸完成!
38 
39     '''找到打開的excel文件,並自動關閉它'''
40     excelHwnd=0
41     while ExcelHwnd==0:
42         time.sleep(0.2)
43         excelHwnd=max(win32gui.FindWindow("XLMAIN","reportList.XLSX - Excel"),win32gui.FindWindow("XLMAIN","reportList - Excel"))
44 
45     '''以防SAP沒有完全釋放Excel進程,建議等待excel窗口可見後,再關閉它'''
46     isVisible=False
47     while isVisible==False:
48         time.sleep(0.2)
49         isVisible=win32gui.IsWindowVisible(excelHwnd)
50 
51     '''關閉excel進程'''
52     win32gui.SendMessage(excelHwnd,win32con.WM_CLOSE,None,None)
53 
54 
55   except Exception as e:
56     print(e)
57     print(sys.exc_info()[0])
58 
59   finally:
60     session = None
61     connection = None
62     application = None
63     SapGuiAuto = None
64 
65 Main()

各位筒子,趕快動手試下吧o(* ̄▽ ̄*)ブ

快來掃碼關注我的公衆號 獲取更多爬蟲、數據分析的知識!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章