python自动化:uiautomation、pyautogui操作会计记账系统(4):科目余额表
#coding=utf-8
#科目余额表balance sheet
import xlrd, xlwt, pyautogui, time, pyperclip, openpyxl,pandas,os, tkinter,\
datetime, win32gui, uiautomation, subprocess, xlwings,json, easygui
from tkinter.filedialog import askopenfilename
pyautogui.PAUSE = 1
mont_list =['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
year = time.strftime("%Y")
this_mont = int(time.strftime("%m"))
# year_inpu ='2021'
# mont_inpu ='12'
year_inpu = easygui.integerbox(msg='请输入年份', lowerbound=2005, upperbound=2050)
mont_inpu = easygui.integerbox(msg='请输入月份', lowerbound=1, upperbound=12)
list_time_quan = ['当前年月', '指定年月','指定年份','指定区间'] #time quantum时间段
#time_quan = list_time_quan[1]
time_quan = list_time_quan[2]
if time_quan == '当前年月':
time_quan_tabl = str(year)+'年'+str(this_mont)+'月科目余额表' #time quantum时间段 table 科目余额表名称。
elif time_quan == '指定年月':
#time_quan_tabl = str(year_inpu)+'年'+str(mont_inpu)+'月科目余额表'
time_quan_tabl =str(mont_inpu) + '月科目余额表'
elif time_quan == '指定年份':
time_quan_tabl = '当年科目余额表'
elif time_quan == '指定区间':
time_quan_tabl = '指定区间科目余额表'
def creat_file(year_input):
print('开始运行创建文件夹自定义函数……')
with open('**电脑端账套号生成村委会文件夹用.txt', 'r') as f:
dic = []
for line in f.readlines():
line = line.strip('\n') # 去掉换行符\n
b = line.split('\t') # 将每一行以空格为分隔符转换成列表
#print(list(b))
dic.append(b)
#print(dic)
admin_villi_dict=dict(dic)
#print('账套所在的村委会文件夹列表是:')
print(admin_villi_dict)#列表转字典
if not os.path.exists('D:\**会计系统导出数据'):
os.mkdir('D:\**会计系统导出数据')
admin_villi_list=['前锋', '西海', '八家', '冲洋', '新围', '竹洛', '竹湖', '新屋', '达材', '朝中', '官窦', '伞塘', '白岗', '稔坪', '西坑', '三和', '居委']
year = time.strftime("%Y")
#print("当前年份是:", year)
if year_input==year:#等于
time1 = time.strftime("%Y%m%d", time.localtime()) # 加上秒不会出现同名
else:
time1= year_input #赋值
#print('创建第3层文件夹folder3_1')
folder3_1 = r"D:\**会计系统导出数据" + '\\' + time1 +'' + time_quan_tabl
#print('判断文件夹是否存在,不存在则创建,文件保存在:'+folder3_1)
if not os.path.exists(folder3_1):
os.mkdir(folder3_1)
#print('创建第4层文件夹folder4_i')
for i in range(0,16):
folder_admin_villi=time1+admin_villi_list[i]+time_quan_tabl
folder4_i=r'D:\**会计系统导出数据'+'\\'+ time1 + time_quan_tabl+'\\' +folder_admin_villi
if not os.path.exists(folder4_i):
os.mkdir(folder4_i)
#print('创建文件夹:'+folder4_i)
return admin_villi_dict,folder3_1
def check_file(folder3_1):
# 打开文件
path= folder3_1
dirs = os.listdir(path)
year = time.strftime("%Y")
file_accnt_num_list=[]
for home, dirs, files in os.walk(path):
for file_name in files:
#filelist.append(os.path.join(home, file_name))
if os.path.splitext(file_name)[1] == '.xls':
#print(file_name)
file_year = file_name[0:4] # 截取文件名前4个字符
#print(file_year)
# os.rename(file, new) # 进行重命名
if file_year == year:
# 取整方法是可以去除0,但是遇到字符串不能转化为整型会报错
# file_accnt_num=int(file_name[9:12])
s = file_name[9:12]
file_accnt_num = "".join(s[::1]).lstrip("0")
#print(file_accnt_num)
else:
s = file_name[5:8]
file_accnt_num = "".join(s[::1]).lstrip("0")
#print(file_accnt_num)
file_accnt_num_list.append((file_accnt_num))
#print(filelist)
#print(file_accnt_num_list)
#print('对列表进行排序,查找时可能减少遍历次数。也便于根据账套号顺序查找')
#file_accnt_num_list2=file_accnt_num_list.sort()
#print('sort影响列表本身,sorted不影响列表本身,用sort排序')
file_exist_list = sorted(file_accnt_num_list)
#print('已导出的文件列表','file_exist_list:')
print(file_exist_list)
print('已导出的文件数量',len(file_exist_list))
return file_exist_list
def accnt_login(account_Num):
wc1 = uiautomation.WindowControl(searchDepth=1, Name='帐套登陆')
# 设置为顶层
#pyautogui.alert(text="按回车键继续程序", title="提示") # 窗口前置才能用键盘快捷键
wc1.SetTopmost(True) # 置顶能用快捷键
pc2_1= wc1.PaneControl(searchDepth=1, Name='帐套信息')
ec3_8=pc2_1.EditControl(searchDepth=1, Name='', foundIndex=2)
ec3_8.SetFocus()
#print('ec3_8')
#print('账套号输入框的位置是:')
#print(ec3_8.BoundingRectangle)
pyperclip.copy(account_Num) #account_Num是账套号
pyautogui.hotkey('ctrl', 'v') # 再粘贴
pyautogui.press('enter')
def user_login():
wc1=uiautomation.WindowControl(searchDepth=1, Name='用户注册')
# 设置为顶层
wc1.SetTopmost(True) # 置顶能用快捷键
pyautogui.press('down') # 向下选择超级用户
pyautogui.press('enter') # 点击确定
pyautogui.press('enter') # 点击确定
#print('超级用户登录成功')
def select_year(screenWidth, screenHeight, year_input):
#print('选择年份')
#print('深度1')
wc1 = uiautomation.WindowControl(searchDepth=1, Name='**经营管理系统V2007 - [科目余额表]')
# 设置为顶层
#wc1.SetTopmost(True)
#print(wc1.Name)
#print('深度2') #isum自创字母后的数字表示深度
#sbc2_1= wc1.StatusBarControl(searchDepth=1, ClassName= 'TStatusBar')
pc2_2= wc1.PaneControl(searchDepth=1,ClassName='MDIClient')
#print(pc2_2.Name)#工作区
#print('深度3')
wc3_1= pc2_2.WindowControl(searchDepth=1,Name='科目余额表')
#print(wc3_1.Name) # 工作区
#print('深度4')
pc4_2= wc3_1.PaneControl(searchDepth=1, ClassName='TPanel',Name= '')
#print(pc4_2.BoundingRectangle) #Rect: (0,183,311,1013)[311x830]
#print('深度5')
#Rect: (1,214,310,442)[309x228]
pc5_2 = pc4_2.PaneControl(searchDepth=1, ClassName='TPanel',Name= '',foundIndex=2)
#print(pc5_2.BoundingRectangle)
#print('深度6')
rbc6_12b = pc5_2.RadioButtonControl(searchDepth=1, Name='指定区间')
rbc6_13b= pc5_2.RadioButtonControl(searchDepth=1, Name='当前年月')
rbc6_14b = pc5_2.RadioButtonControl(searchDepth=1, Name='指定年份')
rbc6_18b = pc5_2.RadioButtonControl(searchDepth=1, Name='指定年月')
#print('点击:'+rbc6_14.Name)
#year = time.strftime("%Y")
#print("当前年份是:", year)
if time_quan == '指定年月':
rbc6_18b.Click()
print(year_input, year)
if year_input!=year:
print('走了这条路')
pyautogui.press('tab')
pyperclip.copy(year_input)
pyautogui.hotkey('ctrl', 'v')
cbc6_21b =pc5_2.ComboBoxControl(searchDepth=1, ClassName = 'TComboBox', foundIndex=3)
mont_show = cbc6_21b.GetValuePattern().Value # month show会计系统4
# 显示月份
# print(mont_show)
pyautogui.press('tab')
for c in range(len(mont_list)):
if mont_show == mont_list[c]: # 一月对应的c是0
# print('c+1')
# print(c+1)
print(mont_list[c])
if mont_inpu > c + 1:
for t in range(abs(mont_inpu - (c + 1))):
pyautogui.press('down')
else:
for t in range(abs(mont_inpu - (c + 1))):
pyautogui.press('up')
# if mont_inpu != this_mont:
# print('按tab键切换到月份下拉菜单,按向下按钮,一直到十二月')
# pyautogui.press('tab')
# for i in range(0,12):
# pyautogui.press('down')
# for i in range(0, abs(mont_inpu- this_mont)):
# pyautogui.press('up')
if time_quan == '指定年份':
rbc6_14b.Click()
if year_input!=year:
pyautogui.press('tab')
pyperclip.copy(year_input)
pyautogui.hotkey('ctrl', 'v')
# print('按tab键切换到月份下拉菜单,按向下按钮,一直到十二月')
# pyautogui.press('tab')
# for i in range(0,12):
# pyautogui.press('down')
# if mont_inpu != this_mont:
# print('按tab键切换到月份下拉菜单,按向下或向上按钮,一直到十二月或一月')
# pyautogui.press('tab')
# if mont_inpu > 6 and this_mont > 6:
# for i in range(0, 6):
# pyautogui.press('down')
# time.sleep(1)
# for i in range(0, 12 - mont_inpu):
# pyautogui.press('up')
# elif mont_inpu <= 6 and this_mont <= 6 and this_mont != 1: # 1月份显示12月份数已经入账。所以this_mont 大于6
# for i in range(0, 6):
# pyautogui.press('up')
# time.sleep(1)
# for i in range(0, mont_inpu - 1):
# pyautogui.press('down')
# else:
# for i in range(0, 12):
# pyautogui.press('up')
# time.sleep(1)
# for i in range(0, mont_inpu - 1):
# pyautogui.press('down')
cbc6_21=pc5_2.ComboBoxControl(searchDepth=1,ClassName='TComboBox',foundIndex=4 ) #排除零项
#print(cbc6_21)
tc7_1=cbc6_21.TextControl(searchDepth=1,Name='',)
tc7_1.SetFocus()
pyautogui.press('down')
time.sleep(1)
pyautogui.click(screenWidth/25.6 , screenHeight/18 ) #点击(75,60 )刷新
# #代替三方鼠标定位软件
# x1,y1,x2,y2=700,27,788,51 #另选账套位置
# x1,y1,x2,y2=316,184,1919,986 #科目余额表显示的范围
# x1,y1,x2,y2=259,560,1607,700#空白的区域
# x1,y1,x2,y2=315,183,1920,1013
# # pyautogui.moveTo(x1,y1,duration=2)
# # pyautogui.moveTo(x2,y1,duration=2)
# # pyautogui.moveTo(x2,y2,duration=2)
# # pyautogui.moveTo(x1,y2,duration=2)
# # pyautogui.moveTo(x1,y1,duration=2)
#
#
def to_excel(screenWidth, screenHeight, year_input, accnt_Num_name, i,admin_villi_dict):
wc1 = uiautomation.WindowControl(searchDepth=1, Name='**经营管理系统V2007 - [科目余额表]')
pyautogui.click(screenWidth / 7.1111, screenHeight /15.4286) # 系统小等字体点击导出(270,70)
time.sleep(0.5)
# pyautogui.click(590,80) #点击导出
# time.sleep(1)
pyautogui.press('down') #按向下键,选择导出Excel表格
time.sleep(0.5)
pyautogui.press('enter') # 点击确定
pyautogui.keyDown('backspace')#长摁删除键
time.sleep(0.5)
pyautogui.keyUp('backspace')
#time1 =time.strftime("%Y%m%d%H%M%S", time.localtime())#加上秒不会出现同名
year = time.strftime("%Y")
#print("当前年份是:", year)
if year_input==year:#等于
time1 = time.strftime("%Y%m%d", time.localtime()) # 加上秒不会出现同名
else:
time1= year_input #赋值
#file_path= r"D:\**会计系统导出数据"+'\\'+time1+'现金三栏明细账'+'\\'+file_name+'.xls'
#字典必须传入字符串,admin_villi_dict[str(i)]
file_path = r"D:\**会计系统导出数据" + '\\' + time1 + time_quan_tabl+ '\\' +time1+admin_villi_dict[str(i)]+time_quan_tabl
if not os.path.exists(file_path):
#print('如果没有预先归类到行政村文件夹,就放在上一级文件夹')
file_path = r"D:\**会计系统导出数据" + '\\' + time1 + time_quan_tabl
# print('判断文件夹是否存在,不存在则创建,文件保存在:'+file_path)
# if not os.path.exists(file_path):
# os.mkdir(file_path)
file_name = time1 + " " + accnt_Num_name + time_quan_tabl
file_title = time_quan_tabl+"(" + accnt_Num_name + ")"
print('文件保存路径是:'+file_path)
file_full_path = file_path + '\\' + file_name + '.xls'
print("文件名是:",end="")
print(file_name)
#pyautogui.typewrite(file_name) #不能写入中文
pyperclip.copy(file_full_path) # 写入文件名
pyautogui.hotkey('ctrl', 'v') # 再粘贴
pyautogui.press('enter') # 点击确定
wc1.Minimize() # 最小化缩小窗口
print('导出Excel表会自动打开,所以需要等待较长时间。')
time.sleep(22)#等待自动打开Excel,必须足够长时间,不然会出现文件名出现不了
pyautogui.click(screenWidth / 3.2, screenHeight / 4.6957) # 点击标题,使得WPS前置。(600,230),Excel的显示方式必须是全屏
pyautogui.typewrite(" ")
pyautogui.press('backspace')
#yautogui.press('insert') #
#print('修改表格标题:'+file_title)
pyperclip.copy(file_title) # 写入表格标题
pyautogui.hotkey('ctrl', 'v') # 再粘贴
time.sleep(0.5)
pyautogui.hotkey('alt', 'f4') # 关闭Excel
time.sleep(0.5)
pyautogui.press('enter') # 点击确定,保存更改
time.sleep(1)
wc1.Restore() # 将窗口回复到最大化
return file_full_path
#这里需要加一个,假如保存文件失败之后,**系统错误提示
#标题是错误,内容是路径不存在或者文件不可写! 确定。
#pyautogui.press('enter')
def chage_accnt():
#print('深度1')
wc1 = uiautomation.WindowControl(searchDepth=1, Name='**经营管理系统V2007 - [科目余额表]')
# 设置为顶层
#wc1.SetTopmost(True)
#print(wc1.Name)
#print('深度2') #isum自创字母后的数字表示深度
#sbc2_1= wc1.StatusBarControl(searchDepth=1, ClassName= 'TStatusBar')
pc2_2= wc1.PaneControl(searchDepth=1,ClassName='MDIClient')
#print(pc2_2.Name)#工作区
mbc2=wc1.MenuBarControl(searchDepth=1, Name= '应用程序')
#print('mbc2')
#print(mbc2.Name)
mic3_9=mbc2.MenuItemControl(searchDepth=1, Name='', foundIndex=9)
#print('mic3_9')
#print(mic3_9.BoundingRectangle)#(700,27,788,51)[88x24]
#print('点击另选账套')
mic3_9.Click()
#另选账套的坐标:Rect: (700,27,788,51)
#这四个 参数 分别代表的意思是: left top right bottom 是 左 上 右 下。
def open_fold():
# #open folder,打开文件夹,用win+E快捷键
pyautogui.hotkey('win', 'e')
pyautogui.press('tab')
#pyautogui.press('insert')
pyautogui.press('enter')
pyperclip.copy('D:\**会计系统导出数据')
pyautogui.hotkey('ctrl', 'v')
pyautogui.press('enter')
def func(year_input):
#print('当前屏幕分辨率宽 X 高:')
screenWidth, screenHeight = pyautogui.size()
#print(screenWidth, screenHeight) # 屏幕分辨率1920 1080,导出的按钮595,80
msg = '浏览需要导出的村委会Excel表格文件并打开'
title = '打开文件'
filePath = easygui.fileopenbox(msg, title)
#print(filePath)
df = pandas.read_excel(filePath)
#df=pandas.read_excel('**电脑端账套号 导出科目余额表用.xlsx')
#df = pd.read_excel(src_file, header=1, usecols='B:F')
#header参数为一个整数,从0开始索引,其为选择的行,比如1表示Excel中的第2行。
#usecols参数设定选择的Excel列范围范围(A-…),例如,B:F表示读取B到F列。
accnt_dict=dict(zip(df['账套号'],df['账套号加单位简称']))
print('获取字典的键,要转化为列表。第一个键是:',end='')
account_Num= list(accnt_dict)[0]
print(account_Num)
year = time.strftime("%Y")
#print("当前年份是:", year)
#year_input = pyautogui.prompt('请输入账套查询的年份:')
#print('弹窗输入年份:' + year_input)
#print('不要把创建文件夹自定义函数放在循环内,先创建文件夹……')
admin_villi_dict,folder3_1 = creat_file(year_input)
#print('遍历3级文件夹下所有文件,检查表格上账套号对应的Excel表是否已导出')
file_exist_list=check_file(folder3_1)
print('Excel文件上要导出的文件数量及文件列表是:','list_accnt_dict(要先将字典的键转化为字符串格式,两个列表的元素都是字符串才能做减法)')
list_accnt_dict= [str(t) for t in list(accnt_dict)]
print(len(list_accnt_dict),list_accnt_dict)
print('已导出的数量及文件列表', 'file_exist_list:')
print(len(file_exist_list),file_exist_list)
#print('删除两个列表重复值,一个列表减去另一个列表,用set(集合)操作')
accnt_list2=list(set(list_accnt_dict)-set(file_exist_list))
#方法2
# accnt_list2=list(set(list_accnt_dict))
# list(set(file_exist_list))
# for n in (list_accnt_dict):
# for m in (file_exist_list):
# if n==m:
# accnt_list2.remove(m)
print(accnt_list2)
print('sort影响列表本身,sorted不影响列表本身,用sort排序')
accnt_list2 = sorted(accnt_list2)
print('未导出的文件数量及文件列表是:')
print(len(accnt_list2),accnt_list2)
file_numb = 0
for i in accnt_list2:
#print('i在之前转化为字符串,要重新转化为数值格式')
i=int(i)
#print('直接用遍历字典的键值循环,i就是账套号')
accnt_Num_name=accnt_dict[i]
print('账套号是:' + str(i)+',账套名称是:'+accnt_Num_name)
time.sleep(1)
#账套号登录自定义函数
accnt_login(i)
time.sleep(1)
#用户登录自定义函数
user_login()
time.sleep(1)#第二次循环时,科目余额点击
# 选项出现较慢,需要等待
#print('点击科目余额表')
pyautogui.click(screenWidth /2.7826, screenHeight / 1.125) # 系统小字体显示,点击科目余额表(690,960)
time.sleep(1)
select_year(screenWidth, screenHeight,year_input)
#print('等待2秒,数据生成需要时间')
time.sleep(3)
print('导出Excel表涉及到创建文件夹,创建文件,需要输入屏幕长宽、年份、账套号、账套名称、账套所在村委会字典')
file_full_path= to_excel(screenWidth, screenHeight, year_input, accnt_Num_name, i,admin_villi_dict)
time.sleep(3)
#print('系统中等字体显示点击另选账套')
pyautogui.click(722,37) #另选账套
#account_Num+=1
#print('系统小字体显示点击另选账套坐标135,36')
pyautogui.click(screenWidth/3.2,screenHeight/30) #另选账套
time.sleep(3)#另选账套必须足够长时间,因为窗口切换幅度大
file_numb+=1
print('导出第{}个文件'.format(file_numb))
#pyautogui.alert(text=r"文件保存在D:\**会计系统导出数据", title="提示") #
if __name__ == "__main__":
#creat_file('2019')
print('桌面不能打开其他程序,程序在左下角运行。程序运行时不能操作鼠标和键盘,不能打开word和WPS。文件保存在D:\**会计系统导出数据.')
#pyautogui.alert(text="桌面不能打开其他程序,程序在左下角运行。程序运行时不能操作鼠标和键盘。文件保存在D:\**会计系统导出数据",title="提示")
# time.sleep(1)
#time.sleep(20)
#打开程序
proc_list = ['D:\**经营管理系统2007版\BJACCOUNT.EXE', 'E:\**经营管理系统2007版\BJACCOUNT.EXE', 'C:\**经营管理系统2007版\BJACCOUNT.EXE',
'F:\**经营管理系统2007版\BJACCOUNT.EXE', 'G:\**经营管理系统2007版\BJACCOUNT.EXE','H:\**经营管理系统2007版\BJACCOUNT.EXE',
'I:\**经营管理系统2007版\BJACCOUNT.EXE', 'J:\**经营管理系统2007版\BJACCOUNT.EXE', 'K:\**经营管理系统2007版\BJACCOUNT.EXE',
'D:\Program Files\**经营管理系统2007版\BJACCOUNT.EXE', 'E:\Program Files\**经营管理系统2007版\BJACCOUNT.EXE',
'C:\Program Files\**经营管理系统2007版\BJACCOUNT.EXE', 'F:\Program Files\**经营管理系统2007版\BJACCOUNT.EXE',
'G:\Program Files\**经营管理系统2007版\BJACCOUNT.EXE', 'H:\Program Files\**经营管理系统2007版\BJACCOUNT.EXE',
'I:\Program Files\**经营管理系统2007版\BJACCOUNT.EXE', 'J:\Program Files\**经营管理系统2007版\BJACCOUNT.EXE',
'K:\Program Files\**经营管理系统2007版\BJACCOUNT.EXE',
'D:\Program Files (x86)\**经营管理系统2007版\BJACCOUNT.EXE', 'E:\Program Files (x86)\**经营管理系统2007版\BJACCOUNT.EXE',
'C:\Program Files (x86)\**经营管理系统2007版\BJACCOUNT.EXE', 'F:\Program Files (x86)\**经营管理系统2007版\BJACCOUNT.EXE',
'G:\Program Files (x86)\**经营管理系统2007版\BJACCOUNT.EXE', 'H:\Program Files (x86)\**经营管理系统2007版\BJACCOUNT.EXE',
'I:\Program Files (x86)\**经营管理系统2007版\BJACCOUNT.EXE', 'J:\Program Files (x86)\**经营管理系统2007版\BJACCOUNT.EXE',
'K:\Program Files (x86)\**经营管理系统2007版\BJACCOUNT.EXE',
]
for i in range(len(proc_list)):
try:
subprocess.Popen(proc_list[i])
#print('程序在:{}'.format(proc_list[i]))
break
except:
#print('程序不在:{}'.format(proc_list[i]))
pass
time.sleep(2)
wc = uiautomation.WindowControl(searchDepth=1, Name='帐套登陆')
# 设置为顶层
#pyautogui.alert(text="按回车键继续程序", title="提示") # 窗口前置才能用键盘快捷键
#print('窗口前置才能用键盘快捷键')
wc.SetTopmost(True) # 置顶能用快捷键
# accnt_Num_txt = wc.EditControl()
# print('accnt_Num_txt',accnt_Num_txt)
year_input = str(year_inpu)
print(year_input)
func(year_input)
# for year_input in range(2021, 2020, -1):
# year_input=str(year_input)
# print(year_input)
# func(year_input)
open_fold()