RPAツールであるUiPathについてのメモ書きです。
私はプログラミングは素人ですので、初歩的な内容も記載しており、中には間違った情報もある可能性があることご了承ください。言語はVB.NET、使用ツールはUiPath Studioです。
・新規のプロジェクトを作成する場合は、基本的にフローチャートにすれば良いと思います。シーケンスはフローチャートの中に置きます。
・UiPath Studioの「ファイルを実行」では、現在のファイルを実行。「実行」の場合は、プロジェクトが実行されます。デバッグは動作確認に使用し、動作は遅くなります。
・「実行(プロジェクトを実行)」では、初期設定では「Main.xaml」ファイルが実行されます。「ワークフローファイルを呼び出し(invoke workflow)」アクティビティで、xamlファイルから他のxamlファイルを呼び出し実行できます。初めに実行されるファイルから他のxamlファイルをこれによって呼び出すのが通常です。
・UiPathのプロセスを多重実行したい場合は、テンプレートの「バックグラウンドプロセス」で作成したものが可能。これはUI操作アクティビティが除かれています。つまり、UI操作が含まれるプロセスは一つしか実行できない仕様です。
・変数の型を指定する際、既定のリストに無い型については参照リストから選択します。私が良く使う型としては、List、Datetime、TimeSpan、Double、Browser、UiElement、DataTableなど。参照リストでこれらの型名を検索できます。.NETの型の場合(この例ではList, DateTime, TimeSpan, Double, DataTable)は、ネットで「.net 型名」で検索し、名前空間を把握しておけば参照リストから正確に選択できます。例えばListの場合は、「System.Collections.Generic」が名前空間なので、参照リストの中のこの項目下(mscorlib→System.Collections.Generic)にあるList<T>が該当します。BrowserやUiElementなどはUiPathの型であり、その場合は、参照リストの中でUiPathの文字がある項目内から型名を探します。ListやArray、Dictionaryなどについては、中身の型も選択します。また、変数はアクティビティ内の所定の欄で「Ctrl+K」で作成することもでき、その場合は初めから適当な型になっています(コレクション型を指定する欄ではICollectionが設定されるがListに変えたりはしている)。
・List型の場合、変数を設定した時に規定値として「New List(of 型名)」と入力することで使えるようになります(代入でも良い)。型名には、Listの中身の型名を入れます。初期値として予め要素を入れる場合は、後に続けて「from {リスト内容}」と記述します。例えばString型の要素を持つListの場合、「New List(of String) from{"aa","bb","cc"}」などとします。
・変数のスコープは、出来るだけ狭い範囲にします。ファイル全体をスコープにする変数(グローバル変数)は少なくした方が管理しやすいです。
・VB.NETのコードでは、大文字と小文字を区別しません。
・良く使う型変換について
a変数を変換するとして
文字列に変換・・・a.ToString
整数型(Int32)に変換・・・CInt(a)
浮動小数点数型(Double)・・・CDbl(a)
真偽値(Boolean)・・・CBool(a)
日付型(DateTime)・・・CDate(a)
CIntでは、小数点以下が四捨五入ではなく銀行丸めになります。四捨五入をする場合はmath.round(a, 少数部に残す桁数, MidpointRounding.AwayFromZero)を使います。Double型では、小数部のある数値を扱いますが、日常使う10進法の数値を表すには精度が完全では無い場合があるため、10進法数値の正確な計算が必要な部分ではDecimal型を使います(計算速度は遅くなる)。
・ExcelファイルやCSVファイルなどから「範囲を読み込み」や「CSVを読み込み」で取得したデータテーブルの各項目はオブジェクト型となっているため、元々の型(文字列や数値など)として利用したい場合は型変換を行う必要があります。
・レコーディング機能について
レコーディング機能を利用すると、いちいち自分でアクティビティを配置しないので楽ですが、自動で生成されたセレクターの内容は適宜変える必要があります。
ベーシック・・・アクティビティごとに完全セレクターを生成する。コンテナを使用せず、アクティビティを配置する。
デスクトップ・・・コンテナを作り、その中にアクティビティを配置する。それらのアクティビティは部分セレクターを持つ。
WEB・・・ブラウザ内の操作のみを対象とする。ブラウザコンテナを生成する。
コンテナとは・・・「ウィンドウにアタッチ」「ブラウザーにアタッチ」「アプリケーションを開く」「ブラウザを開く」などで生成されます。指定した「ウィンドウ」または「ブラウザ」内で、複数の操作を行うためのもの。
一つのウィンドウまたはブラウザ内で複数の操作をする場合はコンテナを生成したほうが便利かと思います。また、ウィンドウやブラウザコンテナは、全く同一のセレクターのものが複数あったとしても識別できる利点もあります。
例えば、コンテナ内に配置しないアクティビティの場合、セレクターのみで操作対象を判別します。この時、全く同一のセレクターを持つ要素が複数あった場合は、どちらを操作対象とするかが不安定です(一番最近アクティブになった方を操作対象とすると思われます)。
それに対してコンテナの場合は、コンテナ要素を一度指定してしまえば、他に同一のセレクターを持つ要素があっても指定したコンテナを識別できます。コンテナを指定する時は、目当てのコンテナを指定できるように工夫する必要がありますが、一度指定しまえば他の同一セレクターを持つウィンドウやブラウザーと混同されることはありません。つまり、コンテナの生成は、確実に特定のコンテナ内で操作を行いたいという目的に適しています。
また、ブラウザコンテナの場合は、一度ブラウザを指定しまえばURLが変わって当初のセレクターから変わっても同じブラウザ内で操作を実行できます(ウィンドウコンテナについては未確認)。
速度を検証しましたが、一つのコンテナ内で部分セレクターを持つアクティビティを複数配置する場合と、コンテナを作らずアクティビティを配置する場合とでは私が試した限りでは誤差の範囲でした。
・セレクターについて
セレクターはUI要素を特定するためのものです。トップレベルのセレクター要素(<wnd>や<html>)と、その下のセレクター要素に分けられます。完全セレクターにはトップレベルが含まれ、部分セレクターには含まれません。コンテナは、トップレベルのセレクター要素を持ち、コンテナ内に配置されるアクティビティは部分セレクターを持ちます。ただし、コンテナ内に配置されるアクティビティに完全セレクターを持たせることも出来ます。その場合は、アクティビティを実行してもコンテナ内に要素が見つからなかった場合、コンテナ外で同一のセレクター要素がある場合に操作対象とするようです。
自動で生成されるセレクターは必ずしも適切なもので無い場合も多いため、適宜変える必要があります。それはUI Exploreで行います。セレクターには信頼性の違いがあり、できるだけ信頼性の高いものを指定することが大事です。詳細はhttps://docs.uipath.com/studio/lang-ja/docs/about-selectors
セレクターにはワイルドカードや変数が使用できます。ワイルドカードとは、例えば「*」を使用することで、0文字以上の任意の文字を表すことができます。変化する文字列を*で置き換えることで対応できます。変数を使用する場合は、例えば以下のようにします。
以下はメモ帳のセレクターです。
"<wnd app='notepad.exe' cls='Notepad' title='無題 - メモ帳' />"
このタイトルに変数を入れたい場合、
"<wnd app='notepad.exe' cls='Notepad' title='"+変数名+" - メモ帳' />"
のようにします。
セレクターは文字列ですので「"(ダブルクォーテーション)」で囲い、それに変数を&か+で連結します。
これはアクティビティのプロパティパネルから行った方が良いと思います。セレクターエディターやUIExploreではセレクター文字列は"で囲まれていない表示となっています。また、変数を入れると、セレクターエディターやUIExploreが使えません。
また、セレクター内の特定の文字についてはエスケープ文字を使用する必要がありますが、自動で要素を検出した場合は自動でエスケープ文字が使用されています。
・要素を見つける際の挙動
UI操作アクティビティは設定されたセレクターに基づいて要素を見つけようとしますが、その際の挙動について記します。
完全セレクターを持つアクティビティに関しては、まずトップレベル(最上階層)のセレクター要素を見つけようとします。見つかった後、その中で下層のセレクター要素を見つけようとします。つまり、初めにトップレベルセレクターが合致したウィンドウやウェブページの中で、目的の要素を探そうとします。
トップレベルのセレクター要素に当てはまるものが複数ある場合(例えば、同じタイトルのウェブページが複数開かれており、セレクターにそのタイトル名しか指定されていない場合)、そのうちの一つの中でしか最終目的の要素を探そうとしません。この例で言うと、同一タイトルの複数のウェブページの中のどれかにのみ最終目標の要素が存在する場合は、要素を見つけられない可能性があります。これを避けるには、コンテナを使用したり、探す対象のウィンドウやウェブページを予めアクティブにしておくこと等が考えられます。「アクティベート」アクティビティでは、指定の要素をアクティブにできます。
ただし、ブラウザ操作のページ推移前後では、前のページで要素を探していてもページが切り替われば新しいページで要素の探査を継続するようです。
「要素を探す」アクティビティで見つけた要素をUiElement変数に入れた場合は、そのUI要素は無条件で識別されます(一度指定したコンテナが無条件で識別されるのと同様)。同一セレクター要素が他にあっても、同一のトップレベルセレクター要素が他にあっても識別されます。
・ブラウザ操作について
UiPathではIE、Chrome、FireFox、Edgeが操作できます。IEはデフォルトで操作できますが、その他のブラウザにはブラウザ拡張を入れる必要があります。UiPath Studioの「ツール」からインストールできます。
ただし、IEのUI操作が最も安定しています。ChromeやFireFoxは、ブラウザとして認識せずにUI操作が出来ない時があります。その場合は一度ブラウザを「ウィンドウを閉じる」で閉じたり、ブラウザ自体をtaskkillコマンドで強制終了(コマンドプロンプトで「taskkill /IM chrome.exe /F」)したりした後に再起動することで直ることがあります。
または、予めブラウザに複数のプロファイルを設定しておき、それぞれにブラウザ拡張をインストールしておき、どれかが失敗したら別のプロファイルで試すということも可能かと思います。ただしChromeは複数のプロファイルが起動した状態では初めに起動したプロファイルでしかUI操作は出来ない仕様です。
Edgeに関しては最も不安定かと思われます。私の環境では認識できませんでした。
このようにIEが一番UI操作は安定していますが、ブラウザ自体のパフォーマンスはChromeやFireFoxなどのほうが上かと思います。
独自にブラウザごとのUI操作の速度検証をしたのですが、速い順にIE、Chrome、FireFoxとなりました。
ブラウザを開く時は通常、「ブラウザーを開く」アクティビティを使用します。プロファイルを指定したりシークレットウィンドウを開いたりなどの設定を付加する場合は、「プロセスを開始」で引数を渡します。
「ブラウザーを開く」でのプロパティについて説明します。「新しいセッション」は、IEのみで有効な設定で、新しいセッションでページを開きます。ただしWindows10でそれが動作するかどうかは未確認です。新しいセッションを使用すると、複数のユーザーで同じサイトにログインできたりします。通常は必要ないかと思います。また、UiPath.UIAutomation.Activities 19.10.1の段階では「新しいセッション」の項目のFalseとTrueが逆になっているバグがあります。Trueにしたい場合はFalseにしてください。デフォルトではFalse(表示上のTrue)です。chromeやfirefoxで新しいセッションを利用する場合は、別のプロファイルを作ればそれが別セッションとなります。また、FireFoxの場合は「Multi-Account Containers」というアドオンも利用できます。プライベートウィンドウ(シークレットウィンドウ)も別セッションとなります。
「通信方法」は、通常はそのままで良いです。既定ではネイティブです。WebDriverは、WebDriverをインストールすることで使用可能になります。しかし、私の検証した限りではWebDriverは非常に遅いです。WebDriverの特徴としては、ヘッドレス(非表示)で実行できる点です。ヘッドレスでも遅いことに変わりはありません。
「非表示」は、IEのみで有効な設定で、ヘッドレスと同じ意味かと思います(詳しくは分かりません)。ただし特定のUI操作が伴うと非表示は解除されます。
・速度について
アクティビティは一連の連続処理の初回呼び出しの時は時間がかかります。なので、プログラムの処理速度を計測する時にはそれを考慮する必要があります。一定時間内でなるべく速く処理をするプログラムを作る場合、本番直前にそれぞれのアクティビティを使用しておくと良いと思います。ただし前回の呼び出しから時間が経つとまた次回の呼び出しに時間がかかるようになるようです。
UiPath.UIAutomation.Activitiesのバージョンが新しくなるに連れ、機能性が強化されバグ修正が行われますが、私が実験した限りではパフォーマンス(速度)が低下するようです。
「要素を探す」「クリック(シミュレート)」をブラウザ上で繰り返し速度測定しました。19.10.1よりも21.10.4が遅く、更に22.10.2が遅いという結果になりました。
・バグと思われるもの(UiPath.System.Activities 19.10.1)について
①「" "」という形でのスペース文字列のみを代入アクティビティで代入するとエラーになるので、「space(1)」を代入しています。
②Integer.TryParse()の第二引数に変換結果が入りません。