LoginSignup
1
1

【UiPath】フルリモのお供。マウスを動かし続けるロボット(改良)

Posted at

皆もすなるQiitaといふものを、儂もしてみむとてするなり。

と言う訳で、こん**は!はなっち!です。

この記事はUiPathブログ発信チャレンジ2023サマーの24日目の記事です。

【初めに】
 UiPathブログ発信チャレンジ2023サマーの3日目の記事で、【UiPath】フルリモのお供。マウスを動かし続けるロボットを書きました。

その後、実際に使ってみると、じっとしている分には申し分ないのですが、例えばPowerPointを作成中で、右下にあるObjectを右上に移動しようとすると、勝手にマウスが動いてしまって、アタフタしてしまう事が多々ありました。

本来はスクリーンセーバーが起動するのを抑止しようという目的で作成したものでしたが、このままだと別のイライラが募るばかり...

今回は、その後の対応策をまとめてみました。


1)移動させるマウス位置を固定にしなければいい!

前回の記事では、

最初のカーソルの位置は(X,Y)=(200,400)としました。次は (X,Y)=(X+α,Y+α) α=1 とすると、いずれは画面サイズを超えたところにカーソル位置を持っていくことになります。

スクリーンセーバーが起動されなければ、カーソル位置を常に新しい場所にする必要はなく、最低2点あれば十分ですので。int32型配列として保持する事にしました。
image.png

と、Int32型配列に、固定値として設定していました。

※今気が付いた。座標の話と張り込んだ画像がマッチしていないですね(^^♪

ここの固定値現在のマウスの位置に変更し、マウスを動かす先は現在のマウスの位置を基に +1 したポイントにする事にしました。


2)現在のマウスの位置をどう取得するのか?

UiPathアクティビティから、MOUSEで検索すると...

ちょっと該当するアクティビティはなさそうです。

となると、.NETの機能を利用するのが手っ取り早いですね。得た結果が、以下の式でした。

'マウスポインタの位置を取得する
'X座標を取得する
Dim x As Integer = System.Windows.Forms.Cursor.Position.X
'Y座標を取得する
Dim y As Integer = System.Windows.Forms.Cursor.Position.Y

確認のため、「メッセージボックス」アクティビティで、マウスの位置を表示させてみましょう。
〔設定内容〕
image.png
image.png
〔実行#1〕
UiPath Studioの「現在のファイルを実行アイコン」の中ほどにマウスを置き、実行!(下図では赤い点の辺り)
image.png
〔実行結果#1〕
image.png

〔実行#2〕
画面の中央ほどにマウスを置き、実行!
image.png
〔実行結果#2〕
image.png

どうやら、ちゃんと取得できますね。

3)取得した現在のマウスの位置から...

スクリーンセーバーが起動が起動しない様に、現在のマウスの位置から +1 させていきましょう。
image.png

X = {1 + System.Windows.Forms.Cursor.Position.X}
Y = {1 + System.Windows.Forms.Cursor.Position.Y}

これを延々繰返していけばOKですね。

ただ、画面の最大サイズ位置であるである右下にマウスがあった場合、異常終了するのではないか?と言う思いにいたり...だったら、画面の最大サイズを求めて、その画面サイズを超えないように制御すれば...

4)画面の最大サイズをどう取得するのか?

これも、.NETの機能を利用するのが手っ取り早いですね。得た結果が、以下の式でした。

'ディスプレイの高さ
Dim h As Integer = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height
'ディスプレイの幅
Dim w As Integer = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width

確認のため、「メッセージボックス」アクティビティで、画面の最大サイズを表示させてみましょう。
〔設定内容〕
image.png
image.png
〔実行結果〕
image.png
〔評価〕
マウスを中ほどにして取得した値と、画面サイズを見比べるとちゃんと取れていますね(当然と言えば当然)。
image.pngimage.png

5)計算!

現在のマウスの位置を +1 させていき、画面サイズを超えたなら -1 させていく。そうなると、最終的には画面サイズの辺り(右下)を行ったり来たりの動きになってしまいますね。
だったら、繰り返して計算するのだから、

  • 奇数回目は、現在のマウスの位置に+1する
  • 偶数回目は、現在のマウスの位置に-1する

ようにしてやれば、解決!

と考えたのですが、第一回目(奇数回目)のマウス位置が、そもそも画面サイズで、そこに+1したら既に画面サイズからオーバーする値になってしまう!

と悶々とし始めたら、記事の冒頭の

画面の最大サイズ位置であるである右下にマウスがあった場合、異常終了するのではないか?と言う思いにいたり...だったら、画面の最大サイズを求めて、その画面サイズを超えないように制御すれば...

の思いを翻して、そもそも画面のサイズを超えても、あるいはあり得ない値が設定されても大丈夫ではないか?と考えはじめ...

6)場外乱闘

画面サイズの高さ(.HEIGHT)、幅(.WIDTH)は、0以上の整数ですから、究極の場外乱闘は、負の整数ですね。

  • 「ホバー」アクティビティXのオフセットYのオフセットの値に、直接-1を設定して実行しみます。

お見せ出来ませんが、画面の左上にマウスが移動しました!!

  • 「ホバー」アクティビティXのオフセットYのオフセットの値に、直接10000を設定して実行しみます。

お見せ出来ませんが、画面の右下上にマウスが移動しました!!

と言う事は、特に場外乱闘値を考慮しなくてもよさそうですね。

7)再考した計算!

現在のマウスの位置は取得出来た。繰り返しの奇数回には+1、偶数回には-1をしてあげれば、現在のマウスの位置辺りをちょろっと動きます。その+1あるいは-1を求めるのに、こんな風に考えてみました。

その1

奇数回目か、偶数回目かは、「繰り返し (コレクションの各要素)」アクテイビティの「現在のインデックス」の値を、2で割った際の余りが1だったら奇数0だったら偶数回と言う事はわかりますね。
image.png
この条件分岐後の処理の中で、現在のマウスの位置を +1 させていったり、 -1 させていったりすれば良い訳です。

その2

奇数回目か、偶数回目か。状態は2つしかありません。この2つしかないことに着目すると、Boolean型を利用できそうです。

Boolean型は、True値またはFalse値を取りうる変数の型です。Boolean型をInt32型に変換すると、True値は-1に、False値は0になります。

逆に、Int32型をBoolean型に変換すると、0はFalseに、0以外はTrueになります。

Boolean型が、-1または0を持つInt32型の値に変換出来るのですから、その値を直接利用しない手はありませんね。

計算式:CINT(DISTANCE) * 2 + 1

DISTANCE(Boolean型)がTrueの場合
 CINT(DISTANCE) * 2 + 1
= CINT(True) * 2 + 1
= -1 * 2 + 1
= -2 + 1
= -1

DISTANCE(Boolean型)がFalseの場合
 CINT(DISTANCE) * 2 + 1
= CINT(False) * 2 + 1
=  0 * 2 + 1
=  0 + 1
=  1

image.png


8)態々計算する必要ある?

今まで、スクリーンセーバが起動されないためには、マウスを移動させなければならないと考えていました。

ここまで来て今更なのですが、もしかしたら、マウスを移動させなければならないのではなく、マウスを移動する行為をしなければならないのではないかと。

+1あるいは-1したマウスの位置をもって 「ホバー」アクティビティを実行しなくても、±0したマウスの位置をもって、つまり今のマウスの位置をそのまま設定し、 「ホバー」アクティビティを実行すればいいのではないかと。。。

やってみたら、正にその方法で正解でした。

こうすると、実にスッキリしたロジックになりますね。

まとめ

  • 一つの完成形から、不都合を探してみよう
  • その不都合から、改善の方法を考えてみよう、やってみよう
  • 改善の方法を、複数トライしてみよう
  • その中で、最適解で実装し、しばらく使ってみよう
  • また不都合を探してみよう
    • 現在の不具合は、手でマウスを移動している最中に、「ホバー」アクティビティが実行され、手でのマウス移動が終了した時に、「ホバー」アクティビティが実行された時点のマウス位置にマウス移動してしまう(戻ってしまう)事が、ややイライラのタネですね。

おわりに

いかがでした?

今回も読んでいただきありがとうございました!
是非UiPathでのロボ開発の一助になればと思っています。

ありがとうございました!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1