import time
import win32com.client
import pandas as pd
import locale
import sys
from datetime import datetime
import win32com.client as win32
# 获取当前日期和时间
now = datetime.now()
# 将日期格式化为 "dd.mm.yyyy"
formatted_date = now.strftime("%d.%m.%Y")
def output_session():
# 获取SAP GUI对象
SapGuiAuto = win32com.client.GetObject("SAPGUI")
# 获取SAP应用程序对象
application = SapGuiAuto.GetScriptingEngine
# 获取连接对象
connection = application.Children(0)
# 获取会话对象
session = connection.Children(0)
return session
def is_clear_item(session):
# 此函数取消使用
# 判断是否只有一条数据
all_number = session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6102/txtRF05A-ANZPO").text
print("Number of items: " + all_number)
if all_number == "1":
print("No items to clear")
return "No items to clear"
# 判断是否有可清项
haveNegativeItem = False
havePositiveItem = False
row_count = 0
for index in range(int(all_number)):
if row_count == 20:
# 点击Next Page
session.findById("wnd[0]").maximize
session.findById("wnd[0]").sendVKey(23)
time.sleep(2)
row_count = 0
# 读取日期
Amount = session.findById(f"wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6102/tblSAPDF05XTC_6106/txtDF05B-PSBET[9,{str(row_count)}]").text
print("Amount: " + Amount)
if "-" in str(Amount):
haveNegativeItem = True
elif "-" not in str(Amount):
havePositiveItem = True
elif haveNegativeItem and havePositiveItem:
break
else:
pass
row_count += 1
if not haveNegativeItem:
print("No negative items to clear")
return haveNegativeItem
if not havePositiveItem:
print("No positive items to clear")
return havePositiveItem
def net_data(session):
# 选择第六列第0行日期-点击排序
session.findById("wnd[0]/usr/tabsTS/tabpREST").select()
session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/tblSAPDF05XTC_6106/ctxtRFOPS_DK-NETDT[7,0]").setFocus()
session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/btnICON_SORT_UP").press()
def do_clear_item(session):
"""
如果总金额为负数,先选择所有正数
:param session:
:return:
"""
# 总条数
row_count = 0
all_number = session.findById("wnd[0]/usr/tabsTS/tabpMAIN/ssubPAGE:SAPDF05X:6102/txtRF05A-ANZPO").text
all_money = session.findById("wnd[0]/usr/tabsTS/tabpMAIN/ssubPAGE:SAPDF05X:6102/txtRF05A-NETTO").text
if float(str(all_money).replace("-", "").strip().replace(",","")) == 0:
print("amount is 0")
# 点击 charge off dis
session.findById("wnd[0]/tbar[1]/btn[7]").press()
# reference
session.findById("wnd[0]/usr/txtBKPF-XBLNR").text = "JD_AR_CLEARING"
# PstKy
session.findById("wnd[0]/usr/ctxtRF05A-NEWBS").text = ""
# Account
session.findById("wnd[0]/usr/ctxtRF05A-NEWKO").text = ""
time.sleep(1)
else:
is_click = False
# 不选中所有行
session.findById("wnd[0]/usr/tabsTS/tabpMAIN/ssubPAGE:SAPDF05X:6102/btnICON_SELECT_ALL").press()
session.findById("wnd[0]/usr/tabsTS/tabpMAIN/ssubPAGE:SAPDF05X:6102/btnIC_Z-").press()
if "-" in all_money:
# 正数先排序
session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6102/tblSAPDF05XTC_6102/txtDF05B-PSBET[9,0]").setFocus()
session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6102/btnICON_SORT_DOWN").press()
else:
# 负数先排序
session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6102/tblSAPDF05XTC_6102/txtDF05B-PSBET[9,0]").setFocus()
session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6102/btnICON_SORT_UP").press()
for index in range(int(all_number)):
# 选中所有正数
if row_count == 20:
# 点击Next Page
session.findById("wnd[0]").maximize
session.findById("wnd[0]").sendVKey(23)
row_count = 0
Amount = session.findById(f"wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6102/tblSAPDF05XTC_6102/txtDF05B-PSBET[9,{row_count}]").text
# 如果总金额为负数,先选中所有正数;如果总金额为正数,先选中所有负数
if "-" in all_money:
if "-" not in str(Amount):
session.findById(f"wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6102/tblSAPDF05XTC_6102/txtDF05B-PSBET[9,{row_count}]").setFocus()
session.findById("wnd[0]").sendVKey(2)
is_click = True
else:
net_data(session)
break
else:
if "-" in str(Amount):
session.findById(f"wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6102/tblSAPDF05XTC_6102/txtDF05B-PSBET[9,{row_count}]").setFocus()
session.findById("wnd[0]").sendVKey(2)
is_click = True
else:
net_data(session)
break
row_count += 1
if is_click:
print("Have items to clear")
else:
print("Clearing is not supported")
return "NO Clearing is not supported"
# 恢复到第一行
session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/txtRF05A-ABPOS").text = "1"
session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/txtRF05A-ABPOS").setFocus()
session.findById("wnd[0]").sendVKey(2)
row_count = 0
for index in range(int(all_number)):
# 选中所有负数
if row_count == 20:
# 点击Next Page
session.findById("wnd[0]").maximize
session.findById("wnd[0]").sendVKey(23)
row_count = 0
Amount = session.findById(f"wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/tblSAPDF05XTC_6106/txtDF05B-PSBET[9,{row_count}]").text
if "-" in all_money:
# 选中所有负数
if "-" in str(Amount):
session.findById(f"wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/tblSAPDF05XTC_6106/txtDF05B-PSBET[9,{row_count}]").setFocus()
session.findById("wnd[0]").sendVKey(2)
# 判断当前差额
Assigned = session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/txtRF05A-NETTO").text
print(Assigned)
if float(str(Assigned).replace("-", "").strip().replace(",","")) <= 1 and float(str(Assigned).replace("-", "").strip().replace(",","")) != 0:
# 点击 charge off dis
session.findById("wnd[0]/tbar[1]/btn[7]").press()
# PstKy
session.findById("wnd[0]/usr/ctxtRF05A-NEWBS").text = "50"
# Account
session.findById("wnd[0]/usr/ctxtRF05A-NEWKO").text = "67432000"
# reference
session.findById("wnd[0]/usr/txtBKPF-XBLNR").text = "JD_AR_CLEARING"
session.findById("wnd[0]").sendVKey(2)
# Amount
session.findById("wnd[0]/usr/txtBSEG-WRBTR").text = float(str(Assigned).replace("-", "").strip().replace(",",""))
# Cost Center
session.findById("wnd[0]/usr/subBLOCK:SAPLKACB:1015/ctxtCOBL-KOSTL").text = "S105"
break
if "-" in Assigned:
session.findById(f"wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/tblSAPDF05XTC_6106/txtDF05B-PSDIF[10,{row_count}]").setFocus()
session.findById("wnd[0]").sendVKey(2)
# 点击 charge off dis
session.findById("wnd[0]/tbar[1]/btn[7]").press()
# reference
session.findById("wnd[0]/usr/txtBKPF-XBLNR").text = "JD_AR_CLEARING"
# PstKy
session.findById("wnd[0]/usr/ctxtRF05A-NEWBS").text = ""
# Account
session.findById("wnd[0]/usr/ctxtRF05A-NEWKO").text = ""
time.sleep(1)
break
else:
# 选中所有正数
if "-" not in str(Amount):
session.findById(f"wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/tblSAPDF05XTC_6106/txtDF05B-PSBET[9,{row_count}]").setFocus()
session.findById("wnd[0]").sendVKey(2)
# 判断当前差额
Assigned = session.findById("wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/txtRF05A-NETTO").text
print(Assigned)
if float(str(Assigned).replace("-", "").strip().replace(",","")) <= 1 and float(str(Assigned).replace("-", "").strip().replace(",","")) != 0:
# 点击 charge
session.findById("wnd[0]/tbar[1]/btn[7]").press()
# PstKy
session.findById("wnd[0]/usr/ctxtRF05A-NEWBS").text = "50"
# Account
session.findById("wnd[0]/usr/ctxtRF05A-NEWKO").text = "67432000"
# reference
session.findById("wnd[0]/usr/txtBKPF-XBLNR").text = "JD_AR_CLEARING"
session.findById("wnd[0]").sendVKey(2)
# Amount
session.findById("wnd[0]/usr/txtBSEG-WRBTR").text = float(str(Assigned).replace("-", "").strip().replace(",", ""))
# Cost Center
session.findById("wnd[0]/usr/subBLOCK:SAPLKACB:1015/ctxtCOBL-KOSTL").text = "S105"
break
if "-" not in Assigned:
session.findById(f"wnd[0]/usr/tabsTS/tabpREST/ssubPAGE:SAPDF05X:6106/tblSAPDF05XTC_6106/txtDF05B-PSDIF[10,{row_count}]").setFocus()
session.findById("wnd[0]").sendVKey(2)
# 点击 charge off difference
session.findById("wnd[0]/tbar[1]/btn[7]").press()
# reference
session.findById("wnd[0]/usr/txtBKPF-XBLNR").text = "JD_AR_CLEARING"
# PstKy
session.findById("wnd[0]/usr/ctxtRF05A-NEWBS").text = ""
# Account
session.findById("wnd[0]/usr/ctxtRF05A-NEWKO").text = ""
break
row_count += 1
# 点击save
session.findById("wnd[0]/tbar[0]/btn[11]").press()
time.sleep(1)
status = session.findById("wnd[0]/sbar/pane[0]").text
# status = "YES TEST SUCCESSFUL"
if "was posted in company" in status:
return "YES" + status
else:
return "NO" + status
def handling_clear_5523(excel_BL5N, Tomail):
# 创建结果表
column_names = ["Execute Result in SAP including Document", "Sequence", "Account"]
error_DT = pd.DataFrame(columns=column_names)
correct_DT = pd.DataFrame(columns=column_names)
# 初始时间
start_time = datetime.now()
# 连接sap
session = output_session()
# 读取BL5N数据
BL5N_DT = pd.read_excel(excel_BL5N)
# 获取所有account,并去重
Accounts = BL5N_DT["Account"].values.tolist()
unique_accounts = list(set(Accounts))
error_sequence = 1
correct_sequence = 1
for account in unique_accounts:
lst = BL5N_DT[BL5N_DT["Account"] == account]["Amount in doc. curr."].tolist()
all_positive = all(float(str(x).replace(",", "")) > 0 for x in lst)
all_negative = all(float(str(x).replace(",", "")) < 0 for x in lst)
if all_positive or all_negative:
print("All items are positive or negative")
continue
session.findById("wnd[0]/tbar[0]/okcd").text = "/nf-32"
session.findById("wnd[0]/tbar[0]/btn[0]").press()
# Account
session.findById("wnd[0]/usr/ctxtRF05A-AGKON").text = account
# Clearing Date
session.findById("wnd[0]/usr/ctxtBKPF-BUDAT").text = formatted_date
# Company Code
session.findById("wnd[0]/usr/ctxtBKPF-BUKRS").text = "5523"
# Currency
session.findById("wnd[0]/usr/ctxtBKPF-WAERS").text = "CNY"
# Special G/L Ind
session.findById("wnd[0]/usr/ctxtRF05A-AGUMS").text = "A"
# click Additional Selection
session.findById("wnd[0]/usr/sub:SAPMF05A:0131/radRF05A-XPOS1[0,0]").select()
# click Process Open Items
session.findById("wnd[0]/tbar[1]/btn[16]").press()
time.sleep(1)
status = session.findById("wnd[0]/sbar/pane[0]").text
print(status)
if "items were selected" not in status:
print("No open items were found")
new_rows = pd.Series([status, error_sequence, account], index=column_names)
error_DT = pd.concat([error_DT, new_rows.to_frame().T], ignore_index=True)
error_sequence += 1
continue
res = do_clear_item(session)
if "YES" in res:
new_rows = pd.Series([res.replace("YES", ""), correct_sequence, account], index=column_names)
correct_DT = pd.concat([correct_DT, new_rows.to_frame().T], ignore_index=True)
correct_sequence += 1
else:
new_rows = pd.Series([res.replace("NO", ""), error_sequence, account], index=column_names)
error_DT = pd.concat([error_DT, new_rows.to_frame().T], ignore_index=True)
error_sequence += 1
# 结束时间
end_time = datetime.now()
# 计算运行时间
gap_time = end_time - start_time
# 获取差异的总秒数
total_seconds = int(gap_time.total_seconds())
# 计算小时、分钟和秒
hours, remainder = divmod(total_seconds, 3600)
minutes, seconds = divmod(remainder, 60)
# 格式化为时:分:秒
time_str = f"{hours:02}:{minutes:02}:{seconds:02}"
html_produce(time_str, error_DT, correct_DT, Tomail)
def html_produce(gap_time, error_DT, correct_DT, Tomail):
html_table = []
html_table.append("""
JD Clearing Result
""")
html_table.append(f'JD Clearing Result 清账用时{gap_time}
')
html_table.append(f'处理异常: {error_DT.shape[0]} 条, 处理成功: {correct_DT.shape[0]} 条
')
html_table.append('')
# 添加表头
html_table.append(" ")
for col in error_DT.columns:
html_table.append(f"{col} | ")
html_table.append("
")
for index, row in error_DT.iterrows():
html_table.append(" ")
for col in error_DT.columns:
html_table.append(f"{row[col]} | ")
html_table.append("
")
# 添加表头
html_table.append(" ")
for col in correct_DT.columns:
html_table.append(f"{col} | ")
html_table.append("
")
for index, row in correct_DT.iterrows():
html_table.append(" ")
for col in correct_DT.columns:
html_table.append(f"{row[col]} | ")
html_table.append("
")
html_table.append("