多种窗口都可能被激活的情况下判断其中某个是否激活
遇到的问题
今天测试 SAP 系统流程的时候突然出现了问题导致无法继续,问题是这样的:在 SAP 查询出结果后需要点击导出为电子表格,点击以后过几分钟会弹出这样的窗口:
然后我只需要检测 “另存为” 窗口是否激活,输入文件名点击保存就行了,结果今天点击导出变成了这样:
是的,变成了另一个窗体,RPA 一直检测不到名字为 “另存为” 的窗口,所以一直在继续检测。
我怀疑是自己的操作出了问题,然后退出重新尝试了一下,结果第一次第二次出来的是 “另存为” 窗口,第三次就变成了 “客户行项目显示” 窗口了,似乎是完全随机的,跟操作没有关系。我的内心是崩溃的,想了一下如果不是配置问题应该只能检测这两种窗口是否有一个被激活了。
解决办法(斜体部分为缺陷上报和优化建议)
首先想到的是在第一个判断结果为假时连上第二个判断
这种想法很快被否定了,由于不知道窗口多久才会弹出,第一个是否激活窗口设置的等待时间比较长,如果弹出的是第二个窗口,只有在第一个等待时间完全走完以后才会执行第二个判断,所以把两个窗口放在一起判断比较好,看来只能自己写函数了。
下面给出操作步骤:
1. 打开艺赛旗自带的 iwin.py 文件,目录为 C:\is-RPA\plugin\Com.Isearch.Func.Python\Lib\ubpa\iwin.py,可以看到里面定义了一个 do_win_is_active()函数,用来判断某个窗口是否激活,那么我们可以自己写一个 do_wins_is_active() 函数,用来判断两个中的一个窗口是否激活 (当然也可以传入可变参数来达到对更多种窗口进行判断的效果,这里为了节省时间就只判断两个),代码如下:
'''
检查指定两个窗口中的一个是否存在且被激活
win_title :窗口标题
返回: XX已激活:成功 False:失败
'''
def do_wins_is_active(win_title=(), win_text=(), waitfor=WAIT_FOR):
__logger.debug('窗口是否激活')
try:
starttime = time.time()
while True:
rst = dll.AU3_WinActive(win_title[0], win_text[0])
rst2 = dll.AU3_WinActive(win_title[1], win_text[1])
time.sleep(0.1)
if rst == 1:
return win_title[0] + " 已激活"
elif rst2 == 1:
return win_title[1] + " 已激活"
else:
runtime = time.time() - starttime
if runtime >= waitfor:
__logger.debug('窗口未激活')
return False
except Exception as e:
raise e
这里的循环中自己加了个睡眠操作,可以节省一些 cpu 计算资源,建议每个类似这种需要等待很久的控件代码在循环中加入 sleep 语句。否则的话,每秒钟可能就进行了上万次判断:
另外,有些控件设置等待时间没有效果,可能是因为艺赛旗程序员写脚本的时候没在下面红框中加时间判断,需要加一下。
2. 在 iwin.py 中加入上述函数并保存后,就可以在设计器中自己写代码块了
tvar = iwin.do_wins_is_active(win_title=(r'另存为', r'客户行项目显示'),win_text=(r'', r''),waitfor=300)
if tvar == '另存为 已激活':
pass
elif tvar == '客户行项目显示 已激活':
pass
pass 里面写判断到窗体激活后的操作,win_title 那边可以自己根据实际情况进行修改。
不错,这个是个 bug,8.0 修复 👍
啊呀,不是的林总,我这个虽然放在了建议板块,但是只有其中一部分是建议(就是帖子里面字体为斜体的部分)
总共两个建议:
1. 含有 watifor 的控件一般都是用 while True 来循环判断,每一秒都会执行上万次 while 循环,像这种控件可以在每一次循环都 sleep 很短的时间,这样既不影响机器人执行效率,又对那些运行速度卡的电脑比较友好
2. 有些控件就算设置等待时间 waitfor 也没有作用,是因为函数体里面漏加了代码,我目前发现的只有检测窗体是否激活这个 do_win_isactive() 函数,其他也可能有同样的问题,这个需要你们去检查一下
嗯,不错,因为在建议板块,我就考虑了下产品是否需要这样功能,感觉产品不需要的,还是你自己这样灵活处理比较好
我这个问题比较特殊,两种窗口都有可能会跳出来,不确定会跳出哪一个。而且要等很久,每一次时间也不一定,所以 waitfor 只能稍微加高一点,没法先判断其中一个窗口,等 waitfor 时间到了再判断另一个窗口,这样效率很低
我合并只是另外写了一个方法,正常情况下还是调用原来的 do_win_is_active() 函数就行了 😹
这个我觉得不同窗口有不同处理逻辑,所以不好合并,还是需要你自行处理,把 wait 缩短即可