みなさん,こんにちは。
シンノユウキ(shinno1993)です。
今回はVBAを使った,「エクセル栄養君」の食品の一覧のボタンをすべてクリックするマクロを紹介します.活用の機会は少ないかも?ですが,こんなことも可能!という目線でごらんください.
ではいきましょう!
こんな感じになります!
最初に,どんな感じになるのかを紹介します.マクロを実行すると,以下のようになります:

Excelシートやユーザーフォームへの反映が遅れていますが,すべてしっかりとクリックしています.
ではコードを紹介していきましょう!
コード全文はこちら!
コードは以下のようになります:
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Declare Function SetCursorPos Lib "User32" (ByVal x As Long, ByVal y As Long) As Long
Private Type Position
x As Long
y As Long
End Type
Declare Function GetCursorPos Lib "User32" _
(lpPoint As Position) 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)
Sub test()
Dim itemCount As Long
Dim listCount As Long
Dim cnt As Long
Dim item As Long
Dim ctg As Long
Dim loopCount As Long
Dim mode As Long
Dim foodAddBtn As Position
Dim ctgBtn As Position
Dim food As Position
Dim leftFoodFirst As Position
Dim rightFoodFirst As Position
Dim rightDown1 As Position
Dim rightDown2 As Position
Dim leftDown1 As Position
Dim leftDown2 As Position
Dim aryCtgInfo As Variant
Dim window As String
'---設定---
foodAddBtn.x = 214: foodAddBtn.y = 72
leftFoodFirst.x = 810: leftFoodFirst.y = 341
rightFoodFirst.x = 1088: rightFoodFirst.y = 341
leftDown1.x = 951: leftDown1.y = 642
leftDown2.x = 951: leftDown2.y = 657
rightDown1.x = 1222: rightDown1.y = 642
rightDown2.x = 1222: rightDown2.y = 657
Const ITEM_OFFSET = 15
Const CTG_START = 1
Const CTG_END = 18
aryCtgInfo = SettingSh.Range("A2:E19")
Const ITEM_COUNT_INDEX = 2
Const LIST_COUNT_INDEX = 3
Const X_INDEX = 4
Const Y_INDEX = 5
'----------
Application.ScreenUpdating = True
ThisWorkbook.ActiveSheet.Range("B4").Activate
'Call click(foodAddBtn)
For ctg = CTG_START To CTG_END
'カテゴリのラジオボタンをクリック
ctgBtn.x = aryCtgInfo(ctg, X_INDEX): ctgBtn.y = aryCtgInfo(ctg, Y_INDEX)
Call click(ctgBtn)
itemCount = aryCtgInfo(ctg, ITEM_COUNT_INDEX)
listCount = aryCtgInfo(ctg, LIST_COUNT_INDEX)
loopCount = getLoopCount(itemCount, listCount)
'リストボックス内のすべてのアイテムをループ
For cnt = 1 To loopCount
window = getWindow(ctg)
If window = "Left" Then
food = leftFoodFirst
Else
food = rightFoodFirst
End If
'リストボックスに表示されているすべてのアイテムをクリック
For item = 1 To listCount
Call click(food)
food.y = food.y + ITEM_OFFSET
Next item
'リストに表示されているアイテムの数で↓ボタンの場所が違うため
window = getWindow(ctg)
If listCount = 20 Then
If window = "Left" Then
Call click(leftDown1, listCount)
Else
Call click(rightDown1, listCount)
End If
Else
If window = "Left" Then
Call click(leftDown2, listCount)
Else
Call click(rightDown2, listCount)
End If
End If
Next cnt
'リストボックスの最後のあまりをクリック
mode = getMode(itemCount, listCount)
If mode <> 0 Then
If window = "Left" Then
food = leftFoodFirst
Else
food = rightFoodFirst
End If
food.y = food.y + (listCount - mode) * ITEM_OFFSET
For item = listCount - mode To listCount
Call click(food)
food.y = food.y + ITEM_OFFSET
Next item
End If
Next ctg
End Sub
Sub click(pos As Position, Optional clicks = 1)
Dim click As Long
SetCursorPos pos.x, pos.y
For click = 1 To clicks
mouse_event 2
mouse_event 4
Next
End Sub
Sub 座標を調べる()
Dim pos As Position
Call GetCursorPos(pos)
Debug.Print pos.x, pos.y
End Sub
Function getMode(itemCount, listCount)
getMode = itemCount Mod (listCount)
End Function
Function getLoopCount(itemCount, listCount)
getLoopCount = WorksheetFunction.RoundDown(itemCount / listCount, 0)
End Function
Function getWindow(ctg)
Dim food As Position
If ctg < 10 Then
getWindow = "Left"
Else
getWindow = "Right"
End If
End Function
こちらのコードは,以下のサイトを参考にしました.
これらのコードは,スクリーン上の座標を指定してクリックしています.私のディスプレイ環境は1920×1080の等倍環境ですので,これと同じ環境であれば,上記のコードで問題ありません.
しかし,それ以外の環境の場合は,クリックするボタンの座標をそれぞれ修正してください.
また,食品群のラジオボタンの座標や情報はコード上に記述すると複雑になるため,以下のような形でシート上に記述しています.これをシートのA1からコピーし,シートのオブジェクト名を「SettingSh」とすれば問題ありません.
| itm | lst | x | y | |
| 1 | 164 | 20 | 698 | 340 |
| 2 | 62 | 21 | 698 | 365 |
| 3 | 27 | 21 | 698 | 395 |
| 4 | 94 | 21 | 698 | 416 |
| 5 | 52 | 20 | 698 | 446 |
| 6 | 385 | 20 | 698 | 475 |
| 7 | 181 | 20 | 698 | 496 |
| 8 | 52 | 20 | 698 | 526 |
| 9 | 54 | 20 | 698 | 551 |
| 10 | 446 | 20 | 987 | 339 |
| 11 | 293 | 20 | 987 | 363 |
| 12 | 20 | 20 | 987 | 391 |
| 13 | 58 | 20 | 987 | 416 |
| 14 | 31 | 20 | 987 | 442 |
| 15 | 142 | 20 | 987 | 474 |
| 16 | 59 | 21 | 987 | 496 |
| 17 | 136 | 21 | 987 | 522 |
| 18 | 23 | 20 | 987 | 552 |
まとめ
今回はVBAを利用して「エクセル栄養君」の自動化に挑戦してみました.次回は料理一覧を自動で入力できるマクロを作成してみます.
