엑셀VBA 오토마우스 만들기

엑셀VBA 오토마우스 만들기

 

좀 번거롭긴 하지만 엑셀VBA로도 오토마우스를 만들 수 있다. 그렇다고 서든어택같은 게임에서 쓰일 법한 오토마우스를 만들 수 있는건 아니고… 혹시 그런 의도였다면 조용히 ‘뒤로’를 클릭하시기 바란다.

 

회사 업무적으로 (1)특정한 프로그램을 반복적으로 사용하는데 (2)엑셀 스프레드 시트의 값을 옮겨적고 있는 (3)매우 지루하고 따분하고 반복적인 업무 중이다. 라는 상황에서 이 포스팅이 도움이 될 것이다.

 

따로 이렇게 페이지를 만드는 이유는 기존의 VB에서의 방식으로는 VBA에서 좀처럼 작동하지 않기 때문이다.

 

키입력을 예로 들면 기본적으로 VB에서는 sendkeys를 사용하여 키보드를 조작하게 되는데 VBA에서는 잘 안먹힌다. 게다가 엑셀을 기반으로 하고 있기 때문에 엑셀을 포커스에 두고 알트탭을 무지 눌러야하는 등 번거로운 점이 많다.

 

이 모든 단점을 무마할 강력한 장점이 있다면 역시나 엑셀 스프레드시트가 연동되어 있다는것. 필자는 이제 회사에서 버튼 한 번 클릭으로 향락을 즐기고 있다. 컴퓨터가 알아서 마우스 움직이고, 키보드 치고… 그러하다.

 

1. 각종 선언들

‘마우스 클릭을 위한 선언하기
Private Declare Sub mouse_event Lib “user32” (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)

 

‘마우스 좌표 가져오기를 위한 선언하기
Private Type POINTAPI
x As Long: y As Long
End Type
Dim a As POINTAPI
Private Declare Function GetCursorPos Lib “user32” (IpPoint As POINTAPI) As Long

 

‘마우스 위치설정을 위한 선언하기
Private Declare Function SetCursorPos Lib “user32” (ByVal x As Long, ByVal y As Long) As Long
Const MOUSEEVENTF_LEFTDOWN = 2
Const MOUSEEVENTF_LEFTUP = 4

Const MOUSEEVENTF_RIGHTDOWN = 8
Const MOUSEEVENTF_RIGHTUP = 10

Const MOUSEEVENTF_MIDDLEDOWN = 20
Const MOUSEEVENTF_MIDDLEUP = 40

 

‘키보드 상태확인을 위한 선언하기
Private Declare Function GetAsyncKeyState Lib “user32” (ByVal vKey As Long) As Integer

 

‘키입력을 위한 선언하기
Const KEYEVENTF_EXTENDKEY = &H1
Const KEYEVENTF_KEYUP = &H2
Private Declare Sub keybd_event Lib “user32.dll” (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

 

‘시간지연(슬립)을 위한 선언하기
Public Declare Sub Sleep Lib “kernel32.dll” (ByVal dwMilliseconds As Long)

윈도우 10 컴퓨터, 64비트 컴퓨터에서는 Private Declare Sub 텍스트가 빨간색으로 표시될 것이다.

아래와 같이 선언한다.

‘마우스 클릭을 위한 선언하기
Private Declare PtrSafe Sub mouse_event Lib “user32” (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)

‘마우스 좌표 가져오기를 위한 선언하기
Private Type POINTAPI
x As Long: y As Long
End Type
Dim a As POINTAPI
Private Declare PtrSafe Function GetCursorPos Lib “user32” (IpPoint As POINTAPI) As Long

‘마우스 위치설정을 위한 선언하기
Private Declare PtrSafe Function SetCursorPos Lib “user32” (ByVal x As Long, ByVal y As Long) As Long
Const MOUSEEVENTF_LEFTDOWN = 2
Const MOUSEEVENTF_LEFTUP = 4

Const MOUSEEVENTF_RIGHTDOWN = 8
Const MOUSEEVENTF_RIGHTUP = 10

Const MOUSEEVENTF_MIDDLEDOWN = 20
Const MOUSEEVENTF_MIDDLEUP = 40

‘키보드 상태확인을 위한 선언하기
Private Declare PtrSafe Function GetAsyncKeyState Lib “user32” (ByVal vKey As Long) As Integer

‘키입력을 위한 선언하기
Const KEYEVENTF_EXTENDKEY = &H1
Const KEYEVENTF_KEYUP = &H2
Private Declare PtrSafe Sub keybd_event Lib “user32.dll” (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

‘시간지연(슬립)을 위한 선언하기
Public Declare PtrSafe Sub Sleep Lib “kernel32.dll” (ByVal dwMilliseconds As Long)

 

2. 마우스 좌표 가져오기

현재 사용자의 마우스 좌표값을 알아낸다.

 

Call GetCursorPos(a)
MsgBox a.x & “,” & a.y

 

3. 마우스 클릭

특정 위치에 마우스를 클릭하게 한다. 2번과 같이 쓰면 된다.

 

Call SetCursorPos(x좌표, y좌표) ‘마우스 위치설정
Call mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) ‘마우스 눌렀다가
Call mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) ‘마우스 뗀다

 

4. 키입력

sendkeys는 과감하게 버린다. keybd_event 함수를 쓴다.

예를 들면 엔터키 입력

 

‘엔터키 입력
keybd_event 13, 0, 0, 0
keybd_event 13, 0, KEYEVENTF_KEYUP, 0
‘여기서 13은 enterkey의 아스키값

‘Alt+Tab 입력
keybd_event VK_MENU, 0, 0, 0
keybd_event VK_TAB, 0, 0, 0
keybd_event VK_TAB, 0, KEYEVENTF_KEYUP, 0
keybd_event VK_MENU, 0, KEYEVENTF_KEYUP, 0 

본 키입력에서는 아스키 코드를 쓴다.

<간략한 아스키 코드 일람표>

48 :0, 49: 1
65 :A, 66: B
37 : 좌 방향키, 38 : 상, 39 : 우, 40 : 하
46 : delete
112 : F1, 113 : F2

 

5. VBA 코드에서의 실제적 적용

키보드, 마우스 등을 모두 함수화하면 편리하다.

따라서 본 포스트에서는 함수화된 코드들을 제공한다.

 

5-1. 키입력 함수들

Function AltTab()
‘알트 탭
keybd_event 18, 0, 0, 0 ‘알트
keybd_event 9, 0, 0, 0 ‘탭
keybd_event 9, 0, KEYEVENTF_KEYUP, 0
keybd_event 18, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

Function Tb() ‘탭
‘탭
keybd_event 9, 0, 0, 0 ‘탭
keybd_event 9, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

Function CtrlV()
keybd_event 17, 0, 0, 0 ‘컨트롤
keybd_event 86, 0, 0, 0 ‘브이
keybd_event 86, 0, KEYEVENTF_KEYUP, 0
keybd_event 17, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

Function CtrlC()
keybd_event 17, 0, 0, 0 ‘컨트롤
keybd_event 67, 0, 0, 0 ‘씨
keybd_event 67, 0, KEYEVENTF_KEYUP, 0
keybd_event 17, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

Function CtrlA()
keybd_event 17, 0, 0, 0 ‘컨트롤
keybd_event 65, 0, 0, 0 ‘에이
keybd_event 65, 0, KEYEVENTF_KEYUP, 0
keybd_event 17, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

Function Delete()
keybd_event 46, 0, 0, 0 ‘딜리트
keybd_event 46, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

Function Enter()
keybd_event 13, 0, 0, 0 ‘엔터
keybd_event 13, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

Function GoRight()
keybd_event 39, 0, 0, 0 ‘우측 방향키
keybd_event 39, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

Function GoLeft()
keybd_event 37, 0, 0, 0 ‘좌측 방향키
keybd_event 37, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

Function F2()
keybd_event 113, 0, 0, 0 ‘F2
keybd_event 113, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

Function ESC()
keybd_event 27, 0, 0, 0 ‘ESC
keybd_event 27, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Function

 

5-2. 마우스 입력 함수들

Function NoRestClick(xx As Integer, yy As Integer)
Call SetCursorPos(xx, yy) ‘마우스 위치설정
DoEvents
Call mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) ‘마우스 눌렀다가
DoEvents
Call mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) ‘마우스 뗀다
DoEvents
End Function

 

Function Click(xx As Integer, yy As Integer)
Call Rest

Call SetCursorPos(xx, yy) ‘마우스 위치설정
DoEvents
Call mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) ‘마우스 눌렀다가
DoEvents
Call mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) ‘마우스 뗀다
DoEvents
End Function

 

5-3. 시간지연 함수

Call Sleep(100)

 

키입력 이후에 바로 슬립을 붙여서 써줘야 동작이 원활하다. 100 대신 다른 숫자를 넣어도 좋다.

예를 들면

 

Call Delete
Call Sleep(10)

 

이렇게 쓰거나

 

Call NoRestClick(778, 411)
Call Sleep(100)

 

이렇게 쓰면 된다.

 

5-4. REST 함수

임의로 만든 함수인데 알트탭(엑셀로 돌아옴)-메시지박스-알트탭(쓰던 프로그램창으로)을 통해 엑셀 포커싱을 환기해준다. 메시지 박스를 띄우는 함수라고 봐도 된다(예를 들어 당신이 알트탭으로 다른 프로그램을 포커싱하고 있다고 하자. 이 때 msgbox 함수를 그냥 쓰면 안 띄워진다. 반드시 엑셀에 포커스를 맞춘 후 msgbox를 띄우고, 다시 돌아가야 한다)

 

다른 사람들은 어떻게 하는지 모르겠는데, 내 경우에 중간중간 알트탭을 자주해주면 작동이 좀 더 원활하게 되었다. msgbox를 확인해주는게 거슬린다면 그 부분만 주석처리 하면 됨.

 

Function Rest()
Call AltTab ‘알트탭
DoEvents
MsgBox “d”
DoEvents
Call AltTab ‘알트탭
DoEvents
End Function 

 

6. 마치며

모두의 칼퇴근을 이뤄주는 엑셀 매크로를 짜는 그 날까지 힘냅시다.