公式サイトのKnowledge Baseサンプルを詳しく解説します。
今回は"Automate Data Extraction from Desktop Application"です。
https://www.uipath.com/kb-articles/automate-data-extraction-from-desktop-application
シナリオ
経費精算のためのWindowsアプリケーション"ExpenseIt"を起動し、Emailアドレス、従業員番号等を入力してログイン、そして画面にテーブル状に表示された経費リストを自動的に読み取り、CSVファイルに保存します。
このサンプルで使用する機能
- UiPath Studio
- Desktop Recording - Windowsアプリケーションへのログインを記録します。
-
Screen Scraping - 画面に表示された経費リストを読み取ります。
- UiPathアクティビティ
- Open Application - 経費精算アプリケーションを起動します
- Type into - 経費精算アプリケーションに情報を入力します
- Click - ボタンをクリックします
- Build Data Table - CSVデータを保持するDataTableを作成します
-
Write Csv File - DataTableをCSVファイルで保存します
※Type into, ClickはRecording機能で自動的に作成されます。
- Windows Workflow
- Whileコントロール
-
Assignコントロール
- .Net関連
- System.data.DataTable - 経費データを格納するデータモデルです
準備
-
サンプルZIPファイルをダウンロードします。
https://drive.google.com/open?id=0BxVAKI3l9Pc5UWY5Ujd2eElZVUEZIPファイルには以下のファイルが含まれています。これらのファイルを任意の場所に展開します。
- Expenses.csv - 出力されるCSVファイル - Main.xaml - ワークフローのXAML実装 - project.json - UiPathプロジェクトファイル - WPF_30_ANYCPU_ExpenseIt.exe - 経費精算アプリケーション実行ファイル
実行と結果
- Runボタン(またはF5キー)で実行します。
- ExpenseItが起動し、自動的に必要項目が入力されます。
-
Expenses.csvが出力されます。
(zipファイルに元々含まれていましたが更新日時が変わっています)
ファイルを開けると画面で表示された経費リストが出力されています。
ワークフロー作成ビデオ
解説
-
"Open application 'WPF_30_ANYCPU_ExpenseIt...'"アクティビティ
ダブルクリックすると以下のようになっています。
①ここでは操作対象となるウィンドウが表示されています。
Recording機能でウィンドウを選択した際、アプリケーション実行ファイルのパス(FileName)とウィンドウのSelectorが自動的に記録されます。
FileNameには経費精算アプリケーションの実行ファイルのパスが記録されています。
Selectorを確認してみましょう。Selectorとは、UiPathが操作対象のユーザ・インターフェース要素を特定するために使う情報で、Recording機能で自動的に設定されます。
ここではアプリケーション・ウィンドウを特定するためのSelectorとして以下の3つが使用されています。
"app" - 実行ファイル名 "title" - ウィンドウタイトル "cls" - ウィンドウクラス名
"app"は経費精算アプリケーションの実行ファイル名である"wpf_30_anycpu_expenseIt.exe"が、"title"はアプリケーションのウィンドウタイトルである"ExpenseIt Standalone"が、"cls"はウィンドウクラス名である"HwndWrapper*"がそれぞれ指定されています(アスタリスク*はワイルドカードで、HwndWrapperで始まる名前を指定しています)。
ウィンドウクラスについて
実行ファイル名、ウィンドウタイトルについては自明ですが、ウィンドウクラスが何かを知るにはWindowsにおけるアプリケーション開発についての知識が必要です。Windowsアプリケーション開発でウィンドウを作成する際、CreateWindowというWindows APIを使い、引数としてlpClassName
としてウィンドウクラス名を渡し、どのようなデザイン・機能を持つウィンドウにしたいか指定します。これが"cls"で指定するウィンドウクラス名です。なお、指定するウィンドウクラスはあらかじめRegisterClassを使い、WNDCLASS構造体としてWindowsシステムに登録しなければいけません。
参考1:C++によるWindowsプログラミングの学習-ウィンドウを作成する
参考2:"WinLister"というツールで筆者のPCでウィンドウクラス名の一覧を表示すると以下のようになります。
②Window Scopeが表示されています。
Recording機能を使う際、"Basic Recording"を使うとWindow Scopeはアクティビティとして出てきません。"Desktop Recording"を使うと出てきます。同じアプリケーション、同じウィンドウタイトルのウィンドウが複数並ぶ場合はDesktop Recordingを使い、明示的にWindowを指定する必要があります。
③Type intoアクティビティでEmailアドレスを入力します。
④Type intoアクティビティで従業員番号(Employee number)を入力します。
⑤"Create Expense Report"ボタンをクリックします
-
"Screen scraping"アクティビティ
- "Screen scraping"アクティビティはRecording機能により"Window Scope"アクティビティ、Sequenceアクティビティ、"Get Full Text"アクティビティの組み合わせとして自動で生成されます。
①"Screen scraping"の実体はSequenceアクティビティです。
②"Attach Window 'CreateExp Hwndwrapp'"はWindow Scopeアクティビティです。プロパティ"Selector"の詳細を見てみましょう。
Open ApplicationアクティビティでもSelectorを使用していますがtitleのみ"Create Expense Report"に変わっています。これは、実際にウィンドウタイトルが親画面と子画面で異なっているためです。(Open Applicationアクティビティでは"ExpenseIt Standalone"でした)
③Get Full Textアクティビティで画面上のテキスト文字を読み取ります。
実際には、以下の文字列が読み込まれます。システム 元のサイズに戻す(R) 移動(M) サイズ変更(S) 最小化(N) 最大化(X) 閉じる(C) Alt+F4 Email Alias: Email _Alias: Someone@example.com Employee Number: Employee _Number: 57304 Cost Center: _Cost Center: 4032 Add Expense Add _Expense View Chart Expense Type Description Amount Meal Mexican Lunch 12 Meal Italian Dinner 45 Education Developer Conference 90 Travel Taxi 70 Travel Hotel 60 Total Expenses ($): 277 OK _OK Cancel _Cancel
読み込まれた文字列はString変数"scrappedText"に格納されます。
IgnoreHiddenオプションは今回チェックされていませんが、チェックした場合は画面上表示されていない「システム」から「閉じる(C) Alt+F4」などは読み込まれません。
- "Screen scraping"アクティビティはRecording機能により"Window Scope"アクティビティ、Sequenceアクティビティ、"Get Full Text"アクティビティの組み合わせとして自動で生成されます。
-
AssignでString型の配列変数"lines"に読み取った結果を代入します。
lines = scrappedText.Split(separators,StringSplitOptions.RemoveEmptyEntries)
第一引数の"separators"は下のように変数定義され、改行コードが現れたらlinesの次の配列要素へと文字列を入れていきます。
StringSplitOptions.RemoveEmptyEntries は"空の文字列を格納している配列要素を含まない"ようにするためのオプションです。
-
もう一度読み取ったテキストデータを見てみましょう。
「システム」から始まり「Amount(下から4つ目)」までいったところでループが止まり、その位置の変数iが保持されます。ほしいデータは"Meal"以降です。
-
WhileでCSVデータを格納するDataTableを構築します。
1つの経費アイテムはExpense Type, Description, Amountの3項目で構成されているので"Add Data Row"アクティビティで、
{lines(i), lines(i+1), lines(i+2)}
をDataTable型のdtExpenses変数に追加していきます。1回目のループ、2回目のループではそれぞれ、Meal, Mexican Lunch, 12 Meal, Italian Dinner, 45 ...
がDataTableに追加されます。
ループ処理は"Total Expenses ($):"が出てくるまで3行単位で回ります。
-
"Write CSV"アクティビティででCSVファイルを出力します。
FilePathとして"Expenses.csv"が、入力DataTableとしてdtExpensesが指定されています。