VBAでマウスを操作(カーソル移動/クリック)する方法【mouse_event関数(API)】
VBAにはキーボードを押したことにする「SendKeysステートメント」という機能が存在します。
これは実際にキーボードを押すわけではなく”キーボードを押したという信号”をプログラムによって送信することで、結果としてキーボードを押したことにすることのできる機能です。
(入力がキーボードではなくVBAになったという考え)
このSendKeysと同じくマウスのカーソル移動やクリックといった操作もVBAで行うことができます。
ただその操作はVBAではなく、VBAで「Windows API」を呼び出すことにより行います。
という訳で今回はWindows APIを利用してマウスを操作する方法を解説していきます。
今回学ぶことのできる内容は以下のとおりです。
Windows APIについて
SetCursorPos関数の使い方
GetCursorPos関数の使い方
mouse_event関数の使い方
上記の関数を使いマウスを操作(カーソル移動/クリック)する方法
上記の関数を使い現在のマウスカーソル位置の座標を取得する方法
これらの関数で操作できる内容は、SendKeysのマウス操作Verと思ってもらえれば大丈夫です。
ちなみに余談ではありますが、マウスがクリックされたことを取得するには、キーボードが押されたことを取得する「GetAsyncKeyState関数」で取得することができます。
マウスを操作するためのAPI関数
VBAでマウスを操作するには下記の3つのWindows APIの関数を使います。
・SetCursorPos関数 : 指定した座標にカーソルを移動する
・GetCursorPos関数 : 現在のカーソル座標を取得する
・mouse_event関数 : 左/右/ホイールを操作する
上記の通り、実際にマウスを操作するのは「SetCursorPos関数」と「mouse_event関数」で、操作自体には関わりませんがコードの作成を補助する役割として「GetCursorPos関数」があります。
イメージとしては下のgif画像のように実行した瞬間に指定した座標へカーソルを移動/クリックさせることができます。(使用関数は「SetCursorPos関数」「mouse_event関数」のみ)
Windows APIとは
これらマウス操作の関数はWindows APIで用意されているものでVBAとは別のものです。Windows APIとは簡単にいえばWindowsに用意されている機能がまとまっているセットのようなものです。
Windows APIにはマウス操作に関する関数以外にも様々な関数があり、VBA上でそれらを呼び出すことで、Windowsに用意されている様々な機能を使用することができます。(たとえばWindowsのシステム効果音を鳴らしたり、指定した秒数だけ処理を止めることができます)
ちなみに名前からわかると思いますが、Windows APIではWindowsの機能を呼び出しているだけので基本的にはWindows以外のOSでは使用することはできません。
マウス操作の各関数の使い方
マウス操作の関数を使うにははじめに「Windous APIの関数を使うよ」と宣言する必要があります。
※宣言をしないと各関数は使えずエラーになるので書き忘れに注意しましょう。
使用しているWindowsが32bitか64bitかによって宣言時に書く内容が変わってきます。
以下のどちらかをコードの一番初め(Option Explicitの次の行あたり)に書いておくことで、そのモジュール内で各関数を使うことができるようになります。
‘【SetCursorPos関数】
Declare PtrSafe Function SetCursorPos Lib “user32” (ByVal x As Long, _
ByVal y As Long) As Long
‘【GetCursorPos関数】
Declare PtrSafe Function GetCursorPos Lib “user32” (lpPoint As coord) As Long
‘【mouse_event関数】
Declare PtrSafe 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)
‘【SetCursorPos関数】
Declare Function SetCursorPos Lib “user32” (ByVal x As Long, _
ByVal y As Long) As Long
‘【GetCursorPos関数】
Declare Function GetCursorPos Lib “User32” (lpPoint As coord) As Long
‘【mouse_event関数】
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)
※操作環境のbitと構文があっていないとエラーになるので注意しましょう。
上記のどちらを書けばいいかわからない場合は以下のコードをコピペして、モジュールの最上部に書いておきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#If Win64 Then '【SetCursorPos関数】 Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long '【GetCursorPos関数】 Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As coord) As Long '【mouse_event関数】 Declare PtrSafe 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) #Else '【SetCursorPos関数】 Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long '【GetCursorPos関数】 Declare Function GetCursorPos Lib "User32" (lpPoint As coord) As Long '【mouse_event関数】 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) #End If |
この構文を書いておくことで自動的に使うことのできる方の構文が使用されます。
VBE上では使えない方の構文が赤色で表示される場合がありますが、実行に影響はありません。
各関数の宣言文は「Private/Public」を付けて各関数の有効範囲を指定することもできます。
・Private Declare PtrSafe Function~ :モジュール内で呼び出し有効
・Public Declare PtrSafe Function~ :モジュール外で呼び出し有効
またGetCursorPos関数の引数「lpPoint As coord」の「coord」は自身で用意する必要があります。
ここでは座標(Coordinate)から取って「coord」としていますが好きな名称にしても問題ありません。
1 2 3 4 |
Type coord x As Long y As Long End Type |
「coord」は上記のようにTypeステートメントを使って定義します。
記載する場所はSubプロシージャ外(宣言文のすぐ後ろ当たり)です。
詳しくは以降のサンプルコードを参考にして下さい。
SetCursorPos関数の構文
SetCursorPos関数は指定した座標地点にマウスカーソルを移動させることのできる関数です。
構文は非常にシンプルで以下のように書きます。
SetCursorPos X座標,Y座標
座標は整数値(Long型)で画面の左上が基準となり、右に行くほどX座標値が増え下に行くほどY座標値が増えます。現在のカーソル位置の座標を取得することのできるGetCursorPos関数であらかじめ調べておいた座標値を入れるのが無難です。
カーソルの移動は現在の地点から指定した座標地点まで一瞬で飛びます。
たとえばペイントでクリック状態のまま移動させても線が引かれることはないということです。
GetCursorPos関数の構文
GetCursorPos関数は現在のマウスカーソル地点の座標を取得することのできる関数です。
SetCursorPos関数を使用する際に座標がわからない時にはこの関数を使います。
構文はSetCursorPos関数と同様ににシンプルで下記のように書きます。
Dim c As coord
GetCursorPos c
上記コードによって「c」という変数内に現状のカーソル地点のX座標/Y座標が格納されます。
「c」のタイプ(ここではcoord)はさきにも書いた通り事前に用意しておく必要があります。
座標を取得後は、X座標は「c.x」Y座標は「c.y」と表すことができます。
上記コードを実行する度に座標値は最新のカーソル地点の座標に更新されていきます。
mouse_event関数の構文
mouse_event関数はマウスのボタンを操作することのできる関数です。
構文は以下のように書きます。引数の値によってマウスの操作内容が変化します。
mouse_event 操作内容
上記の引数「操作内容(dwFlags)」には下記のいずれかの引数の数字を入力します。
引数 | パラメータ値 | 操作内容 |
2 | MOUSEEVENTF_LEFTDOWN | 左ボタンが押されたことを示す |
4 | MOUSEEVENTF_LEFTUP | 左ボタンが離されたことを示す |
8 | MOUSEEVENTF_RIGHTDOWN | 右ボタンが押されたことを示す |
10 | MOUSEEVENTF_RIGHTUP | 右ボタンが離されたことを示す |
20 | MOUSEEVENTF_MIDDLEDOWN | 中央ボタンが押されたことを示す |
40 | MOUSEEVENTF_MIDDLEUP | 中央ボタンが離されたことを示す |
上記以外にも何個か機能がありますが、古いWindows用なので現在は使用できなものもあります。
詳しくは「mouse_event – API 関数解説」を参照下さい。
また、引数は16進数での値なのでそのまま入力してもうまく実行できないので注意してください。
扱う際は上記の引数の前に「&H」をつけて16進数として扱ってください。
(引数の2や4は16進数でも同じ値なので&Hをつけずにそのままでも利用できます)
たとえば左クリックがしたければ
「mouse_event &H2」(左ボタン押下)→「mouse_event &H4」(左ボタン解放)と順に書きます。
クリックの場合は押下した後に解放する必要があるので注意しましょう。
マウス操作サンプルコード
実際にVBAマクロとして使用する場合は以下のように書きます。
下記コードの「Sub マウスで画面の任意の位置をクリック()」を実行することで、指定した座標をクリックすることができます。mouse_eventを追加したり引数を変えることでWクリックや右クリックのような操作をすることも出来ます。
また「クリックする座標を調べたい」という場合は「Sub 現在のカーソル位置の座標を取得()」を実行することでイミディエイトウィンドウに座標を表示させることができます。
(※実行ボタンをクリックで押すとボタン部分の座標が取得されてしまうため、カーソルを取得したい位置に移動してから[F5]キーでコードを実行させましょう)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
Option Explicit #If Win64 Then '【SetCursorPos関数】 Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long '【GetCursorPos関数】 Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As coord) As Long '【mouse_event関数】 Declare PtrSafe 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) #Else '【SetCursorPos関数】 Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long '【GetCursorPos関数】 Declare Function GetCursorPos Lib "User32" (lpPoint As coord) As Long '【mouse_event関数】 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) #End If Type coord x As Long y As Long End Type '------------------------------------------------------------------------------------- Sub マウスで画面の任意の位置をクリック() SetCursorPos 100, 200 'X=100,Y=200の地点にカーソルを移動 mouse_event &H2 'マウス左ボタンを押す mouse_event &H4 'マウス左ボタンを離す End Sub '------------------------------------------------------------------------------------- Sub 現在のカーソル位置の座標を取得() '※このプロシージャにフォーカス(プロシージャ内をクリック)してから[F5]キーで実行 Dim c As coord GetCursorPos c Debug.Print c.x 'カーソル位置のX座標をイミディエイトウィンドウに表示 Debug.Print c.y 'カーソル位置のY座標をイミディエイトウィンドウに表示 End Sub |
まとめ
今回はWindows APIを使ってマウスを操作する方法についてでした。
本ページで紹介した関数を使うことで、VBAではどうしても操作できない領域(たとえばブラウザ上の指定の場所をクリックする)にアクセスすることが出来ます。
ただ「SendKeys」と同じように、不安定なものでもあります。
また、クリックしたい地点の座標が少しズレただけでもコード内容を書き直す必要があるものです。
それらを踏まえたうえでどうしてもVBAで操作できない領域を操作したいという場合にはぜひこれらのAPI関数を利用してみて下さい。