今天要從頭開始建立一個實際操作,首先我先把流程圖給畫出來,比較好方便思考,這項功能是我們利用 Code 產生一個 CSV 檔案,裡面擁有好幾段運算式 (AB) (A-C) 等等的,我們會利用圖片偵測的方式判斷出小算盤的圖片樣式,並且讓桌面操作可以根據我們 CSV 檔案中的運算式做操作。假如說今天獲得運算式 (215) 他就會去偵測小算盤中 2 15 這三個圖片,並且依序自動點擊,完成後再將結果儲存起來,寫入回 CSV 檔案。
建立訓練命名技能群組,點擊『Desktop Automation』後開始進行程式碼撰寫。
我們在這步驟寫出兩個 List 並且涵蓋加減乘除等運算式,並且利用迴圈的方式,將陣列一列列寫入 CSV 檔案中,我們從 writeCSV 可以看見我們寫入的他的 header 和 rows,並且命名為 table.csv。寫完的檔案可以再 WorkSpace中看見
let num1_list = [12,50,1,5]
let num2_list = [31,5,2,3]
let operation_list = ['*',"/","+",'-']
let header = ['num1','operation','num2']
let rows = []
for(let i=0 ; i<num1_list.length ; i++){
let obj = {}
obj['num1'] = num1_list[i]
obj['operation'] = operation_list[i]
obj['num2'] = num2_list[i]
rows.push(obj)
}
await api.writeCSV('table.csv',rows,header)
藉由桌面自動化圖片辨識的方式,裁切選擇需要做圖片辨識的範圍,我們這邊把所有的數字鍵盤和運算符號都涵蓋進去,在這邊可以根據需求決定是否要做 Mask 來將圖片去背景,我這邊的測試結果是沒有使用去背。
截圖後選取的 Crop 會將我們的圖片存入「Crop List」中,在 No-Code Mode 的模式下,進入 Crop List 相簿可以看到以下截圖畫面,這就是我剛才所做的整個 List 設定。
從 Crop List 點選「Click Drop」,會將抓取的程式碼存入 Low-Code 模式中,將我們所有的程式碼都程列出來,並且上傳 Commit 測試,確定截圖能夠完整執行運算功能。
我們接下來到 WorkSpace 會看見我們的圖片已經被存起來了,我們能修正調整一下檔案命名,讓他看起來正常一點,此外程式碼參考如下,這樣命名真的清楚多了。
//程式碼太長了這裡特別縮一下 通常不會這樣簡寫
let buttons = {
num0 : 'crop-0.png',num1 : 'crop-1.png',
num2 : 'crop-2.png',num3 : 'crop-3.png',
num4 : 'crop-4.png',num5 : 'crop-5.png',
num6 : 'crop-6.png',num7 : 'crop-7.png',
num8 : 'crop-8.png',num9 : 'crop-9.png',
plus : 'crop-plus.png',multiple : 'crop-multiple.png',
minus : 'crop-minus.png',divide : 'crop-divide.png',
equal : 'crop-equal.png',clean : 'crop-clean.png',
dot : 'crop-dot.png'
}
async function pressButton(btn){
switch(btn){
case '0' :await api.clickCrop(buttons['num0'], 20, 20);break;
case '1' :await api.clickCrop(buttons['num1'], 20, 20);break;
case '2' :await api.clickCrop(buttons['num2'], 20, 20);break;
case '3' :await api.clickCrop(buttons['num3'], 20, 20);break;
case '4' :await api.clickCrop(buttons['num4'], 20, 20);break;
case '5' :await api.clickCrop(buttons['num5'], 20, 20);break;
case '6' :await api.clickCrop(buttons['num6'], 20, 20);break;
case '7' :await api.clickCrop(buttons['num7'], 20, 20);break;
case '8' :await api.clickCrop(buttons['num8'], 20, 20);break;
case '9' :await api.clickCrop(buttons['num9'], 20, 20);break;
case '+' :await api.clickCrop(buttons['plus'], 20, 20);break;
case '-' :await api.clickCrop(buttons['minus'], 20, 20);break;
case '*' :await api.clickCrop(buttons['multiple'], 20, 20);break;
case '/' :await api.clickCrop(buttons['divide'], 20, 20);break;
case '.' :await api.clickCrop(buttons['dot'], 20, 20);break;
}
}
首先確保每一次都能夠正常打開流程,我們先將預設的工具打開,這次範例使用的是 Windows 系統內建的小算盤,我只需要將路徑放上即可。
// open calculator
await api.shell.openPath('C:/Windows/System32/calc.exe')
await api.sleep(300);
利用 readCSV 讀取 table.csv 檔案,並且利用 , 做分隔從 0 行列開始。我們利用 Console.log 查看我們的輸出結果。我可以寫得細項一點,確保執行資料輸出是正常的,我們可以打開 Debug 視窗做輸出確認。
// read csv table
let data = await api.readCSV('table.csv', ',', 0)
console.log(data)
console.log(data[0]['num1'])
console.log(data[0]['operation'])
console.log(data[0]['num2'])
Debug 視窗可以發現輸出結果有問題,就能再細部調整程式碼。
一切執行都很順利的話我們就能更細部的執行,寫了一個迴圈,我們一樣可以設定 consloe 來確保輸出正常,我們利用 Click 來取得資料。
for(let i = 0; i<data.length; i++){
let number1 = data[i]['num1']
let operator = data[i]['operation']
let number2 = data[i]['num2']
console.log("Num1:"+number1)
console.log("Oper:"+operator)
console.log("Num2:"+number2)
// click number1
for(let b1 = 0; b1 < number1.length; b1++){
await pressButton(`${number1[b1]}`);
await api.sleep(300);
}
// click operator
await pressButton(`${operator}`)
await api.sleep(300);
// click number2
for(let b2 = 0; b2 < number2.length; b2++){
await pressButton(`${number2[b2]}`);
await api.sleep(300);
}
// click =
await api.clickCrop(buttons['equal'], 20, 20)
await api.sleep(300);
// copy result
await api.keyboard.type(api.key.LeftControl, api.key.C);
await api.sleep(300);
// read clipboard
let result = api.clipboard.readText()
// output to data
data[i]['result'] = result
await api.writeCSV('result.csv', data, ['number1', 'operator', 'number2', 'result'])
// click C
await api.clickCrop('crop-clean.png', null, null, {confidence: 0.99})
}
上方迴圈已經有寫過但特別拉出來單獨講一下。我們複製每一次運算出來的結果,像是 5*30 = 150,他就會把 150 給儲存下來複製到剪貼簿內,我們再撈取剪貼簿內的資料取得運算結果,從這程式碼中可以看到我們利用 api.writeCSV 寫入資料到 result.csv 檔案內,並且設定他的表頭和 data,這次我們也包含了運算結果 result。我們能夠在 WorkSpace 中看見輸出成功的檔案。
// copy result
await api.keyboard.type(api.key.LeftControl, api.key.C);
await api.sleep(300);
// read/out clipboard
let result = api.clipboard.readText()
data[i]['result'] = result
await api.writeCSV('result.csv', data, ['number1', 'operator', 'number2', 'result'])
黃仁勳的一句話讓這個世界都瘋了,身為與數據打交道多年的我們能做些什麼呢? 很簡單就是跟著一起瘋。「You Learn the more, you Get the more.」。沒想到鐵人賽又一年了呢,這篇是 【Five mins RPA】 系列文章除此之外也歡迎大家走走逛逛關於我過去的文章
一個正在為 300 多萬訂閱的 Youtuber 服務的資料科學家,擅長將商管行銷導入機器學習與人工智慧,並且從大量的數據中找出 Insight,待過 FMCG、Communication、Digital Marketing,最近一直在資訊圈打滾,趕著不被這波人工智慧浪潮給吞噬,寫文章寫了好一段時間了,期待著這個社會每個人能在各個角力間不斷沖突而漸能找到一個平衡點並回歸最初的初心。