一、簡介
1.什么是RPA?
Robotic Process Automation,中文翻譯為機器人流程自動化,簡稱RPA。
RPA是軟件機器人,用來完成計算機上重復的工作。
2.UiBot是什么?
UiBot是一種RPA平台
3.RPA平台組成部分
1.開發工具:制作、運行、調試軟件機器人
2.運行工具:普通用於運行已有流程,查閱結果。
3.控制中心:對多台PC上的機器人集中控制(分發流程、設定啟動條件等)
Creator把流程先上傳到Commander,再由Commander統一下發給各個Worker,並統一指揮各個Worker執行流程
UiBot的三個組成部分
二、基本概念
流程 > 流程快 > 命令 > 屬性
1.流程:UiBot流程是一連串的執行動作,以流程圖的方式顯示,包含一個文件夾。
2.流程圖:
包含“開始”、“結束”、“流程塊”和“判斷”四種元素,用箭頭連起來。
只能有一個“開始”元素,可以有多個“結束”元素,可以有多個“判斷”元素,至少一個“流程塊”。
一個流程分多個步驟,每個步驟用流程塊來描述(冰箱打開 -> 裝進大象 -> 關上冰箱)。
推薦把邏輯獨立的封裝成一個流程塊,留個流程塊最好不要超過20個,多個溝通起來困難。
3.可視化視圖
命令:把一個步驟具體細化成命令去執行,如:模擬鼠標、鍵盤操作,對窗口、瀏覽器操作等
屬性:細化描述具體的命令
4.源代碼視圖
5.小結
這一章學習了四個概念:流程、流程塊、命令、屬性。還看到了三種視圖:流程圖、可視化視圖、源代碼視圖。它們之間的關系如下圖所示:
流程包含多個流程塊,流程塊包含多個命令,命令包含多個屬性。流程圖是流程的展現,可視化視圖和源代碼視圖都是流程塊的展現。
6.進階:流程圖的輸入和輸出
流程圖中的變量,其作用域也僅限於當前流程中,在流程塊里面是無法直接使用的。
當一個流程塊開始運行的時候,可以把一個值(可以是變量或者表達式)“輸入”到流程塊中;而當一個流程塊運行結束的時候,也可以把一個值“輸出”到流程圖中的某個變量中。還可以在流程圖中加入一個“判斷”,根據某個值,來決定究竟后面要找哪條路徑去運行。
UiBot用到的編程語言是不區分關鍵字、變量名的大小寫的,所以您也可以寫 SELF.INPUT
、self.input
,或者 RETURN <輸出值>
等。
流程圖的屬性欄
如下圖所示,“判斷”元素有兩個出箭頭,一個標有yes,一個標有no,當其屬性中的“條件表達式”為真時,沿着yes箭頭往后運行,否則,沿着no箭頭往后運行。
流程圖輸入和輸出的具體用法:
我們首先選中“流程塊1”,在其“輸出”屬性中,填寫一個變量名,假設是X
;然后選中“流程塊2”,在其“輸入”屬性中,填寫同樣的變量名(不區分大小寫)。這樣,通過變量X
,就把“流程塊1”的輸出和“流程塊2”的輸入連接起來了。如下圖所示。 這個變量X
僅在當前流程圖中有效,其作用僅僅是把兩個流程塊連接起來。在流程塊1和流程塊2中,均無法直接使用X
來設置或者獲取其值。
通過同一個變量,連接流程塊1的輸出和流程塊2的輸入
如何讓流程塊1輸出,又如何讓流程塊2輸入呢?
我們先點擊“紙和筆”圖標進入流程塊1,只需要插入一條“獲取系統時間”和一條“格式化時間”命令(在“時間”分類下),並把“格式化時間”中的“時間”屬性設為“獲取系統時間”的結果,即可得到當前時間,並以容易閱讀的格式保存在變量sRet中。 然后,再插入一條“跳出返回”命令(在“詞法語法”分類下),並把sRet設為返回值,即可讓流程塊1正確輸出。如下圖所示。為了方便讀者理解,圖中同時列出了這個流程塊的可視化視圖和源代碼視圖,讀者可根據掌握程度任選其一。
在流程塊1中輸出當前時間
再點擊“紙和筆”圖標進入流程塊2,只需要插入一條“輸出調試信息”命令,並把“輸出內容”屬性設為Self.Input(不區分大小寫)即可。如下圖所示。同樣,我們也列出了這個流程塊的可視化視圖和源代碼視圖,以方便理解。
在流程塊2中輸出調試信息,信息來自於流程塊1
回到流程圖界面,然后點擊“運行”按鈕,即可看到運行結果。注意,由於流程塊2需要獲得流程塊1的輸出,所以,在流程圖中運行的結果是正確的。雖然流程塊2也可以單獨運行,但在單獨運行時,由於缺乏流程塊1的輸出,結果可能會有不同。
三、界面元素
1.什么是界面元素?
鼠標下面都是一個小的圖形部件,我們把這些圖形部件稱為“界面元素”。
在UiBot中,界面元素的作用,就是作為“有目標”的命令中的目標使用。
2.目標選取
“
點擊目標”命令和“選擇目標”按鈕
用“目標選擇器”選中開始菜單按鈕
“目標”屬性的值
{"wnd":[{"app":"explorer","cls":"Shell_TrayWnd"},{"cls":"Start","title":"開始"}]}
3.目標編輯
目標常見錯誤:
- 無論如何移動鼠標,都無法使遮罩恰好遮住要作為目標的界面元素(通常是遮罩太大,遮住了整個窗口)
- 遮罩可以恰好遮住界面元素,但用生成的數據查找目標時,發生了:
- 錯選:找到界面元素不是我們選的
- 漏選:界面元素存在,卻找不到
修改目標
目標編輯器
0:這是目標的上級界面元素 1:是目標界面元素,程序逐級從上往下查找。
- 不理解的特征名稱,比如
cls、aaname
等,暫時不管它們; - 善用通配符
*
,代表“匹配任意內容”。如界面元素title
特征的值是“姓名:張三”,“張三”可能變,但“姓名:”不變。所以,可以用title: "姓名:*"
來作為特征,而不是把這條特征去掉; - 去掉特征的時候要慎重。去掉特征可以減少漏選,但會增加錯選。流程運行時漏選易發現,錯選不易發現。
大多數的“有目標”命令在找不到目標時會報錯,除非:(1)判斷了目標是否存在 (2)用Try…Catch捕獲異常。
程序錯選的時候,UiBot並不知道,還會繼續往下運行。
提醒:不同操作系統、瀏覽器上,同樣的界面元素特征可能不一樣。
所以,在用UiBot制作流程,並且在別人的計算機上使用的時候,請盡量保持開發環境和生產環境的一致性,以減少不必要的錯誤。
4.進階
遮罩選取目標常見問題:只能遮罩選取整個窗口,不能具體選中目標界面元素。
如何正常選取?
1.Chrome瀏覽器:
Chrome瀏覽器需要安裝擴展程序“UiBot Native Message Plugin”,並啟用。
推薦大家在RPA流程中還是使用原生的Chrome瀏覽器或IE瀏覽器(360安全瀏覽器、QQ瀏覽器等容易出錯)
2.跨域網頁
網頁中通過iframe嵌套了另一個域名下的網頁(不同的二級域名或頂級域名),Chrome瀏覽器處於安全考慮,禁止對引用的網頁訪問,如元素選取,執行JS等,無法自動化操作。(IE可以)
解決辦法:
(1)使用IE瀏覽器
(2)通過啟動參數命令,來關閉Chrome的安全設置
右鍵點擊Google Chrome圖標,選擇 屬性->快捷方式,在“目標”一欄填入啟動參數,具體格式如下:<Chrome安裝路徑> --disable-web-security --user-data-dir=用戶數據目錄
。比如,我們的Chrome安裝在C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
下,用戶數據目錄為D:\temp
,那么套用格式,我們在Chrome目標窗口應填入C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security --user-data-dir=D:\temp
,如下圖:
Chrome關閉安全設置
在目標后添加(雙引號后面): --disable-web-security --user-data-dir=D:\temp
在經過以上操作后,我們再打開Chrome,會看到Chrome地址欄會有如下的提示,並且安裝的擴展程序也消失不見了。不要着急,這是因為Chrome的用戶數據目錄發生了變化,只要重新安裝UiBot的Chrome擴展程序,即可自動化操作。
Chrome關閉安全設置后打開顯示
經過以上設置,Chrome即可支持跨域訪問。
3.SAP客戶端程序
SAP客戶端程序需要在設置中打開腳本支持,才能正常選取。我們以SAP 710客戶端為例:
- 打開SAP客戶端程序,進入登錄主界面;
- 輸入rz11事務碼並進入相應界面;
SAP輸入事務碼
- 在事務界面輸入sapgui/user_scripting,並點擊display;
rz11事務界面
- 查看Current Value當前值選項,如果為TRUE則已經開打選項,不需要做任何改動;如果為FALSE則需要點擊Change Value改變此處為TRUE;
sapgui設置界面
- 點擊設置按鈕,選擇Options項;
SAP客戶端設置選項
- 切換到Scripting選項卡,勾選“Enable Scripting”選項,並取消勾選“Notify When a Script Attaches to Running Man GUI”和“Notify When a Script Opens a Connection”選項。
SAP客戶端Scripting選項卡設置
設置完成后,即可象普通的Windows軟件一樣,用UiBot對SAP客戶端進行界面元素的獲取和操作。除了前文中介紹的“鼠標點擊”、“鍵盤輸入”等操作之外,我們來看一個新的例子,用UiBot自動設置單選框的內容:
在“界面元素”類的命令下,找到“設置元素勾選”命令,拖動插入到組裝區。按下“查找目標”,可以看到UiBot的界面元素選擇遮罩可以准確的遮住SAP客戶端中每個單選框的位置。選中我們關注的單選框,並在命令屬性欄的“是否勾選”選擇“是”即可。如圖所示:
SAP客戶端Scripting選項卡設置
運行此流程,即可看到SAP客戶端的單選框被UiBot自動設置為“Display inbound call”一項。
4.JAVA程序
UiBot支持Swing、AWT、JNPL、Applet等多種Java應用程序。除Swing以外,其他Java程序都需要安裝Java擴展程序。
可以按照如下步驟去安裝Java擴展程序:
-
打開UiBot Creator,隨便選擇一個流程。在菜單中選擇“幫助”->“安裝Java擴展”;
-
安裝成功之后,UiBot Creator將會有對應的安裝成功提示出現。需要注意的是,如果需要操作的Java程序是以管理員權限進行安裝,那么同樣需要以管理員權限啟動UiBot Creator,才能順利安裝Java擴展程序。
安裝后,即可象普通的Windows軟件一樣,用UiBot對Java程序進行界面元素的獲取和操作。
5.進階:網頁目標
網頁目標:百度主頁的二維碼
wnd
信息標明了這個網頁所在的瀏覽器窗口,html
信息才是網頁上的界面元素的關鍵信息。
html
:代表這是一個網頁界面元素;
url
:對應瀏覽器地址欄中顯示的URL,不參與元素特征匹配。僅在“綁定外部瀏覽器”命令中(在“瀏覽器”類命令中可以找到)用到,用於選擇想要綁定的瀏覽器活動標簽頁;title
:與url類似,對應瀏覽器標簽頁的標題,不參與元素特征匹配,也僅在“綁定外部瀏覽器”命令中使用;tagName
:html標簽類型(div、a、input
等);
attrMap
:對界面元素詳細的html描述;
index
:一般起輔助作用,說明在滿足特征條件情況下,元素出現的順序。UiBot的index是從數字1開始的,當index沒有填寫或取0時,則會選擇第一個出現的元素。
實例:獲取產品月銷量
具體步驟:
- 從UiBot Creator的命令區選擇“獲取元素文本”命令,如下圖:
獲取元素文本命令
- 在“獲取元素文本”命令上點擊“查找目標”按鈕,並選擇銷量數字,如Intel i5 8500頁面的“98”,如下圖:
選中需要獲取的文本
- 用“輸出調試信息”命令查看抓取到的值(當然,也可以用於其他用途,如轉換成數字、保存到Excel表格等,本文暫不贅述其他用途),如下圖:
查看抓取的內容
看起來,好像工作得很好,毫無問題的獲得了Intel i5 8500的月銷量:98。但是,如果我們在其他商品上再去運行這個流程(使用Chrome瀏覽器,只需切換頁面的標簽即可,UiBot始終會在激活的標簽工作),就會發現出問題了。
在其他商品上運行流程
可以看到,在等待一定時間之后,UiBot最終因為沒有找到目標而拋出了異常。那么,問題到底出在什么地方?我們應該如何做,才能讓UiBot順利找到目標呢?
點擊“獲取元素文本”命令,查看命令的屬性,並具體打開“目標”屬性進行查看,如下圖:
細心的讀者可能已經發現了:原來"aaname"
這條特征已經被固定在“98”了。這顯然是不合理的:我們本來就是為了獲取銷量,如果把銷量的數值98也加到特征里面,那是毫無意義的!因為銷量一旦發生變化,特征就無法匹配了,造成“漏選”的問題。怎么辦呢?我們可以很自然的想到:取消aaname
特征的勾選狀態,或把aaname
的特征采用"*"
進行通配,即可跳過這條造成“漏選”的特征。如下圖:
修改“aaname”的特征為通配符
請注意,這里不必糾結上面圖片框里顯示的98,那只是一張參考圖,在實際查找目標的時候不會起到任何作用。也不必糾結title
和url
這兩條特征,因為前文已經提到,這兩條特征也不會參與到查找目標的過程中。
修改完成之后,再次運行這個流程塊,看看是否能正確獲取其他商品的月銷量。如下圖:
修改“aaname”特征之后的運行
奇怪的事情發生了,之前的異常確實沒有出現,並且獲取到了內容。但是並不是我們想要的“77”,而是“月銷量”幾個字,這是怎么回事呢?
我們觀察一下頁面上的內容,發現修改“aaname”之后,雖然不會發生“漏選”,但由於文字“月銷量”的特征和“77”完全一致,造成了“錯選”。仔細查看即可發現,“月銷量”文字和“77”的tagName、attrMap
等特征完全一樣,好比是一個戶口本里的同一家人,已經無法區分了。怎么辦呢?可以使用"index"
特征來定位他們的不同。上文提到,UiBot的index
是從數字1開始的,當index沒有填寫或取0時,則匹配第一個。從頁面上看,“月銷量”這個元素在銷量數字的前面,如果它是第一個,那么銷量數字就應該是第二個,因此,我們猜測,當的index
取2的時候,就可以找到銷量數字了。不妨填上試一下。
修改“index”特征的值
現在驗證一下。在UiBot Creator工具欄上,點擊“運行”按鈕,直接運行當前的流程塊。可以看到,在其他商品的頁面上,也可以正確的拿到了其月銷量數據了。
實際操作中,多多嘗試和總結經驗。
四、無目標命令
1.為什么沒有目標?
UiBot所在的系統和目標不在統一系統中,無法操作目標界面元素。
虛擬機和遠程桌面,如:Citrix、VMWare、Hyper-V、VirtualBox、遠程桌面(RDP)、各種安卓模擬器(如靠譜助手)等
解決辦法:可以把UiBot和流程涉及到的軟件,都安裝在虛擬機里,或者遠程計算機里。
基於DirectUI的軟件:元素是被畫出來的,UiBot無法找到。
游戲:元素是畫出來的,界面變化快,時效性要求高,RPA對游戲效果不好。游戲推薦按鍵精靈。
2.無目標命令
有目標和無目標的命令
最重要的是“模擬移動”:設置坐標位置 - 模擬移動 - 模擬點擊 - 輸入文本
Windows坐標理解為第4象限,坐標x:200, y:300,x軸是距離屏幕左邊的水平方向的距離,y軸是距離屏幕上面的垂直方向的距離。
Windows的屏幕坐標系
坐標保存在BotScript語言的字典中,字典可以存放多個值,變量名為pnt
,則使用pnt["x"]
和pnt["y"]
即可得到坐標的x和y兩個值。
固定坐標情況很少,一般都會有變化的,一般推薦使用其他命令根據某種特征,先找到界面元素的坐標,然后把坐標當做變量穿給無目標命令。
在UiBot中,無目標命令的最佳拍檔,是圖像命令。
3.圖像命令
UiBot Creator里面列出的“圖像”類命令
“查找圖像”命令:指定一個圖像文件,格式png(無損壓縮,推薦)、bmp、jpg等,掃描查找是否在指定區域,沒有則發生異常。
使用“查找圖像”命令並指定圖像和查找范圍
“查找圖像”命令的屬性
“激活窗口”:把窗口放到最前面顯示,防止被其他窗口遮擋,一般都默認是。
用“輸出調試信息”查看結果
結果:
{ "x" : 116, "y" : 235 }
objPoint["x"]
和 objPoint["y"]
即可得到其中的x和y值
用“輸出調試信息”查看結果
“點擊圖像”:“查找圖像”、“模擬移動”、“模擬點擊”三條命令的組合
4.OCR命令
很難直接獲取微信中的聊天文字
UiBot采用百度雲OCR,使用條件:
1.聯網
2.向百度付費:免費通用文字識別每天5000次,證照等識別每天500次,超過了需要購買百度服務。
3.注冊百度賬號:需要自己注冊百度雲賬號 及 百度雲OCR服務的賬號(一般稱為Access Key和Secret Key),申請方法很簡單,請點擊這里查看我們的在線教程。
UiBot的OCR命令
紅框里的命令類似於“圖像”類中的“點擊圖像”、“鼠標移動到圖像上”,“查找圖像”命令,只不過不需要傳入圖像了,只需要在屬性中標明要找的文字即可。
藍框里的命令和綠框里的命令類似,只不過前者需要提供一個圖像文件,后者需要提供一個窗口、以及窗口中的一個區域。
選擇OCR目標
完成一條OCR命令
下面,再測試一下“圖像特殊OCR識別”命令。所謂“特殊”,是指我們要測試的是某種特定的圖像,如身份證、火車票等。假設我們在D:\\1.png
文件中保存了如下的圖像:
要進行特殊OCR的圖像
特殊OCR的屬性設置
5.注意事項
無目標的命令,特別是它們所依賴的圖像、OCR等命令,有以下的缺點:
- 速度慢
- 怕遮擋
- 依賴圖像文件
- OCR需聯網
圖像、OCR命令技巧:
截圖盡量小
區域盡量小
盡量保持分辨率和縮放比列一致
如,Windows 10操作系統分辨率和縮放比例:
使用圖片時用絕對路徑:
推薦把圖片文件放res文件夾下,用@res"1.png"表示路徑,@可以自動獲取前綴路徑。
五、語言參考
1.概述
UiBot是用來做RPA的編程語言,UB語言簡單易用。
2.基本結構
UB語言是純文本格式,UTF-8編碼。
執行一個流程塊的時候,從第一行開始執行,遇到函數定義暫時跳過,然后繼續從函數結束后的一行開始執行。
推薦一行只寫一個語句。如果一定要寫多個語句,則用冒號分隔符(:)進行分隔。
需要折行,可以在任意語句中出現的逗號(,
)或二元運算符(“二元運算符”的概念請參考這里)之后直接折行,一定要在其他地方折行,則用反斜杠(\
)作為折行符號。例如:
Dim a= \
1
注釋:
單行注釋://
多行注釋:
/*
語句1
語句2
*/
UB語言中所有關鍵字、變量名、函數名均不區分大小寫。
3.變量、常量和數據類型
1.數據類型:整數、浮點、布爾、字符串、函數、復合型和空值。
整數型:可以以十進制或者十六進制的方式表示,其中十六進制需加前綴 &H
或 &h
浮點數:可以用常規方式或者科學計數法表示。如 0.01
或者 1E-2
或者 1e-2
均代表同一個浮點數。
布爾型:True
或 False
(
不區分大小寫
)
字符串:一對雙引號("
) 或 一對單引號('
)包含,\t
代表制表符,用 \n
代表換行,用 \'
代表單引號,用 \"
代表雙引號,用 \\
代表反斜杠本身。
字符串中間可以直接換行,無需增加任何其他符號,換行符也會作為字符串的一部分。
用前后各三個單引號('''
)來表示一個長字符串。在長字符串中,可以直接寫回車符、單引號和雙引號,無需用 \n
,\'
或者 \"
函數型的值只能是已經定義好的函數
復合型:數組、字典等
空值型: Null
,不區分大小寫
a = 1 // a是整數型變量 a = &HFF // a還是整數型變量 a = True // a是布爾型變量。作為動態類型語言,a的類型可以隨時變化 a = FALSE // a是布爾型變量,注意True和False都不區分大小寫 a = 'UiBot' // a是字符串型變量 a = "UiBot RPA" // a是字符串型變量,字符串中可以換行 a = null // a是空值型變量,可以寫為Null、NULL或null(不區分大小寫)
2.變量和常量
變量定義:
Dim 變量名
定義變量並賦初值:
Dim 變量名=值
定義多個變量:
Dim 變量名1 = 值1, 變量名2
Dim 變量名1 = 值1, 變量名2 = 值2
標識符:有命名的東西(例如:變量、常量、函數等)
標識符以英文字母或_開頭,可以包含數字、UTF-8編碼中的其他語言字符(如漢字),變量名不區分大小寫。
UB語言變量必須定義(除了For
語句中的循環變量、Try
語句中的異常變量、函數參數等)。
局部變量:函數內定義和使用
全局變量:函數外任意位置定義,全局使用。
3.復合類型
數組:
[值1, 值2, 值3 ]
字典:
{ “名字1”:值1, “名字2”:值2, “名字3”:值3 }
名字只能是字符串,值可以是任意類型
索引使用方括號[],多維數組或字典中的數組:
變量名[索引1][索引2]
Dim 變量 = [486, 557, 256] // 變量可以用中文命名,初值是一個數組 a = 變量[1] // 此時a被賦值為557 變量 = {"key1":486, "key2":557, "key3":256} // 變量的類型改為一個字典 a = 變量["key1"] // 此時a被賦值為486 變量["key4"] = [235, 668] // 往字典中增加一個新值,可以是一個數組 //此時,字典中的內容為 {"key1":486, "key2":557, "key3":256, "key4":[235, 668]} a = 變量["key4"][0] // 此時a被賦值為235
注:數組索引只能是整數,0開始。字典索引只能是字符串類型。
4.運算符和表達式
表達式:變量、常量和值用運算符和圓括號 ( )
連接到一起
Not
是一元運算符
- :
一元運算符,也可以用作二元運算符
其他都是二元運算符
注:=:出現在括號()內表示判斷,單獨語句表示賦值。
表達式常用於賦值語句,可以給某個變量賦值,其形式為:
變量名 = 表達式
數組、字典是引用類型,引用傳遞。
引用類型: a = [486, 557, 256] // a是一個數組 b = a // b是a的“別名” b[1] = 558 // 改變b里面的值,a里面的值也會跟着改變 c = a[1] // 此時c的值是558,而不是原來的557 變整數類型: a = 557 // 此時a被賦值為557(變為整數型) b = a // 此時b里面的值也是557,但和a分別保存 b = 558 // b里面的值發生改變,a的值不改變 c = a // 此時c的值仍然是原來的557,因為a不是字典、數組
5.邏輯語句
(1).條件分支語句
If 條件
語句塊1
End If
If 條件
語句塊1
Else
語句塊2
End If
If 條件1
語句塊1
ElseIf 條件2
語句塊2
Else
語句塊3
End If
示例:
// Time.Hour() 可以取得當前時間中的小時數 // TracePrint() 可以把指定的內容輸出到UiBot的輸出欄中 If Time.Hour() > 18 // 取得當前時間中的小時數 TracePrint("下班時間") // 如果大於18,則執行這里的語句 Else TracePrint("上班時間") // 如果不滿足前面的條件,則執行這里的語句 End If
(2).選擇分支語句
根據一定的條件,選擇多個分支中的一個。先計算Select Case
后面的表達式
,然后判斷是否有某個Case
分支和這個表達式
的值是一致的。如果沒有一致的Case
分支,則執行Case Else
(如果有)后面的語句塊。
Select Case 表達式
Case 表達式1, 表達式2
語句塊1
Case 表達式3, 表達式4
語句塊2
Case Else
語句塊3
End Select
示例:
Select Case Time.Month() // 取得當前時間中的月份 Case 1,3,5,7,8,10,12 // 如果是1、3、5、7、8、10、12月 DayOfMonth = 31 // 當月有31天 Case 4,6,9,11 // 如果是4、6、9、11月 DayOfMonth = 30 // 當月有30天 Case Else // 如果是其他(也就是2月) DayOfMonth = 28 // 當月有28天(不考慮閏年的情況) End Select TracePrint(DayOfMonth)
(3).條件循環語句
在UB語言中,使用Do…Loop
語句來實現條件循環,即滿足一定條件時,循環執行某一語句塊。Do…Loop
語句有以下五種不同的形式,用法較為靈活:
- 前置條件成立則循環:先判斷
條件
,條件
成立則循環執行語句塊,否則自動退出循環。
Do While 條件
語句塊
Loop
- 前置條件不成立則循環:和前一條相反,
條件
成立則退出循環,否則循環執行語句塊。
Do Until 條件 //Until:到...為止
語句塊
Loop
- 后置條件成立則循環:先執行語句塊,再判斷
條件
,條件
成立則繼續循環執行語句塊,否則自動退出循環。
Do
語句塊
Loop While 條件
- 后置條件不成立則循環:先執行語句塊,再判斷
條件
,條件
成立則自動退出循環,否則繼續循環執行語句塊。
Do
語句塊
Loop Until 條件
- 無限循環:該循環語句本身不進行任何條件的判斷,需要在語句塊中自行做判斷,如果語句塊中沒有跳出循環的語句,則會無限的執行該循環
Do
語句塊
Loop
示例:
Do Until Time.Hour() > 18 // 判斷當前時間中的小時數,只要不大於18就循環 TracePrint("還沒有到下班時間") // 每次循環,都會執行這里的語句 Delay(1000) // 每判斷一次,休息一秒鍾 Loop TracePrint("下班時間到啦") // 如果大於18,則跳出循環,執行這里的語句
(4).計次循環語句
計次循環語句主要用於執行一定次數的循環,其基本形式為:
For 循環變量 = 起始值 To 結束值 Step 步長
語句塊
Next
起始值
、結束值
、步長
都只允許是整數型或者浮點數型;步長
可以省略,默認值為1。變量從起始值
開始,每循環一次自動增加步長
,直到大於結束值
,循環才會結束。
在計次循環語句中,循環變量
可以不用Dim
語句定義,直接使用,但在循環結束后就不能再使用了。
Dim count = 0 // 定義變量count For i=1 To 100 // 每次循環,變量i都會加1。這里變量i不需要定義 count = count + i Next TracePrint(count) // 這里會顯示1+2+3+…+100的結果,即5050
(5).遍歷循環語句
遍歷循環語句可以用於處理數組、字典中的每一個元素。遍歷循環語句有以下兩種形式:
For Each 循環變量 In 數組或字典
語句塊
Next
在這種形式的循環語句中,會自動遍歷數組、字典中的每一個值,並將其置入循環變量
中,直到遍歷完成為止。
或者:
在這種形式的循環語句中,會自動遍歷數組、字典中的每一個索引和值,並將其分別置入循環變量1、循環變量2中,直到遍歷完成為止。
和計次循環語句類似,在遍歷循環語句中,循環變量
可以不用Dim
語句定義,直接使用,但在循環結束后就不能再使用了。
例如:
Dim days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] // 定義數組型變量days Dim count = 0 For Each i In days // 每次循環,變量i的值分別為days中的每個值 count = count + i // 把數組中的每個值依次加起來 Next TracePrint(count) // 這里會顯示一年中每個月的天數的累加和,即365
(6).跳出語句
Break:只能出現在條件循環、計次循環或遍歷循環等循環語句的內部語句塊中,其含義是立即跳出當前循環。
Continue:只能出現在條件循環、計次循環或遍歷循環等循環語句的內部語句塊中,其含義是立即結束當前循環,並開始下一次循環。
Exit:自動結束整個流程 (不是當前流程塊)
例如:
Dim days = { '一月':31, '二月':28, '三月':31, '四月':30, '五月':31, '六月':30, '七月':31, '八月':31, '九月':30, '十月':31, '十一月':30, '十二月':31 } // 定義字典型變量days For Each i,j In days // 每次循環,變量i, j分別為days中每個名字和值 If j Mod 2 = 0 // 如果j是偶數 Continue // 結束本次循環,開始下一次循環 End If TracePrint(i) // 把days中的名字(其值不是偶數)顯示出來 Next
6.函數
函數的定義和調用沒有先后關系,可以先出現調用,再出現定義。但函數必須定義在全局空間中,也就是說,函數定義不能出現在其他函數定義、分支語句、循環語句下面的語句塊中。
- 無參數的函數
Function 函數名( )
語句塊
End Function
- 有參數的函數
Function 函數名(參數定義1, 參數定義2)
語句塊
End Function
在函數定義中,要退出函數並返回,采用以下寫法:
Return 返回值
Function Add(x, y=1) // 定義了兩個參數的函數,第二個參數有默認值 Return x + y // 返回值為x+y的值 End Function
調用函數的格式如下:
返回 = 函數名(表達式1, 表達式2)
或者
函數名(表達式1,表達式2)
按照第一種格式調用,可以指定一個變量作為返回,當函數調用完成后,函數的返回值會自動賦值給這里的返回變量,調用者可以通過返回值,了解到函數調用的情況。此時,必須在被調用的函數名后面加圓括號。而當按照第二種格式調用時,調用者不需要返回值,則可以省略圓括號,使語句更符合自然語言習慣。
當調用時,相當於對函數中的參數進行了一次賦值運算,用表達式的值對其賦值。與賦值運算的規則相同,當表達式為一個獨立的(沒有使用任何運算符計算)數組、字典時,賦值操作只賦值其引用,也就是說,只是為變量增加一個“別名”。
調用函數時,傳入的表達式的數量可以少於參數的數量,如果某個參數沒有傳入值,或者傳入值為Null
,則采用其默認值,如果連默認值也沒有,則其值自動為Null
。
a = Add(100) // 調用Add函數,第二個參數取默認值1,所以a的值是101 b = Add(100, 200) // 調用Add函數,指定了兩個參數,所以b的值是300 Add 100, 200 // 調用Add函數,不關心返回值,所以可以不寫括號
當函數定義完成后,其名稱可以作為一個函數類型的常量使用,也可以把函數名稱賦值給某個變量,用這個變量也可以調用這個函數。
例如,對於上面定義的函數Add
,可以按照如下的方式使用:
Dim Plus = Add TracePrint Plus(100, 200) // 相當於先調用了Add函數,再用其返回值調用了TracePrint函數,結果是300
7.其他
(1)多模塊
UB語言支持多模塊,可以用其他語言實現擴展模塊,並在當前流程塊中使用。目前支持以下幾種類型的模塊:1)UB語言的流程塊;2)Python語言的模塊;3)C/C++語言的模塊;4).Net的模塊;5)Lua語言的模塊。不同的模塊有不同的擴展名,去掉擴展名以后,剩下的文件名就是模塊的名字。比如某個Python語言的模塊,文件名為Rest.py,則其模塊名為Rest。
在UB語言中,采用以下方式導入一個模塊:
Import 模塊名
注意這里的模塊名的書寫規則和變量名一致,不需要采用雙引號,也不需要加擴展名。如Import Rest。UiBot在編譯和運行時會自動按照Lua語言模塊、C語言模塊、.Net語言模塊、Python語言模塊、UB語言流程塊的先后順序,依次加上相應的擴展名進行查找。在Windows中,由於文件名不區分大小寫,所以Import語句后面的模塊名也可以不區分大小寫。在其他操作系統中,需要注意模塊名的大小寫要和文件一致。
每個導入的模塊,都會被放置在一個與模塊名同名的“命名空間”中,可以通過下面這種方式來調用導入模塊中的函數:
命名空間.函數名
對於Python、Lua語言的模塊,只會保留其中的全局變量定義和函數定義,其他內容都會被忽略。對於C語言的模塊和.Net模塊,只能調用其中定義的函數。
如果要導入一個UB語言的流程塊,則需要導入和被導入的流程塊文件在同一個目錄下。
導入UB語言的流程塊之后,既可以調用被導入的流程塊中定義的函數,又可以直接以流程塊的名字作為函數名,直接運行這個流程塊中的所有命令。
ABC()
例如,有一個流程塊 ABC.task。在其他流程塊中Import之后,直接采用下面的格式即可直接調用ABC.task(相當於運行了ABC.task這個流程塊):
ABC.test()
(2)異常
作為動態類型語言,有很多錯誤在編譯時難以檢查,只能在運行時報錯。而且,由於UiBot不強調運行速度,而更強調運行的穩定性,也會在運行時加入比較多的檢查。當出錯的時候,比較合適的報錯手段是拋出異常。 比如,對於有目標命令(“有目標命令”的概念可以參考這里),在運行的時候,如果到了超時時間都不能找到目標,就會自動拋出一個異常。
除了自動拋出的異常之外,在流程塊中,還可以采用Throw
語句拋出一個異常:
Throw 字符串
在拋出異常時,可以把異常相關信息以字符串的形式一起拋出,也可以省略這個字符串。
如果在流程塊中沒有對異常進行處理,當出現異常時,整個流程都會終止執行,並且把異常相關信息顯示出來。如下圖所示:
流程運行的時候出現異常
如果不希望流程在發生異常的時候終止,可以采用以下語句對異常進行處理:
Try
語句塊
Catch 變量名
語句塊
Else
語句塊
End Try
如果在Try
后面的語句塊中發生了異常,會跳到Catch
后面的語句塊中執行。如果在Try
語句塊中沒有發生異常,且定義了Else
語句塊(當然,也可以省略Else
語句塊),則會跳到Else
語句塊中執行。
Catch
語句后面的變量名可以省略。如果不省略,可以不用Dim
語句提前定義,當發生異常時,這個變量的值是一個字典,其中包含“File”、“Line”和“Message”三個字段,分別代表發生異常的文件名、發生異常的行號、異常包含的信息。
六、編寫源代碼
1.基本規則
UiBot的源代碼視圖遵循以下規則:
- 用一個源代碼文件來表示一個流程塊,源代碼文件的擴展名默認是.task
- 用函數調用來表示一條命令
- 用函數調用時傳入的參數,來表示命令的屬性
- 用
Dim
語句來定義變量
從圖中不難看出,“啟動IE瀏覽器”的命令在源代碼視圖中實際上是對函數WebBrowser.Create
的調用;啟動IE瀏覽器時設置的各項屬性,都是函數調用中的變量,如"about:blank"
等;命令中使用到的變量,需要用Dim
語言定義。
可視化視圖和對應的源代碼視圖
UiBot支持的命令非常豐富,在源代碼視圖中,這些命令都使用函數來表示。所以,UiBot實際上在UB語言的基礎上,內置了一個很大的函數庫。
其中,最常用的一部分函數是沒有命名空間的,如Delay
函數;
其他函數都是包含一個命名空間的,如前面例子中的WebBrowser.Create
函數,其命名空間是WebBrowser
。對於有命名空間的函數,大部分都是通過UB語言中的多模塊機制,利用一個模塊中實現的,所以在使用前需要先用Import
語言導入相應的模塊,例如WebBrowser.Create
函數,在使用前需要寫Import WebBrowser
。
當然,還有幾個基礎功能,其命名空間是會自動Import
的,就不需要我們再做一次Import
了,包括Math
、Log
、Json
等。
UiBot支持的全部命令,其文檔可以參考這里。在本文中,我們僅列出目前版本中已支持的主要命名空間及其功能概述,供讀者參考。如對其中某個命名空間的功能有興趣,再查閱文檔不遲。注意,如前文所述,UB語言中的各種名字、關鍵字都不區分大小寫,所以下表中列出的各個命名空間,都可以按全大寫、全小寫或各種大小寫混合的方案進行書寫。
比如,我們對Mouse
下面的功能感興趣,一種方法是查閱文檔,看看這個命名空間下面有哪些函數,每個函數有哪些參數。另外,如果您的手已經放在鍵盤上了,還有另一種更快捷的方法,如下所述:
- 在UiBot Creator的源代碼視圖中,隨便找一個空行,然后鍵入
Mouse
(其實都不需要完整輸入,只需要輸入首字母m
,即可自動聯想到相關的關鍵詞,按上下箭頭選擇,並按回車確認即可) - 鍵入一個
.
符號,此時,會自動列出Mouse
命名空間下的所有函數 - 繼續按上下箭頭選擇,每個選中的函數,都會出現其功能的簡要說明,按回車確認要用的函數
- 再鍵入一個左括號
(
,此時,會自動列出這個函數的參數,並顯示第一個參數的說明 - 此后,每輸入一個參數,按逗號進行參數分隔后,會自動切換到后續參數的說明
上述過程大致如下圖所示:
2.有命令目標
“點擊目標”操作的源代碼視圖
第一行,以 #
符號開頭,可以簡單的認為是一種特殊的注釋,對流程的運行沒有影響,可以省掉。其實,在UiBot Creator中用淺灰色顯示,也是建議您不要糾結於此。
第一行之后的內容其實是一個函數調用,調用的函數是Mouse.Action
,這個函數包含5個參數。但實際上,只有第一個參數是必須的,后面的參數都可以省略。我們不妨把可以省略的內容都去掉,只剩下下圖所示的內容:
“點擊目標”操作的源代碼視圖(簡化后)
不難看出,函數只剩下了一個參數,這個參數是一個字典類型,代表了要點擊的目標。當然,即便是這樣簡化,這個字典類型里面的內容也是很難手寫出來的。怎么辦呢?請注意,在源代碼視圖的上方,有“元素”、“圖像”、“窗口”、“區域”四個按鈕,分別還有對應的熱鍵Alt+1、Alt+2、Alt+3、Alt+4(如下圖)。由於我們需要用一個界面元素來作為命令的目標,所以,這里點擊“元素”按鈕。
源代碼視圖上方的快捷按鈕點擊后,UiBot Creator的界面暫時消失,出現了“目標選擇器”,也就是紅邊藍底的半透明遮罩。這個“目標選擇器”的用法,和可視化視圖中選取目標的方法一模一樣,只需要把鼠標移動到目標上,待遮罩恰好遮住目標的時候,單擊鼠標左鍵即可。如果您對“目標選擇器”的操作還不熟悉,請回頭復習前文中目標選取這部分內容。
目標編輯器的界面
選擇目標之后,會彈出UiBot Creator的“目標編輯器”對話框,如下圖所示。我們在前文中已經學習過如何使用目標編輯器來修改目標的特征,以避免造成目標的“錯選”或“漏選”。這里的使用方法仍然與前文一致,僅有一點點細微的差別:右下角的按鈕變成了“復制到剪貼板”。按下這個按鈕,UiBot Creator會把目標的各個特征重新組合成一個字典類型的值,並把這個值以文本的形式復制到操作系統的剪貼板中。之后,只需要回到源代碼視圖,把剪貼板里的這段文本粘貼到函數調用Mouse.Action
中作為參數,即可完成這條命令的編寫。
不妨把這段文本粘貼到記事本里,可以看到,其內容就是描述目標的字典類型的值:
{"wnd":[{"app":"explorer","cls":"Shell_TrayWnd"},{"cls":"Start","title":"開始"}]}
在UiBot中書寫一條Mouse.Action()
函數調用,並把上述內容粘貼到圓括號里面,即可完成這條命令:
Mouse.Action({"wnd":[{"app":"explorer","cls":"Shell_TrayWnd"},{"cls":"Start","title":"開始"}]})
舉一反三,我們試試做一點兒更多的操作。比如,把這個開始菜單按鈕的圖像,保存到一個圖像文件里面去。用UiElement.ScreenShot
函數可以完成這個任務。這個函數有兩個必選的參數,第一個參數仍然是指定界面元素作為目標,第二個參數是要保存的圖像文件的路徑。也就是說,第一個參數和前面Mouse.Action
的參數是完全一樣的,把剛才復制到剪貼板的內容直接粘貼到這里就行;第二個參數寫一個文件路徑即可,比如"C:\\temp\\1.png"
。這里有兩個值得注意的細節問題:
- 由於需要寫文件,所以請注意,需要寫到有權限的路徑下。比如,UiBot默認不是以管理員賬號啟動的,所以諸如
"C:\\"
這樣的路徑就是不具有寫權限的,但"C:\\temp"
具有寫權限。 - 我們使用了字符串來表示文件路徑,按照前文中UiBot的規定,字符串中要用轉義字符
\\
來表示一個反斜杠\
,所以路徑需要寫為"C:\\temp\\1.png"
的格式。
保存並運行,即可看到開始菜單按鈕的圖像被存為一個文件。
回過頭看看這段源代碼,不難發現,“開始菜單按鈕”這個目標被重復使用了兩次,不好看。我們稍微改造一下,成為下面的樣子:
Dim StartButton = {"wnd":[{"app":"explorer","cls":"Shell_TrayWnd"},{"cls":"Start","title":"開始"}]}
Mouse.Action(StartButton)
UiElement.ScreenShot(StartButton, "C:\\temp\\1.png")
這樣看起來就清晰多了。
===================================================
個人總結:
准備:
1.chrome瀏覽器安裝插件,用於獲取元素。
2.關閉chrome安全設置,右擊瀏覽器圖標-屬性-目標,在目標后添加(雙引號后面): --disable-web-security --user-data-dir=D:\temp
3.允許excle宏命令:文件-選項-信任中心-設置-宏設置-啟用所有宏,信任VBA工程
細節:
1.獲取網頁元素時,不可以同時打開多個網頁,防止后面的網頁對獲取元素干擾。
2.catch錯誤參數:errorDic
文件:errorDic["File"]
行號:errorDic["Line"]
錯誤信息:errorDic["Message"]
3.打開瀏覽器或文件時,最好執行下:界面 - 窗口 - 更改窗口顯示狀態
防止廣告彈窗的影響,可以將窗口設置為置頂,合適時及時取消置頂。
4.引入其他流程塊:
Import uibot37688ddf4
dim configDic = uibot37688ddf4.GetCofigDic()
5.插件擴展:
.Net:將dll文件放入creator安裝目錄下的extend文件下的DotNet文件下
dll文件制作:vs新建類庫項目 - 類庫名和類名保持一致,再加一個接口類文件Inteface,接口類文件中只寫方法名,類文件去實現接口。
uibot里面調用直接先import dll的文件名,然后調用:Utility.Test()
python:.py文件放入python文件夾下
6.配置:
用uibot命令去寫INI文件第1個節點和鍵值(第一個自己寫沒有)