做办公自动化的小伙伴都知道,驱动SAP GUI我们有SAP原生提供的【脚本录制与回放】以及SAP Scripting API可参考;驱动Office Excel等,我们有微软提供的【录制宏】功能;驱动各类浏览器我们有selenium和Katalon Recorder。这些工具都可以提供简易的代码录制功能,稍微有点编程基础的小伙伴可以基于录制后自动生成的代码,整合上业务逻辑,稍加调整,就可以轻松完成一个自动化脚本的开发。

  可桌面软件远不止这几大类啊,更不是每个公司都舍得花钱买SAP的ERP产品,比如今天的国产ERP巨头金蝶公司的K3 Wise客户端,我们是否也有类似的办法来自动化呢?小爬这里给出的答案是:可以,但是没有官方提供的【动作录制】功能快速生成脚本,这次真的只能徒手写代码了,除了微软大大提供的Windows系统 API,似乎我们什么都依靠不了。小爬今天就带大家层层分解,用python脚本一步步搞定金蝶K3的UI自动化。

  • 自动化启动K3 Wise软件

  我们需要判断金蝶K3 Wise是否已经启动,如果没有,则自动化启动它,我们再次请出我们的好帮手SPY++和了不起的Pywin32库。通过SPY++的元素捕获功能拿到K3登录界面的窗口标题(caption)和类名(Class),再用FindWindow函数来捕获即可,最后再决定是否用subprocess库来启动对应的K3 exe文件,这一步的示例代码如下:

 1 # 需要提前使用管理员权限运行VScode或者Pycharm,否则无法正常使用
2 import win32gui,win32api,win32con,subprocess,time,os
3 def getK3LoginHwnd():
4 sysLoginWnd=win32gui.FindWindow('ThunderRT6Form',"金蝶K/3系统登录") # K3系统登录窗
5 if sysLoginWnd==0:
6 subprocess.Popen(r'C:\Program Files (x86)\Kingdee\K3ERP\K3MainNet.exe')
7
8 # subprocess发送指令启动后需要等K3登录窗彻底可见后,再进行后续操作
9 while sysLoginWnd==0:
10 time.sleep(0.3)
11 sysLoginWnd=win32gui.FindWindow('ThunderRT6Form',"金蝶K/3系统登录") # K3系统登录窗
12 isSysLoginWndVisible=0
13 while isSysLoginWndVisible==0:
14 time.sleep(0.3)
15 sysLoginWnd=win32gui.FindWindow('ThunderRT6Form',"金蝶K/3系统登录") # K3系统登录窗
16 isSysLoginWndVisible=win32gui.IsWindowVisible(sysLoginWnd) # 判断窗口是否已经对用户可见
17 return sysLoginWnd

需要注意的是,我们需要使用管理员权限打开VScode或者Pycharm后再调试脚本,否则windows提示【请求的操作需要提升】,如下图所示。

  • 驱动K3登录窗,成功登录特定账套

1、设置【组织机构】下拉框

  大胆猜测,上图中组织机构下拉框ThunderRT6ComboBox是ComboBox的子类,继承了它的很多特性。比如我们希望选择组织机构【01|查询帐套】,它在combobox列表中索引为1。我们先判断当前值是否是我们要的,否则就选择某个下拉选项。示例代码如下:

1 def setOrganization(sysLoginWnd,organizationIndex):
2 '''根据K3登录窗的句柄和下拉框索引值,选择特定的组织机构'''
3 mainHwnd1=win32gui.FindWindowEx(sysLoginWnd,0,None, '') # ThunderRT6PictureBoxDC
4 mainHwnd2=win32gui.FindWindowEx(sysLoginWnd,mainHwnd1,None, '') # ThunderRT6PictureBoxDC
5 organizationHwnd=win32gui.FindWindowEx(mainHwnd2,0,"ThunderRT6ComboBox", '') # 组织机构
6 currentOrgIndex=win32gui.SendMessage(organizationHwnd, win32con.CB_GETCURSEL) # 当前combobox选中的index
7 if currentOrgIndex!=organizationIndex:
8 win32gui.SendMessage(organizationHwnd, win32con.CB_SETCURSEL, organizationIndex, 0)

  划重点了,K3登录窗中,【组织机构】和【当前帐套】是二级联动的下拉菜单,而我们上面定义的setOrganization方法一通操作后,只更改了【组织机构】,却无法使得【当前帐套】产生联动,应该是后台的消息机制没能推送给程序,导致无法自动联动,实在是空欢喜。莫慌,小爬这里有锦囊妙计:利用python脚本设置好了【组织机构】下拉框后,再激活【组织机构】下拉框,使其处于蓝底,这个时候模拟键盘↓和键盘↑,来激活【当前帐套】的二级联动效果。对了,这里还需要注意一个坑:临界问题,比如下拉框选中的是最后一项,此时应该模拟的是键盘↑+键盘↓,思路理清后,果断完善上面的setOrganization方法,代码如下:

 1 def setOrganization(sysLoginWnd,organizationIndex):
2 '''根据K3登录窗的句柄sysLoginWnd和下拉框索引值organizationIndex,选择特定的组织机构'''
3 mainHwnd1=win32gui.FindWindowEx(sysLoginWnd,0,None, '') # ThunderRT6PictureBoxDC
4 mainHwnd2=win32gui.FindWindowEx(sysLoginWnd,mainHwnd1,None, '') # ThunderRT6PictureBoxDC
5 organizationHwnd=win32gui.FindWindowEx(mainHwnd2,0,"ThunderRT6ComboBox", '') # 组织机构
6 currentOrgIndex=win32gui.SendMessage(organizationHwnd, win32con.CB_GETCURSEL) # 当前combobox选中的index
7 if currentOrgIndex!=organizationIndex:
8 win32gui.SendMessage(organizationHwnd, win32con.CB_SETCURSEL, organizationIndex, 0)
9
10 '''模拟鼠标左键点击元素,激活它'''
11 win32gui.SendMessage(organizationHwnd, win32con.WM_LBUTTONDOWN, 0, 0)
12 time.sleep(0.01)
13 win32gui.SendMessage(organizationHwnd, win32con.WM_LBUTTONUP, 0, 0)
14
15 '''小爬此处的场景中,【组织机构】有6个下拉项,那么最大的index就是5'''
16 if organizationIndex<5: # 模拟键盘↓+键盘↑
17 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYDOWN, win32con.VK_DOWN, 0)
18 time.sleep(0.01)
19 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYUP, win32con.VK_DOWN, 0)
20 time.sleep(0.1)
21 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYDOWN, win32con.VK_UP, 0)
22 time.sleep(0.01)
23 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYUP, win32con.VK_UP, 0)
24 else: # 模拟键盘↑+键盘↓
25 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYDOWN, win32con.VK_UP, 0)
26 time.sleep(0.01)
27 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYUP, win32con.VK_UP, 0)
28 time.sleep(0.1)
29 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYDOWN, win32con.VK_DOWN, 0)
30 time.sleep(0.01)
31 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYUP, win32con.VK_DOWN, 0)
32 time.sleep(0.1)

  今天的分享就到这里了,后续小爬会教大家如何驱动剩下的K3登录界面控件,实现自动登录账套,自动切换账套,玩转金蝶K3的UI自动化。

欢迎扫码关注我的公众号 获取更多爬虫、数据分析的知识!

python办公自动化系列之金蝶K3自动登录(一)的更多相关文章

  1. python办公自动化系列之金蝶K3自动登录(二)

    接上一篇博文python办公自动化系列之金蝶K3自动登录(一),我们接着聊聊利用python脚本实现金蝶K3 Wise客户端自动登录这一需求. 如上图所示,自动选择[组织机构]后,我们还需要驱动[当前 ...

  2. python办公自动化系列之金蝶K3(三)

    小爬在之前的两篇文章 [python办公自动化系列之金蝶K3自动登录(一)].[python办公自动化系列之金蝶K3自动登录(二)]带大家系统搞定了K3客户端的自动登录难题,但是搞定[自动登录]只是我 ...

  3. python网络爬虫之使用scrapy自动登录网站

    前面曾经介绍过requests实现自动登录的方法.这里介绍下使用scrapy如何实现自动登录.还是以csdn网站为例. Scrapy使用FormRequest来登录并递交数据给服务器.只是带有额外的f ...

  4. python带cookie提交表单自动登录(转)

    今天突然把博客给申请了,以前也想过的,奈于自己觉得水平还太低有点不好意思写博客,但是后来一想,自己的记录所学,加深印象,主要还是为了学习进步,不怕丢人!今天就稍微回顾一下这两天写的一段用python模 ...

  5. 使用Python定时执行一任务,自动登录某web系统,生成报表,然后发送邮件给指定人员

    一.项目需求 每周从A系统生成一张Excel报表,发送此报表给指定人员,相关人员依据此报表去完成后续的工作. 项目限制: 1.无法通过EDI系统交互的方式从后台读取数据 2.由于公司网络环境限制,不能 ...

  6. python带cookie提交表单自动登录

    import urllib import urllib2 import cookielib login_url = "xxxxxxxxxxxxx" cj = cookielib.C ...

  7. [Python爬虫] Selenium实现自动登录163邮箱和Locating Elements介绍

    前三篇文章介绍了安装过程和通过Selenium实现访问Firefox浏览器并自动搜索"Eastmount"关键字及截图的功能.而这篇文章主要简单介绍如何实现自动登录163邮箱,同时 ...

  8. Python实现BBS自动登录并发帖

    初学Python有了一段时间,寒假里又看了一些Web编程方面的知识,就写了一个实现bbs自动登录和发帖的Python脚本 由于本人学校BBS站首页使用js加载,貌似通过首页登录不大可行,然后就分析表单 ...

  9. 金蝶K3 WISE 快速登录

    金蝶K3 WISE 快速登录 "C:\Program Files (x86)\Kingdee\K3ERP\k3main.exe" -LoginUser|账套号|账套密码|用户账号| ...

随机推荐

  1. HDC2021技术分论坛:“积木拼装”,HarmonyOS弹性部署大揭秘!

    作者:peitaiyi,华为终端OS产品交付专家 HarmonyOS是一款面向万物互联时代的.全新的分布式操作系统.在传统的单设备系统能力基础上,HarmonyOS提出了基于同一套系统能力.适配多种终 ...

  2. anaconda 安装 gdown

    pip install gdown注意不要使用conda install gdown 这样会报错参考:gdown · PyPI

  3. 来自Java程序员的Python新手入门小结

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. MySQL 尽量避免使用 TIMESTAMP

    MySQL 中常见的时间类型有三种DATE, DATETIME和 TIMESTAMP,其中DATE类型用于表示日期,但是不会包含时间,格式为YYYY-MM-DD,而DATETIME和TIMESTAMP ...

  5. [C++]高效C/C ++编程tips

    Effective C++ 视C++ 为一个语言联邦(C.Object-Oriented C++.Template C++.STL) 宁可以编译器替换预处理器(尽量以const.enum.inline ...

  6. 图像处理opencv-Rect 排序、合并[转]

    opencv进行rect检测时,当检测到多个rect,组成rect vector之后,有些rect是由一个区域误分割得到的, 可以按照某种规格将这些rect合并为一个rect.比如按照x,y,widt ...

  7. Java程序设计基础笔记 • 【第2章 变量与数据类型】

    全部章节   >>>> 本章目录 2.1 变量 2.1.1 变量的概念 2.1.2 变量的使用 2.1.3 实践练习 2.2 数据类型 2.2.1 数据类型的种类 2.2.2 ...

  8. 使用JavaScript 中的Math对象和勾股定理公式,计算鼠标的位置与页面图片中心点的距离,根据距离对页面上的图片进行放大或缩小处理。距离远时图片放大,距离近时图片缩小

    查看本章节 查看作业目录 需求说明: 使用JavaScript 中的Math对象和勾股定理公式,计算鼠标的位置与页面图片中心点的距离,根据距离对页面上的图片进行放大或缩小处理.距离远时图片放大,距离近 ...

  9. Kafka基础教程(四):.net core集成使用Kafka消息队列

    .net core使用Kafka可以像上一篇介绍的封装那样使用(Kafka基础教程(三):C#使用Kafka消息队列),但是我还是觉得再做一层封装比较好,同时还能使用它做一个日志收集的功能. 因为代码 ...

  10. .NET 微服务——CI/CD(3):镜像自动分发

    如何通过Jenkins完成镜像分发?基本做法是:打包镜像→上传镜像到仓库→脚本分发.镜像仓库也有很多,比如docker hub.Harbor等,今天这一篇讲一下基于阿里云镜像仓库的操作. 首先,准备一 ...