【问题标题】:Avoiding repetitive code in python and reuse the existing code避免python中的重复代码并重用现有代码
【发布时间】:2019-08-20 12:48:17
【问题描述】:

我正在从我正在处理的一个应用程序中抓取一些屏幕,并且代码的一部分变得重复。如何避免重复代码并重用代码的早期部分?代码中没有错误,只是重复部分使代码难以维护。

以下是我的逻辑/伪代码:

  1. 从 excel 中读取部门名称。
  2. 登录应用程序
  3. 循环获取部门名称。
  4. 输入部门和日期范围以获取屏幕 A 中的所有员工列表
  5. 屏幕 B 复制每一行的员工 ID。
  6. 转到屏幕 C,根据 id 旁边的分机号查看员工是否处于活动状态或已重新加入
  7. 进入屏幕 D 输入员工详细信息以检查培训是否完成。
  8. 根据前面提到的日期范围复制数据库。
  9. 按照步骤返回屏幕 A,直到屏幕 B 选择该 eid 的行,如果屏幕 D 中的日期匹配,则将其关闭。
  10. 然后选择下一行,再按照整个流程。

这是实际代码:

import win32com.client
import sys
import subprocess
import time
import pandas as pd
import numpy as np
from datetime import date
from datetime import datetime, timedelta
from multiprocessing import Process

eid = pd.read_excel(r'C:\employee\ee_details.xlsx'
                  ,sheet_name='Sheet1'
                  ,header=0
                ,dtype=str
                )
to_day= datetime.today()
raaweekday = datetime.today().weekday()
friday=datetime.today() - timedelta(days=to_day.weekday()-3)
friday=friday.strftime("%m/%d/%Y")
print(friday)

monday=datetime.today() - timedelta(days=to_day.weekday())
monday=monday.strftime("%m/%d/%Y")
print(monday)
j=[]
to_day=to_day.strftime("%m/%d/%Y")
for i in eid['Dept']:
    j = i
    print(j)

def saplogin():
    try:
        path = r'C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe'
        subprocess.Popen(path)
        time.sleep(10)
        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.OpenConnection("EQ2", True)
        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
        
       # Login to SBS BANKING
        session.findById("wnd[0]").Maximize
        session.findById("wnd[0]/usr/txtRSYST-BNAME").Text = username
        session.findById("wnd[0]/usr/pwdRSYST-BCODE").Text = password
        session.findById("wnd[0]").sendVKey(0)
        session.findById("wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell").selectedNode = "0000000077"
        session.findById("wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell").doubleClickNode("0000000077")
        session.findById("wnd[0]").sendVKey(2)

        b = 0
        while b < len(eid['Dept']):
            session.findById("wnd[0]/usr/txtP_BR").Text = eid['Dept'][b]
            session.findById("wnd[0]/usr/ctxtS_DISBDT-LOW").text = "07/01/2019"
            session.findById("wnd[0]/usr/ctxtS_DISBDT-HIGH").text = to_day
            session.findById("wnd[0]/usr/ctxtS_IMPDT-LOW").text = "07/01/2019"
            session.findById("wnd[0]/usr/ctxtS_IMPDT-HIGH").text = to_day
            session.findById("wnd[0]").sendVkey(8)
        
            grid=session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell")
            cntRows = session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").RowCount
            i=0
            while i < cntRows:
                rowValue= session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").GetCellValue(i,"ZCOMMENTS")
                if rowValue=="Training Completed":
                    global eid
                    eid=session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").GetCellValue(i,"Z_EID")                    
                    session.findById("wnd[0]").sendVKey(3)
                    session.findById("wnd[0]").sendVKey(3)
    
                    session.findById("wnd[0]/tbar[0]/okcd").text = "FPP3"
                    session.findById("wnd[0]").sendVKey(0)
                    fpp3=session.findById("wnd[1]/usr/ctxtBUS_JOEL_MAIN-OPEN_NUMBER").Text=eid['Dept'][b]+eid+"-A"
                    session.findById("wnd[1]/tbar[0]/btn[0]").press()
                    pp3=session.findById("wnd[0]/usr/subSCREEN_3000_RESIZING_AREA:SAPLBUS_LOCATOR:2036/subSCREEN_1010_LEFT_AREA:SAPLBUS_LOCATOR:3100/tabsGS_SCREEN_3100_TABSTRIP/tabpBUS_LOCATOR_TAB_02/ssubSCREEN_3100_TABSTRIP_AREA:SAPLBUS_LOCATOR:3200/subSCREEN_3200_SEARCH_AREA:SAPLBUS_LOCATOR:3211/subSCREEN_3200_SEARCH_FIELDS_AREA:SAPLBUPA_DIALOG_SEARCH:2100/txtBUS_JOEL_SEARCH-PARTNER_NUMBER").Text = eid['Dept'][b]+eid+"*"
                    session.findById("wnd[0]/usr/subSCREEN_3000_RESIZING_AREA:SAPLBUS_LOCATOR:2036/subSCREEN_1010_LEFT_AREA:SAPLBUS_LOCATOR:3100/tabsGS_SCREEN_3100_TABSTRIP/tabpBUS_LOCATOR_TAB_02/ssubSCREEN_3100_TABSTRIP_AREA:SAPLBUS_LOCATOR:3200/subSCREEN_3200_SEARCH_AREA:SAPLBUS_LOCATOR:3211/subSCREEN_3200_SEARCH_BUTTON_AREA:SAPLBUS_LOCATOR:3240/btnBUS_LOCA_SRCH01-GO").press()
                    p = 0
                    orgRole = session.findById("wnd[0]/usr/subSCREEN_3000_RESIZING_AREA:SAPLBUS_LOCATOR:2036/subSCREEN_1010_LEFT_AREA:SAPLBUS_LOCATOR:3100/tabsGS_SCREEN_3100_TABSTRIP/tabpBUS_LOCATOR_TAB_02/ssubSCREEN_3100_TABSTRIP_AREA:SAPLBUS_LOCATOR:3200/subSCREEN_3200_SEARCH_AREA:SAPLBUS_LOCATOR:3211/subSCREEN_3200_RESULT_AREA:SAPLBUPA_DIALOG_JOEL:1060/ssubSCREEN_1060_RESULT_AREA:SAPLBUPA_DIALOG_JOEL:1080/cntlSCREEN_1080_CONTAINER/shellcont/shell").RowCount
                    
                    while p < orgRole:
                        training=session.findById("wnd[0]/usr/subSCREEN_3000_RESIZING_AREA:SAPLBUS_LOCATOR:2036/subSCREEN_1010_LEFT_AREA:SAPLBUS_LOCATOR:3100/tabsGS_SCREEN_3100_TABSTRIP/tabpBUS_LOCATOR_TAB_02/ssubSCREEN_3100_TABSTRIP_AREA:SAPLBUS_LOCATOR:3200/subSCREEN_3200_SEARCH_AREA:SAPLBUS_LOCATOR:3211/subSCREEN_3200_RESULT_AREA:SAPLBUPA_DIALOG_JOEL:1060/ssubSCREEN_1060_RESULT_AREA:SAPLBUPA_DIALOG_JOEL:1080/cntlSCREEN_1080_CONTAINER/shellcont/shell").GetCellValue(p, "TRAINING")
                        print(training)
                        time.sleep(10)
                        p+=1
                        session.findById("wnd[0]").sendVKey(3)
                        session.findById("wnd[0]/tbar[0]/okcd").text = "FPL9"
                        session.findById("wnd[0]").sendVKey(0)
                        session.findById("wnd[0]/usr/ctxtFKKL1-GPART").text = training
                        session.findById("wnd[0]/usr/cmbFKKL1-LSTYP").key = "COMPLETED_OPEN"
                        session.findById("wnd[0]").sendVKey(0)
                        session.findById("wnd[0]").sendVKey(3)
                        session.findById("wnd[0]").sendVKey(3)

                        #Code that is being to repeat how to avoid the below code and re-use the above code
#             # going back to the impound screen
                        session.findById("wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell").selectedNode = "0000000077"
                        session.findById("wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell").doubleClickNode("0000000077")
                        session.findById("wnd[0]").sendVKey(2)
                        session.findById("wnd[0]/usr/txtP_BR").Text = eid['Dept'][b]
                        session.findById("wnd[0]/usr/txtS_CO-LOW").Text =eid
                        session.findById("wnd[0]/usr/txtP_BR").Text = eid['Dept'][b]
                        session.findById("wnd[0]/usr/ctxtS_DISBDT-LOW").text = "07/01/2019"
                        session.findById("wnd[0]/usr/ctxtS_DISBDT-HIGH").text = to_day
                        session.findById("wnd[0]/usr/ctxtS_IMPDT-LOW").text = "07/01/2019"
                        session.findById("wnd[0]/usr/ctxtS_IMPDT-HIGH").text = to_day
                        session.findById("wnd[0]").sendVkey(8)
                        #session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").Select
                        time.sleep(10)
                        session.findById("wnd[0]").sendVKey(3)
                        session.findById("wnd[0]/usr/txtP_BR").Text = eid['Dept'][b]
                        session.findById("wnd[0]/usr/txtS_CO-LOW").Text =""
                        session.findById("wnd[0]/usr/txtP_BR").Text = eid['Dept'][b]
                        session.findById("wnd[0]/usr/txtS_CO-LOW").Text =eid
                        session.findById("wnd[0]/usr/txtP_BR").Text = eid['Dept'][b]
                        session.findById("wnd[0]/usr/ctxtS_DISBDT-LOW").text = "07/01/2019"
                        session.findById("wnd[0]/usr/ctxtS_DISBDT-HIGH").text = to_day
                        session.findById("wnd[0]/usr/ctxtS_IMPDT-LOW").text = "07/01/2019"
                        session.findById("wnd[0]/usr/ctxtS_IMPDT-HIGH").text = to_day
                        session.findById("wnd[0]").sendVkey(8)
                        next
#                         session.findById("wnd[0]/usr/txtP_BR").Text =eid['Dept'][b]
                       
                b+=1
        print(b)
    
    except:
        print("NOT WORKING")
    finally:
        session = None
        connection = None
        application = None
        SapGuiAuto = None

saplogin()

【问题讨论】:

  • 尝试使用像 PyCharm 这样的 IDE。他们提供内置的代码重构解决方案。您可以只选择代码的重复部分并将其重构为可重用的方法。它甚至可以选择用方法调用替换重复。
  • @rdas 我可以在 Anaconda 中使用 PyCharm - 我没有下载未经授权的 IDE 的选项

标签: python python-3.x code-reuse sap-gui


【解决方案1】:

如果您有需要多次执行的操作,则必须重复代码。没办法。你只能简化。

  1. 所有被调用两次以上的东西都应该被调用一次并分配给一个对象。这样可以节省大量时间。我假设session 的包含在您的scraping 期间不会改变。因此,session.findById("wnd[0]") 可以存储在变量中以便更快地引用。

  2. 将重复调用的代码放入函数中。例如:

                session.findById("wnd[0]/usr/txtP_BR").Text = eid['Dept'][b]
                session.findById("wnd[0]/usr/txtS_CO-LOW").Text =eid
                session.findById("wnd[0]/usr/txtP_BR").Text = eid['Dept'][b]
                session.findById("wnd[0]/usr/ctxtS_DISBDT-LOW").text = "07/01/2019"
                session.findById("wnd[0]/usr/ctxtS_DISBDT-HIGH").text = to_day
                session.findById("wnd[0]/usr/ctxtS_IMPDT-LOW").text = "07/01/2019"
                session.findById("wnd[0]/usr/ctxtS_IMPDT-HIGH").text = to_day
                session.findById("wnd[0]").sendVkey(8)
    

进入一个函数do_stuff(session),它接受session- 对象以获得正确的上下文。 这样您只需维护该函数,每次调用该函数都会减少您的维护工作量。

  1. 将您的所有 ID 字符串(如 "wnd[0]")放入带有“说话”索引的字典中。这样您就可以避免拼写错误并节省大量因 ID 字符串拼写错误而导致的调试时间。

您是否可以将所有数据转储到数据帧中?所以屏A变成一个,屏B变成另一个,C和D也一样?如果是这样,您可能能够通过使用 Pandas API 巧妙地合并和连接表来获得相同的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多