<img src="//trc.taboola.com/1222697/log/3/unip?en=page_view" width="0" height="0" style="display:none">

ナレッジベース

ユーザーインターフェースに表示されるテキストのサーチ処理

はじめに

UiPath は、UI Automation アクティビティパッケージでいくつかのテキスト関連アクティビティを提供しています。

テキスト関連アクティビティは、ドライバーと呼ばれるコンポーネントが提供する機能を使ってアプリケーションのユーザーインターフェース(UI)から表示する(描画する)テキスト情報を取得し、処理を行います。

バージョン 18.4 からドライバーコンポーネントは、アプリケーションの UI からテキストをサーチする場合、アプリケーションにおけるテキストの描画方法の違いにより、異なる処理を行うようになりました。

本記事では、それがどのように異なるかについて考察します。

 

テキストの描画

Windows オペレーティングシステムには、Graphics Device Interface(GDI)と呼ばれるディスプレイ画面やプリンタなどのグラフィックス装置への描画 API があります。アプリケーションは、ウィンドウにテキストを描画する場合も、最終的には GDI の提供する API を使って行うことになります。

 

GDI は、ウィンドウにテキストを描画するために、簡易に描画できるものから詳細に描画できるものまで、いくつかの API を提供しています。

 

簡易な API(例えば TextOut)を使うと、描画したい位置情報とともに描画したい文字列を渡すだけで、デバイスコンテキストに設定されているフォントを使って簡単にテキストを描画することができます。

 

一方で詳細な API(例えば ExtTextOut)を使うと、オプションの指定(ETO_GLYPH_INDEX)により、文字列の代わりに描画したい個々の文字に関するグリフ(文字のイメージ)の情報を渡してテキストを描画できます。あらかじめ、GetCharacterPlacement API に描画したい文字列を渡して、言語に関する処理(ダイアクリティクス:ラテン文字のアクセント記号、リガチャ:ラテン文字の複数文字の接合、描画の順番、等)を行って、テキスト描画を細かく制御するという方法です。

 

テキストのサーチ

UiPath のドライバーコンポーネントがアプリケーションの UI からテキストをサーチする場合、通常の文字列から描画されたテキストについては、オリジナルの文字列についてマッチングを行っています。

 

一方、アプリケーション(が呼び出した上位レベルの API、例えば DrawText)により ETO_GLYPH_INDEX オプションを指定してグリフの情報をもとに描画されたテキストについては、UNICODE の正規化処理を施した文字列を使ってマッチングを行うようになりました。この方式は、バージョン 18.4 から採用されています。サーチするテキストもサーチされるテキストも同じルールのもと UNICODE 正規化された文字列でマッチングが行われます。

 

UNICODE 正規化を行うようになった理由は、グリフの情報の非可逆性にあります。つまり、グリフの情報から描画テキストの情報に変換する際に UNICODE に特徴的な結合文字列(基底文字に部品となる結合文字を連結して論理的な1文字を形成する文字列)に複数のバリエーション(例:「Ḗ」U+1E16 は結合文字を使うと別に二つのバリエーションがあります:U+0045 U+0304 U+0301 と U+0112 U+0301)ができてしまうため、オリジナルの文字列を使ったマッチングがうまくいかない場合があるからです。UNICODE 正規化した文字列同士をマッチングすることによりそのようなバリエーションをなくす意図をもって導入されました。一般的な効用としても、UNICODE 正規化はサーチするテキストについてバリエーションを考えなくてもよいという点が挙げられます。

 

なお、ビジネスアプリケーションの多くは、通常の文字列からテキストを描画しています。また、サーチ対象の文字列として完全一致を想定した文字列を指定すれば、特別に UNICODE 正規化処理を考慮する必要はありません。しかし、エクスプローラーを含む Windows オペレーティングシステムに標準で付属するアプリケーションは多言語化対応が正しく行われており、そのようなアプリケーションは(呼び出された上位レベルの API により) ETO_GLYPH_INDEX オプションを指定してテキストが描画されていることがあるため、場合によっては末尾処理で注意する必要があります。その例については後述します。

 

影響を受けるテキスト関連アクティビティ

UI Automation アクティビティパッケージで UNICODE の正規化処理の影響を受けるテキスト関連アクティビティは次のとおりです。

  • テキストをクリック(Click Text)アクティビティ
  • テキスト位置を探す(Find Text Position)アクティビティ
  • テキスト上でホバー(Hover Text)アクティビティ
  • テキストの有無を確認(Text Exists)アクティビティ

 

UNICODE 正規化処理の詳細

UiPath のドライバーコンポーネントが行っている UNICODE 正規化は、Win32(NLS) API の NormalizationKC オプションで説明される正規化処理になります。

 

ラテン文字の正規化

  • NormalizationKC オプションによる Basic Latin(基本ラテン文字、US-ASCII 相当)、Latin-1 Supplement(ラテン1補助)、および Latin Extended(拡張ラテン文字)の正規化処理については、次の特徴があります。
  • US-ASCII のアルファベット、数字、記号はそのままです。
  • ダイアクリティクス付きラテン文字はそのままです。
    例:「Ü」(オリジナル)→「Ü」(正規化後)
  • US-ASCII のアルファベットに続くダイアクリティカルな文字との複数文字の並びは、ダイアクリティクス付きの文字1文字に変換されます。
    例:「U」+「̈」(オリジナル)→「Ü」(正規化後)
  • 単独のリガチャー文字は、US-ASCII の相当する複数のアルファベットに変換されます。
    例:「fi」(オリジナル)→「f」+「i」(正規化後)
  • そのほか、特殊な空白文字は半角(US-ASCII)の空白文字に変換されます。
    例:U+00A0 NO-BREAK SPACE(オリジナル)→U+0020 SPACE(正規化後)

 

日本語文字の正規化

NormalizationKC オプションによる日本語文字の正規化処理については、次の特徴があります。

  • 全角漢字、全角ひらがな、全角カタカナはそのままです。
  • 全角英数字は、US-ASCII の相当する英数字に変換されます。
    例:「A」(オリジナル)→「A」(正規化後)
  • 半角カタカナは、全角カタカナに変換されます。
    例:「ア」(オリジナル)→「ア」(正規化後)
  • 半角カタカナに続く半角の濁点および半濁点は、全角の濁点および半濁点付き文字1文字に変換されます。
    例:「ハ」+「゚」(オリジナル)→「パ」(正規化後)
  • 全角ひらがなおよび全角カタカナに続く濁点および半濁点は、全角の濁点および半濁点付き文字1文字に変換されます。
    例:「か」+「゛」(オリジナル)→「が」(正規化後)
  • 全角記号は、US-ASCIIの相当する記号に変換されます。相当するものがないものはそのままです。
    例:「.」全角ピリオド(オリジナル)→「.」ピリオド(正規化後)
  • そのほか、全角の空白文字は半角(US-ASCII)の空白文字に変換されます。

 

エクスプローラーの例

ユーザーインターフェースに表示されているテキストのサーチにおいて、UNICODE 正規化の処理が施される場合の例としてエクスプローラーの例を挙げます。

001_un_issue

 

エクスプローラーのファイル名の一覧(上図の黄色枠シャドーがかかった部分)からテキストをサーチしてクリックするワークフローを [テキストをクリック(Click Text)] アクティビティを使って作ります。

002_un_issue

 

ワークフローはここからダウンロードできます。

この例では、文字列「ガカ」(半角カタカナの「カ」に半角カタカナの濁点そして再び半角カタカナの「カ」)をサーチしています。

エクスプローラーには「ガガ」(半角カタカナの「カ」に半角カタカナの濁点そして半角カタカナの「カ」に半角カタカナの濁点)が表示されています。

 

バージョン2018.3以下の挙動

バージョン2018.3以下を使うとオリジナルの文字列での比較となるため、先頭から3文字がマッチするため、このテキストをクリックすることができます。

 

バージョン2018.4以上の挙動

ところが、バージョン2018.4以上を使うと、このウィンドウのテキストについては、UNICODE 正規化の処理が施されたのちに文字列マッチングとなります。

サーチする文字列は UNICODE 正規化されて「ガカ」(全角カタカナの「ガ」に全角カタカナの「カ」の2文字)となります。

サーチされる文字列は UNICODE 正規化されて「ガガ」(全角カタカナの「ガ」に同じく全角カタカナの「ガ」の2文字)となります。

どちらも2文字となりますが、2文字目がマッチしないため、テキストが見つからないという結果になり、例外が発生します。

 

バージョン2018.4以上の注意点

このように、バージョン2018.4以上を使ってマッチすべきところがマッチしない場合は、注意が必要です。

特に日本語を含む文字列をサーチする場合、対策としては次のとおりです。

  • 半角カタカナの濁点や半濁点を含む(可能性のある)文字列を部分マッチさせる場合は、サーチする文字列の末尾の文字に着目して、濁点、半濁点を付け足して、あるいは、濁点、半濁点付き文字に置換して、繰り返しサーチすることも考慮してください。
  • 半角カタカナと全角カタカナを区別したい場合、あるいは、半角英数字(US-ASCII)と全角英数字を区別したい場合でも、それらは UNICODE 正規化によって同一視されます。したがって、サーチが成功つまりマッチする場合に、念のため [フルテキストを取得(Get Full Text)] アクティビティを使ってすべてのテキストを取り出してもう一度直接マッチングを行う必要があることも考慮してください。

 

おわりに

お使いのアプリケーションがテキスト描画に ETO_GLYPH_INDEX オプションを指定して行っているかどうか(上位レベル API が内部で同オプションを使う下位レベル API を呼び出すか否か)については、アプリケーションのユーザーが知ることは極めて難しいと考えます。また、通常のビジネスアプリケーションにおいてよく見られるラベルやボタンは、ETO_GLYPH_INDEX オプションを指定してテキストが描画されることは稀でしょう。それらの現状を考えると、ワークフローにて UNICODE の正規化処理を意識する必要性は限定的であると言えます。つまり、オリジナルの文字列をサーチする従来の方法を踏襲すれば問題ないと考えます。それでも、サーチ対象の文字列の末尾で特徴的なパターンが見られる場合かつ意図しない挙動が見られる場合は、本記事を参考にして処理を工夫することで対応してください。