#Sample - 19.2 - コンテキスト対応のアンカー

今回のトピックで紹介する新アクティビティは、「コンテキスト対応のアンカー」アクティビティです。クラス名は、UiPath.Core.Activities.AnchorContextAware です。初登場は、さかのぼること、2019.2 リリースです。それからもう1年経ってしまいました。光陰矢の如し、ですね。ということで、「新」という冠に少し無理がありますか? :sweat_smile:

ガイドはこちら

ところで、コンテキスト対応のアンカー登場以前から、我々には「アンカーベース」という同じ種類のアクティビティがあります。ご存じとは思いますが、アンカーベース、現役でがんばっております。まだ引退していません。

新旧アクティビティの使用用途は同じです。ある UI 要素を対象とするアクション(クリックや文字を入力、テキストを取得したり、設定したりする、など)を行いたいけど、その UI 要素のセレクターをうまく選べない場合があります。うまく選べない理由はさまざまです。複数の異なる UI 要素が同じセレクターを生成したり、クラス名やタイトル名などウィンドウの特徴量が実行時に変わってしまったり、などです。そのような場合に、セレクターをうまく選べる別の UI 要素を見つけて、相対的な位置関係からアクション対象の UI 要素を特定させる場合に使用します。

使用用途が同じなためか、両者ともデザインパネルに配置した場合の外見も似ています。


が新アクティビティの外見(ヒントのテキストが英語なのはご愛敬)で、


が旧アクティビティの外見です。

ご覧の通り、アンカーと呼ぶアクティビティとアクションと呼ぶアクティビティを置く場所があります。

アンカーは、基準となる UI 要素を特定するアクティビティです。アンカーの和訳は錨【いかり】ですが、野外でキャンプするときにテントを固定するアンカーをイメージしたほうが分かり易い(個人差はあり)かもしれません。(ちなみにアンガーと濁っても和訳は怒り【いかり】です :grin:

アンカーとして配置できるアクティビティの条件は、UiPath.Core.UiElement クラスのオブジェクトを返すアクティビティであることです。UI Automation アクティビティパッケージにおいては、

  • 相対要素を探す(FindRelative クラス)
  • テキスト位置を探す(FindText クラス)
  • OCRでテキスト位置を探す(FindOCRText クラス)
  • 親要素を取得(GetAncestor クラス)
  • 画面上で指定(IndicateOnScreen クラス)
  • 画像を探す(WaitImageAppear クラス)
  • 要素を探す(WaitUiElementAppear クラス)
    (クラスの名前空間は UiPath.Core.Activities、コンピュータービジョン系アクティビティは省略)

が UiPath.Core.UiElement クラスのオブジェクトを返すアクティビティです。やはり一般的には要素を探すアクティビティを使用する場面が多いと思います。

また、アクションは、アンカーで特定した UI 要素を基準にターゲットの UI 要素を特定し、操作を行うアクティビティです。アクションとして配置できるアクティビティは、操作対象の UI 要素を取り扱うために UiPath.Core.Activities.Target クラスをプロパティに持つアクティビティです。クリックや文字を入力など、UI 自動化を行う多くのアクティビティが該当しますので、一覧は省略します。

さて、新旧アクティビティ、両者の違いは何でしょうか?

コンテキスト対応のアンカーアクティビティは、デザイン時にアンカーアクティビティとアクションアクティビティそれぞれの対象 UI 要素の矩形部分の座標(Left, Top, Right, Bottom)を記録するところに特徴があります。


アンカー境界ボックスプロパティそしてターゲット境界ボックスプロパティに格納されるこれらの座標については、コンテキスト対応のアンカーアクティビティに配置したそれぞれのアクティビティにて「画面上で指定」により UI 要素を選択すると自動で記録されます。手入力は不要です。

コンテキスト対応のアンカーアクティビティは、実行時に座標情報から計算した相対的な位置と大きさを考慮して、アンカーの UI 要素を基準に最も近似している UI 要素をターゲットの UI 要素として選抜して、アクションアクティビティを実行します。したがって、実行時に検出した UI 要素の位置や大きさがデザイン時のものと完全に同じである必要はありません。多少の違いには柔軟に対応できます。

一方、アンカーベースアクティビティは、アンカーの UI 要素を基準とするところは同じですが、アンカー位置と呼ばれるプロパティによりアクションアクティビティのターゲット UI 要素から見たアンカー UI 要素の方位(Top、Left、Right、Bottom など)を指定するところに特徴があります。


アンカーベースアクティビティにおけるターゲットの UI 要素の選抜方法は、次のように考えると理解しやすいと思います。

まず、アンカー位置と同じ方向(アンカー位置が Top または Bottom の場合は垂直方向、Left または Right の場合は水平方向)に着目して、アンカー位置の条件に合致する位置関係にある UI 要素を対象にアンカーの UI 要素との距離が最も小さい UI 要素を候補として選抜します。そして、選抜された UI 要素を対象に今度は直行する方向(アンカー位置が Top または Bottom の場合は水平方向、Left または Right の場合は垂直方向)に着目して、アンカーの UI 要素との距離が最も小さい UI 要素を候補として選抜します。この時点で候補がひとつに絞れない場合に、アンカー位置が垂直方向(Top または Bottom)なら左側に位置する UI 要素が選抜され、アンカー位置が水平方向(Left または Right)なら上側に位置する UI 要素が選抜され、アクションアクティビティが実行されます。

このようにアンカーベースアクティビティはターゲットの UI 要素を選抜するため、UI のレイアウトの条件によっては意図したとおりに動いてくれない場合があります。それを説明するために次のウェブブラウザー上の DIV 要素を例に考えます。


この例において、中心の A1 をアンカーの UI 要素として特定できる場合に、その直下の DIV 要素(いまは X8 が表示されている部分)に対してアクションを起こしたいとします。A1 以外の DIV 要素にはセレクターを唯一に決定できる特徴量がないものとします。

アンカーベースアクティビティに要素を探すアクティビティをアンカーとして配置し、A1 を画面上で指定してセレクターを取得します。次に任意のアクティビティをアクションとして配置し、X8 を画面上で指定してセレクターを取得します。そしてアンカーベースアクティビティのアンカー位置プロパティを Top に設定し、実行します。すると、アクションは X7 の DIV 要素に対して実行されます。その理由は次のとおりです。X7 と X8 の DIV 要素は A1 と垂直方向の距離が同じで、X7 の右辺と X8 の左辺は A1 の左辺と水平方向の距離が同じなため、最終的に左側に位置する X7 の DIV 要素が選ばれるからです。

コンテキスト対応のアンカーアクティビティは、このアンカーベースアクティビティの弱点を補う側面があります。前述の例に対して、コンテキスト対応のアンカーアクティビティでアンカーとターゲットの UI 要素として A1 と X8 の DIV 要素を画面上で指定すれば、ワークフロー実行時に意図したとおり X8 の DIV 要素に対してアクションを実行してくれます。多少のレイアウトのずれが生じても、X8 の DIV 要素が選択されるので安心です。

ということで、以上で説明は終わりですが、最後にどちらのアクティビティを使うべきか、という点について。コンテキスト対応のアンカーアクティビティは、意図する UI 要素を確実に捉えられることができる反面、極端なサイズ変更を伴うレイアウト変更に対応できない場合があります。もしレイアウト変更があっても UI 要素相互の位置関係が相似関係にある場合はアンカーベースアクティビティを試す価値ありです。また逆に、アンカーベースアクティビティも使用できる場面は少なくはないので、両者を適宜使い分けするのがスマートな方法かもしれません。 :vulcan_salute:

検証用ワークフローサンプル:AnchorTest_20200303.zip (19.7 KB)

5 Likes