ボロボロ皇帝のボロ切れと塊

ボロボロ皇帝が悪態、嫌み、好み、何でも己の視点だけで自由に吐く「偏」な場所。たまにExcel、家電、音楽等についても好きに吐いてる。

ボロボロ皇帝が悪態、嫌み、好み、何でも己の視点だけで自由に吐く「偏」な場所。
Excel、家電、音楽、ゲームイラスト小説映画、性癖について等、何でも好きに吐いてる。

どうでも良いかもしれんが背景色変わっていくの見てくれ。
更にどうでも良いかもしれんがアイコンが息してるの見てくれ。


我輩は何にも制約されない身、
「耐えぬ」事を恐れないと決めたのだ!
我輩は好きなときに悪態をつく!
妬み僻み嫉みを背負い、
マイナーだろうが邪道だろうが
我輩は我輩の道を行く!
好きなものは懸命で不器用な諸君,
嫌いなものは器用で完璧を気取った奴らだ。
         

吐くほどめんどくせえからVBA(マクロ)〜任意の座標を自動でクリック〜おまけ:任意の座標へドラッグ&ドロップ

 

 上長というのは、得てして吐くほどめんどくせえアナログ作業を依頼してくる生き物である。

     〜引用元:ボロボロ皇帝のBoroism

 

 

ようこそ諸君、ボロボロ皇帝だ。

 

我輩はめんどくせえこと大嫌いな面倒くさがりなのだが、 

本日、久しぶりに上長(所長)がマジクソめんどくせえ事を、我輩に依頼してきたので、

せっかくだしその時使った何かと応用しやすい(が一歩間違ったら大惨事な)、マクロ(VBA)コードを諸君へ伝授してやるぞ。ありがたく思うのだ。

 

さっさと本題に行きたい諸君のために目次↓

 

 

我輩は小売系の会社で働いている(量販店のとある部署)。

小売業とは何かにつけてキャンペーンを発足するものだ(まあ本当に安くなるから別に顧客からすればいいことなのだがそこは置いといて)。

 

でまあ、そのキャンペーンがどれだけ当たったか宣伝費などに対して売上は、という事を数値をもってしてしっかり分析せねばならん。

要は費用対効果と言うやつだ。

分析に必要な数値を集計するには、

・このお客様キャンペーン見てきた方ですよ(^o^)→フラグ1

・このお客様キャンペーン見てないですよ(´・ω・`)→フラグ0

という風に分かるようにしておけば、BI(ビジネスインテリジェンス)でもなんでもあとから集計をかけることはできる。要は条件の一致で調べていくのだ。

だがしかし!

お間抜けさんはそのフラグ1を立てない。

それどころか、お間抜けなキャンペーン発案者であれば、フラグ立ててね!というルール決めすらしないし、条件のことなど何一つ思いついていない。

つまり、無法地帯だ。無法地帯でキャンペーン受付は増えるが一体どれがキャンペーン受付分か、どれがそうじゃないのか、もう全てがごっちゃになって何がなんだか切り分けができないのだ。

 

頼れるのは、その時、顧客との約束事項が記載されている受付担当の自由入力欄

自由入力欄はそれはそれは自由に記載されており条件など何もないので通常、集計には役立たない。

そんな自由入力欄に唯一、キャンペーン受付とそうでない顧客を識別できる方法がある。なぜならキャンペーン受付であれば受付担当者が、キャンペーン、もしくはキャンペーン、もしくは割引という単語を入れてくれているからだ!!

 

 

今回我輩が科せられた縛り与えられたアイテム等を整理しよう。

全受付から条件無しでキャンペーン受付を切り分ける

自由入力欄はBIでは一部しか出てこない

BIから受付番号は拾える

その受付番号があれば、受付用端末システム上から手動で検索し受付履歴を照会することができる

受付履歴では自由入力欄を見ることができる

受付件数は100件程

 

これをバカ正直に手作業でやるとなると、

いちいち手動で受付番号を叩き→出てきた受付履歴の自由入力欄をコピーし→EXCELシートに貼り付け(ペ)る ×100回

その後に→Find関数で単語検索掛ける

ということになり、ひと言でいえば集計だが、実質イカれた作業】になるわけだ。

 

我輩はそんなイカれたことはしたくない。

 

そんなの、狂ってしまうじゃないか…。

もう、十分…狂っているというのに…。

それを、それに手を出してしまったら…。

終わりだッ…。

終わりなんだああああああ!!!!!!

 

というわけで、我輩はマクロという名の魔法を使うことにした。

我輩はマクロ使いの弟子なのだ(師匠はネット上にたくさんいる)。

 

我輩は、座標を拾うコードクリックするコードコピペ作業を自動化することにした。

※ちなみにこのコードの「一歩間違えたら大惨事」という部分は後ほど説明する。

 

 

これから紹介するのは、

好きなところを自動でクリックするVBA

である。

まずは、

座標を拾う必要がある。

ちなみにこのVBAAPIを使用する。

APIについて説明が必要な諸君のために説明しよう。

 

APIとは:Application Programming Interfaceである

 

は?という感じだな。そりゃそうだ。

まあ我輩はいつも適当な覚え方をしているのであまりためにはならんだろうが、我輩の認識している概念みたいなのでよければ説明させてもらおう。不要であればすっ飛ばしてくれ。

 

APIとは共有できるマジックハンドのようなものだ。

マジックハンドってのは、これだ↓

f:id:wornoutemperor:20210506232911p:plain

例えば、

A地点にあるあのゴミ箱にゴミ入れたいけど遠くて手が届かないよーとなった時、

みんなで共有できる貸出マジックハンドがあればそこにゴミを入れることができる(コロナだから共有できないとかいう話は無しだ)

それはB地点にあるゴミ箱にでも、C地点にあるゴミ箱にでも、条件さえ整えばそのマジックハンドを比較的広範囲で使えるのだ!!

 

つまり便利道具だ。

その便利道具は保管場所にあるのだが、その保管場所の名前を間違えると借りることは出来ないから一字一句間違えないようにしなくてはならん(名前間違えるようなやつには貸しませーん(^o^)とのことだ)

 

 (適当な)説明は一旦ここまでとして。

まず適当に標準モジュールへ以下のコードをコピペ。

ここから↓

Private Type position
x As Long
y As Long
End Type
Declare Function SetCursorPos Lib "User32" (ByVal x As Long, ByVal y As Long) As Long
Declare Sub mouse_event Lib "User32" ( _
ByVal dwflags As Long, _
Optional ByVal dx As Long = 0, _
Optional ByVal dy As Long = 0, _
Optional ByVal dwDate As Long = 0, _
Optional ByVal dwExtraInfo As Long = 0)
Declare Function GetCursorPos Lib "User32" (lpPoint As position) As Long

Sub Lclick()
mouse_event 2
mouse_event 4
End Sub

Sub Rclick()
mouse_event 8
mouse_event 16
End Sub

Sub zahyotyosa()
Dim pos As position
Call GetCursorPos(pos)
Debug.Print pos.x, pos.y
MsgBox pos.x & ", " & pos.y
End Sub

ここまで↑

 

【分かった気になれるかもしれない解説】

Private Type positionUser32という保管場所(Lib=ライブラリー)にあるAPI(マジックハンド)を借りるぞ、というコードだ。

今回ここから借りるAPIは、

・座標を調べるためのもの

・マウスクリックするためのもの

の二つである。

Sub Lclick()Sub Rclick()で先程User32借りてきたマウスクリックするためのものを使う。

わかりやすく名前をLclick(左クリック)とRclick(右クリック)にしており、その名の通り中身はクリックするだけのコードである。

マウスをクリックするには、押して離すという動作が必要なわけである。なので1つのクリックで処理を二つ書かなければならない。面倒なので処理をひとまとめにしておくのだ。
※ひとまとめにしたものをプロシージャという(Sub〜End Subまでのひとつのまとまり。Subはプロシージャの名前みたいなもの、別に覚えなくてもいい)

そうすると後から呼び出せて楽である。

 

Sub zahyotyosa()も同じ考えである。座標を調べるためのものを使って必要な処理ひとまとめにしている。x軸とy軸の交わる点を教えてもらうためのコードというわけだ。

ちなみに、MsgBoxは別にMsgBoxでなくてもよい。これをDebug.Printに変更するとイミディエイトウィンドウとかいう絶対覚えきれなさそうな名前のウィンドウ(我輩は名前はいつも覚えきれていない)に実行結果を吐き出させることが可能なのでそこに表示させてもいい。

このイミディエイトウィンドウが見当たらない場合は、Ctrl+Gで出てくる。

でまあ、己の調査したい座標位置にマウスポインタを持ってきて、zahyotyosaF5で実行させると無事座標を把握できる

 

上記が完成して、

座標を調べたところでようやく好きなところをクリック

デキるようになるのである。

 

例えば、座標1000, 1000を右クリックしたい場合は以下のとおりだ。

 

Sub LRclick()
SetCursorPos 1000, 1000
Rclick
End Sub

 

このように、調べた座標とクリックのコードを組み合わせる任意の場所をクリックできるようになる。

 

こんな感じで出来るようになる、任意の座標自動クリック

 

我輩の場合はコレを、
AppActivate "受付情報照会"

だとかで現在開いているシステムのアプリケーションウィンドウをアクティブにして受付番号を
SendKeys "^v"

でペーストしたり、

SendKeys "~"

でEnter打ったり、
Application.Wait [now()+"00:00:0.5"]

とかで参照待ちしたり、したあとに、
SetCursorPos 686, 711
Lclick
Lclick

こんな感じで、出てきた画面のコピペしたい部分にマウスポインタを持って行き、ダブルクリックで範囲指定して~といった応用をする。

そう、ダブルクリックも出来るのだ!!

 

 

それと、マウスイベントを応用すれば、

ドラッグ&ドロップもできる

Sub Lclick()
mouse_event 2
mouse_event 4
End Sub

とあるが、

この、
mouse_event 2

が、左クリックを押した瞬間で、
mouse_event 4

が、左クリックを話した瞬間であるから、

 

Sub drag()
mouse_event 2

End Sub

Sub drop()
mouse_event 4
End Sub

 

例えば、x1000・y1000の位置からx200・y200の位置にドラッグしたい場合

SetCursorPos 1000, 1000

Call drag

SetCursorPos 200, 200

Call drop

とすれば、無事好きなもんを好きなところへドラッグ&ドロップできるのだ!

ものすごく楽しい〜ぞ(^o^)

 

 

…と、こんな感じのを駆使してどうにかこうにか吐くほどめんどくさい集計を自動化させた我輩。

だが、外部アプリケーションを操作しているため、

Application.Wait

での待機時間の微調整が必要な内容である。

この待機時間を0.1秒でも早く見積もってしまうと、全部が狂う

たとえば待機待ちの計算をミスって100ある繰り返し作業を流れのまま進めてしまったとしよう。というか進める、VBAとはそういう自動化であるからな。

そうなるとマジで無駄なモンができあがってしまうのである。

これが一歩間違えたら大惨事な点だ。

 

こんな感じで大惨事を引き起こさないようにするためには、微調整と、テスト行為が重要だ。

それらを経てこのコードは完成するため、完成までの調整とテストをいかに早く終わらせられるかも意識せねばならない。そうしないと作業自体が進められないからな。

もちろん同じ作業を人力で100繰り返すよりは断然早く済むだろうが、それでも更に素早さとある種の見切り(作業を速く終わらせようとしすぎず、待機時間に余裕を持つ見切り力)のつけ方が大事である。

 

以上、別に、任意の座標を自動クリックするだけであれば、別に大惨事になることは無いだろうが、我輩と同じような事(外部アプリケーションの操作)をしようとしている諸君がいたときのために、注意点であった。

我輩の場合は、大惨事を大分前に経験済みであるから、既に色々と学んで今回のこれは完璧に上手くいった。

VBA最高である!!!

 

余談だが、VBAでの集計自体は上手くいったが、受付時のヒューマンエラー的な物がいくつかあったため、結局手作業での修正も加わった。

まあほぼ自動で終わらせられたから良かったとして、これ、手作業でしてたらマジで発狂してたな、と思う。本当に恐ろしいぜ…。