はじめに
初めまして。UiPathの藤根(フジネ)です。
私は現在、RPAコンサルタントとしてUiPathで働いています。私の主な業務は、お客様先での導入・運用のサポートを行っています。
より現場に近い環境で働いた経験から、地味だけど知っておくと便利な内容を書いてみたいと思います。
今回のブログでは業務自動化を行う際に、使用頻度の最も高い(であろう)クリックアクティビティーについて解説します。
なお、本ブログはUiAutomation v19.5.0で検証を行っています。バージョンにより振る舞いが変わる可能性があるのでご了承ください。
最新の情報に関しては以下を参考ください。
https://activities.uipath.com/docs/click
クリックとダブルクリック
まずは、こちらを紹介します。
「クリック」アクティビティーの横には「ダブルクリック」アクティビティーがありますが、実はこれはこの「クリックの種類」というプロパティーの規定値が違うだけ(正確には表示名称も異なります)で実質的に同じものです。クリックの種類は以下の通り公式サイトに書かれています。
クリックの種類 (ClickType)
ClickType
クリックイベントのシミュレート時に使用するマウスクリックの種類 (シングル、ダブル、アップ、ダウン) を指定します。既定ではシングルクリックが選択されます。
自動化をするうえでほとんどが「シングル」か「ダブルクリック」が使われることが多いと思います。「ダウン」「アップ」のユースケースはあまり浮かびませんが・・・
こんなことを考えることは少ないと思いますが、
「ダウン」と「アップ」を組み合わせて「シングル」と相当に動かそうと思っても
「ダウン+アップ」と「シングル」は厳密には異なるので気をつけてください。
どんな違いが表れるかは対象システムによりけりですが、ちょっと例を挙げてみたいと思います。
WebアプリケーションでのJavaScriptの振る舞いを挙げてみます。
JavaScriptのAddEventLisnerしていた場合は以下のような違いがあります。
|
mousedown |
mouseup |
click |
シングル | 1回発火 | 1回発火 | 1回発火 |
ダブル |
2回発火 | 2回発火 | 2回発火 |
ダウン |
1回発火 | イベント発火 | イベント発火なし |
アップ |
イベント発火なし | 1回発火 | イベント発火なし |
注目すべき点は、「ダウン」+「アップ」を組み合わせても「クリック」イベントが呼ばれないということです。
対抗アプリケーションごとに最も適切なプロパティーを設定することおすすめします。
クリッピング領域 (ClippingRegion)
次はクリッピング領域について説明したいと思います。公式サイトには以下のように書かれています。
ClippingRegion
UiElement を基準とし、左、上、右、下の方向で、クリッピング四角形 (ピクセル単位) を定義します。正と負の両方の値をサポートしています。
これはクリッピング領域を指定したときに入る値です。
セレクターでエレメントを選ぶときに、F3を押すと領域を指定して選ぶことができます。
この領域の中心を押すような動きになります。
例えば、うえの赤枠をクリッピング領域として指定した場合に、真ん中のカーソルが当たっている箇所をクリックするように動作します。
WaitForReady
自動化をするうえで重要な要素の一つが、このプロパティです。これは頻繁に質問されるプロパティです。
公式サイトには次のように書かれています。
WaitForReady
アクションを実行する前に、ターゲットが準備完了になるまで待ちます。
私たち人間はクリックするときに、無意識のうちに自然とボタンが表示されて押せる状態になってから操作します。
まだ画面がでないうちにクリックをするなんてことは通常ありません。一方ロボットはそうではありません。
Element要素をクリックするときに、ロボットに適切なタイミングを指定するプロパティがこのWait for readyです。
ここをうまく調整してあげないと、クリックうまくいかない(空振りする など)場合があります。
以下のオプションを必要に応じて使い分けて下さい。
こちらもWebサイト上には詳しく書かれていますが、ざっくりイメージをつけるために表に書いてみます。
Web(IE) | デスクトップアプリケーション | SAP | |
None | 何も待ちません | ||
Interactive | 対象エレメントが読み込まれるまで待ちます | WindowsMessageのwm_nullの応答があるまで待ちます(※1) | 専用のAPIを使用して実行状態になるまで待ちます |
Complete | 対象ページが全て読み込まれるまで待ちます |
表から見てわかるように、「Interactive」と「Complete」の違いがあるのはWebのみです。これはInternet Explorerのready stateを参照してください。
https://docs.microsoft.com/en-us/previous-versions/bb268229(v%3Dvs.85)
現場でよく勘違いされるのは注釈の(※1)に関してです。プロパティ名だけ見ると、アプリケーションの待機状態を待つように思えますが、そうとも限りません。
WindowMessageを送信し応答があれば実行をします。という意味ですが、これは対象アプリがハングアップ状態のときは待ちますという意味です。つまりアプリケーションが独自で待機状態(くるくる表示、スプラッシュ画面など)を表現をしていてもUiPathからすれば実行可能と判断してしまいます。人間なら、アプリケーションの待機表示があればクリックをしないはずですが、ロボットは容赦なくクリックします。
自動化対象の業務で待機状態があるときは、「On Element Appear」などを使ってタイミングを調整してみてください。
CursorPositionオプション
公式サイトには以下のように書かれています。こちらに関しても具体的な例を出して理解を深めていきたいと思います。
CursorPosition.OffsetX
Position フィールドで選択したオプションに従って生じるカーソル位置の水平方向の変位です。
CursorPosition.OffsetY
CursorPosition.Position
これらのパラメータを合成した箇所にクリックをするように動きます。
Position |
OffsetX |
OffsetY |
クリック位置 |
Center |
0 |
0 |
真ん中 |
TopLeft |
0 |
10 |
左上から10ピクセル下方向 |
BottomRight |
-20 |
0 |
右下から-20ピクセル右方向(20ピクセル左方向) |
デフォルト/SendWindowMessages/SimulateClick オプション
Clickアクティビティーを使用する上で、一番意識をするオプションだと思います。
基本的な考え方は以下です。
デフォルト | ドライバーを経由してマウス操作を実行 |
---|---|
SendwindowsMessage | Windows Messageを使用してマウス操作を実行 |
SimulateType |
APIを呼び出しマウス操作を実行 |
これらクリックの種類について具体的に何が違うのか?
残念ながら内部的な話はできませんが、デバックツールを使って紹介したいと思います。
今回検証に使うのは、とある業界で有名なアプリケーションを使います。画像の赤枠部分のクリックをしたときの動作を検証してみたいと思います。
今回はSpy++というツールを使って調べてみたいと思います。
https://docs.microsoft.com/en-us/visualstudio/debugger/using-spy-increment?view=vs-2019
このツールを使かうと、Windowsの内部メッセージをキャプチャーすることができます。
すべてのメッセージを出すと大量にログが出るので、今回はクリックに関するログだけ出してみます。なお、検出したログは全て載せています。赤色の箇所がクリックそのものをしているメッセージの箇所です。
「デフォルト」「SendWindowMessages」「SimulateClick」それぞれの違いを確かめてみることにします。
デフォルト
log
<000001> 00120B52 S WM_SETCURSOR hwnd:00120B52 nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000002> 00120B52 R WM_SETCURSOR fHaltProcessing:False
<000003> 00120B52 P WM_MOUSEMOVE fwKeys:0000 xPos:37 yPos:10
<000004> 00120B52 S WM_MOUSEACTIVATE hwndTopLevel:00020F28 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<000005> 00120B52 R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000006> 00120B52 S WM_SETCURSOR hwnd:00120B52 nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<000007> 00120B52 R WM_SETCURSOR fHaltProcessing:False
<000008> 00120B52 P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:37 yPos:10
<000009> 00120B52 P WM_LBUTTONUP fwKeys:0000 xPos:37 yPos:10
<000010> 00120B52 S WM_SETCURSOR hwnd:00120B52 nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000011> 00120B52 R WM_SETCURSOR fHaltProcessing:False
<000012> 00120B52 P WM_MOUSEMOVE fwKeys:0000 xPos:37 yPos:10
<000013> 00120B52 P WM_MOUSEHOVER
<000014> 00120B52 P WM_MOUSELEAVE
なんだか色々出ています。
SendWindowMessages
log
<000001> 00120B52 P WM_MOUSEMOVE fwKeys:0000 xPos:37 yPos:10
<000002> 00120B52 P WM_MOUSELEAVE
<000003> 00120B52 P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:37 yPos:10
<000004> 00120B52 P WM_LBUTTONUP fwKeys:0000 xPos:37 yPos:10
ずいぶんすっきりしているイメージですね。
SimulateClick
log
なんと、何も出ていません!でもクリックは出来ています。
ちなみに人が操作すると「デフォルト」に近い形で出てきます。このように根本的に違いがあるんですね。
なお「デフォルト」はマウス操作が奪われてしまうのでrobot実行中にユーザーがマウス操作しようとすると意図せぬ動作をすることがあります。
総合的には早くてマウス操作が奪われない「SimulateClick」をおススメします。
どのクリックが効くかどうかは相手のアプリによりけりなので、どれがベストとは言えませんが根本的に違いがあるということをわかっていただければ幸いです。
一番よい組み合わせをシステムごとに試してみてください。