Summary
You can make a Windows API (application programming interface) call to a Microsoft Windows DLL (dynamic-link Library) to get and set the current cursor position. The current position can be obtained by using the GetCursorPos function in USER32.DLL.
More Information
Microsoft Excel does not have the built-in functionality to get or set the cursor position. However, you can use the Declare statement in a Microsoft Excel Visual Basic for Applications macro to call a Microsoft Windows function to access the current position. You can also use another function SetCursorPos to set the cursor position. The SetCursorPos function can be used in a looping structure to move the cursor across the screen.
Microsoft provides examples of Visual Basic for Applications procedures for illustration only, without warranty either expressed or implied, including, but not limited to the implied warranties of merchantability and/or fitness for a particular purpose. The Visual Basic procedures in this article are provided ‘as is’ and Microsoft does not guarantee that they can be used in all situations. While Microsoft support professionals can help explain the functionality of a particular macro, they will not modify these examples to provide added functionality, nor will they help you construct macros to meet your specific needs. If you have limited programming experience, you may want to consult one of the Microsoft Solution Providers. Solution Providers offer a wide range of fee-based services, including creating custom macros. For more information about Microsoft Solution Providers, call Microsoft Customer Information Service at (800) 426-9400.
EXAMPLES
-
Type the following code into a new module:
' Access the GetCursorPos function in user32.dll
Declare Function GetCursorPos Lib "user32" _
(lpPoint As POINTAPI) As Long
' Access the GetCursorPos function in user32.dll
Declare Function SetCursorPos Lib "user32" _
(ByVal x As Long, ByVal y As Long) As Long' GetCursorPos requires a variable declared as a custom data type
' that will hold two integers, one for x value and one for y value
Type POINTAPI
X_Pos As Long
Y_Pos As Long
End Type' Main routine to dimension variables, retrieve cursor position,
' and display coordinates
Sub Get_Cursor_Pos()' Dimension the variable that will hold the x and y cursor positions
Dim Hold As POINTAPI' Place the cursor positions in variable Hold
GetCursorPos Hold' Display the cursor position coordinates
MsgBox "X Position is : " & Hold.X_Pos & Chr(10) & _
"Y Position is : " & Hold.Y_Pos
End Sub' Routine to set cursor position
Sub Set_Cursor_Pos()' Looping routine that positions the cursor
For x = 1 To 480 Step 20
SetCursorPos x, x
For y = 1 To 40000: Next
Next x
End Sub -
Click anywhere inside the text of the Get_Cursor_Pos routine and press the F5 key to run the Get_Cursor_Pos macro.
You will get a message box displayed with the coordinates of the current position of the mouse pointer.
-
Click anywhere inside the text of the Set_Cursor_Pos routine and press the F5 key to run the Set_Cursor_Pos macro.
The cursor will move diagonally down across the screen.
Need more help?
Want more options?
Explore subscription benefits, browse training courses, learn how to secure your device, and more.
Communities help you ask and answer questions, give feedback, and hear from experts with rich knowledge.
Hm, it’s not exactly built in AFAIK, but I found this page which gives a suggestion that worked for me:
In a module, put this at the top:
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function ScreenToClient Lib "user32" (ByVal hWnd As Long, _
lpPoint As POINTAPI) As Long
Private Type POINTAPI
X As Long
Y As Long
End Type
Then, for the subroutines to get the mouseX and mouseY, put this somewhere below:
Function MouseX(Optional ByVal hWnd As Long) As Long
' Get mouse X coordinates in pixels
'
' If a window handle is passed, the result is relative to the client area
' of that window, otherwise the result is relative to the screen
Dim lpPoint As POINTAPI
Application.Volatile(false)
GetCursorPos lpPoint
If hWnd Then ScreenToClient hWnd, lpPoint
MouseX = lpPoint.X
End Function
and
Function MouseY(Optional ByVal hWnd As Long) As Long
' Get mouse Y coordinates in pixels
'
' If a window handle is passed, the result is relative to the client area
' of that window, otherwise the result is relative to the screen
Dim lpPoint As POINTAPI
Application.Volatile(false)
GetCursorPos lpPoint
If hWnd Then ScreenToClient hWnd, lpPoint
MouseY = lpPoint.Y
End Function
Then, in Excel, if you simply enter into a cell =mouseX()
it’ll return the mouseX position when you hit ENTER
. Same with =mouseY()
.
Trying it out, I did:
Sub chart_Test()
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlLine
ActiveSheet.Shapes("Chart 1").Top = MouseY()
ActiveSheet.Shapes("Chart 1").Left = MouseX()
End Sub
and got it to work.
edit: Note, I’m not as good with charts as other things in VBA, so as you create charts, you’ll need to edit the .Shapes("Chart 1").
part to whatever chart name/number you’re on. Or iterate through them.
Имитация движения и кликов левой и правой кнопками мыши из кода VBA Excel. Эмуляция перемещения курсора и определение его текущих координат.
В VBA Excel нет методов и функций для имитации движения мыши и эмуляции кликов ее левой и правой кнопками. Но для этих целей, а также для определения текущих координат курсора, можно использовать встроенные функции Windows API — GetCursorPos, SetCursorPos и mouse_event.
Если эти функции Windows API объявить без ключевого слова Private, они будут доступны во всех модулях текущего проекта VBA.
Определение координат курсора
Определение текущих координат курсора из кода VBA Excel:
Option Explicit Declare PtrSafe Function GetCursorPos Lib «user32» (lpPoint As POINTAPI) As Long Type POINTAPI X As Long Y As Long End Type Sub Get_Cursor() Dim myPoint As POINTAPI GetCursorPos myPoint Debug.Print «Координата X: « & myPoint.X & vbNewLine & _ «Координата Y: « & myPoint.Y & vbNewLine End Sub |
Скопируйте представленный выше код в стандартный модуль и кликните мышью внутри процедуры Get_Cursor()
. Затем, перемещайте курсор мыши по экрану, не нажимая кнопок, чтобы мигающая вертикальная линия (точка вставки) не ушла из процедуры, и нажимайте клавишу F5. В окне Immediate будут печататься текущие координаты курсора. Клавишу F5 можно нажимать одновременно с процессом перемещения мыши. Значения координат X и Y отображаются в пикселях.
Имитация движения мыши
Имитация движения мыши, а, точнее, перескока мыши из одной точки в другую, осуществляется из кода VBA Excel путем задания новых координат курсору:
Option Explicit Declare PtrSafe Function SetCursorPos Lib «user32» (ByVal X As Long, ByVal Y As Long) As Long Sub Set_Cursor() Dim myX As Long, myY As Long myX = 600 myY = 400 ‘Задаем курсору новые координаты SetCursorPos myX, myY End Sub |
Переменные добавлены в пример для наглядности, их можно не использовать:
А так можно задать множественные перескоки курсора мыши:
Sub Many_Set_Cursor() Dim i As Long For i = 1 To 600 Step 20 Application.Wait Now + TimeValue(«0:00:01») SetCursorPos i, i Next End Sub |
Здесь перескок мыши происходит один раз в секунду.
Уменьшив задержку выполнения цикла предыдущего примера с помощью другого цикла, можно ускорить перемещение курсора и сделать его более плавным:
Sub Many_Set_Cursor_2() Dim i As Long, i2 As Long, a As Long For i = 1 To 600 For i2 = 1 To 100000 a = i2 / 2 Next SetCursorPos i, i Next End Sub |
Здесь уже более похоже на имитацию движения мыши.
Имитация кликов мыши
Чтобы воспроизвести имитацию кликов левой и правой кнопками мыши, нам понадобятся коды событий кнопок мыши:
Событие | Код |
---|---|
Нажать левую кнопку | &H2 |
Отпустить левую кнопку | &H4 |
Нажать правую кнопку | &H8 |
Отпустить правую кнопку | &H10 |
Следующий пример показывает, как установить курсор мыши в заданное место экрана и сымитировать клик правой кнопкой мыши:
Option Explicit Declare PtrSafe Function SetCursorPos Lib «user32» (ByVal X As Long, ByVal Y As Long) As Long 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) Sub Set_Cursor_and_RightClick() ‘Устанавливаем курсор в нужную точку экрана SetCursorPos 800, 600 ‘Нажимаем правую кнопку мыши mouse_event &H8, 0, 0, 0, 0 ‘Отпускаем правую кнопку мыши mouse_event &H10, 0, 0, 0, 0 End Sub |
Я выбрал для примера имитацию клика правой кнопкой мыши из-за большей наглядности (за счет отображения контекстного меню).
Обратите внимание, что функции Windows API, используемые в примерах, должны быть объявлены только один раз.
Фразы для контекстного поиска: положение курсора, имитация клика, эмуляция клика, эмуляция движения, имитация мыши, эмуляция мыши, координаты мыши, расположение мыши, расположение курсора.
Указатель мыши в точку координат курсора |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
Друзья, добрый день!
Решаю такую задачу: для работы макроса необходимо знать, где располагаются определенные элементы на мониторе в данный момент (расположение может быть разное, но в рамках одного цикла работы макроса элементы находятся в одном положении). Для этого хотелось бы, чтобы программа спросила через Inputbox или как-то еще, например, «Щелкните на элементе <плюсик>», пользователь щелкает мышкой на плюсике (либо же наводит на плюсик и нажимает какую-то кнопку, если мышкой нельзя щелкать) и координаты мыши добавляются в переменную, с которой потом уже будем работать.
Нашел такой код:
Код |
---|
Он отлично работает, встаю мышью куда мне надо, нажимаю F5, получаю координаты.
Как это реализовать применимо к описанной выше идее, что это должен быть диалог с пользователем?
Нужно какую-то свою форму рисовать? Покажите, пожалуйста, на примере «появилось окно с просьбой указать элемент — я кликаю на элемент — координаты попали в переменную».
Спасибо.
Update: или вот еще какую красоту нашел (если запустить, и таймер бегает и в режиме реального времени координаты отображаются). Как прикрутить, чтобы спрашивало у пользователя кликнуть в точку, у которой нужно получить координаты.
Код |
---|
Изменено: whateverlover — 18.10.2021 15:29:05