Vba excel координаты мыши

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

  1. 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

  2. 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.

  3. 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, используемые в примерах, должны быть объявлены только один раз.


Фразы для контекстного поиска: положение курсора, имитация клика, эмуляция клика, эмуляция движения, имитация мыши, эмуляция мыши, координаты мыши, расположение мыши, расположение курсора.


Указатель мыши в точку координат курсора

auto-teacher

Дата: Суббота, 29.10.2016, 01:53 |
Сообщение № 1

Группа: Пользователи

Ранг: Новичок

Сообщений: 20


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Как сделать такой макрос, чтобы указатель мыши из любого места переместился туда, где стоит курсор?
Например, есть пример макроса с конкретными числами:
[vba]

Код

Private Declare Function SetCursorPos Lib «user32» (ByVal X As Long, ByVal Y As Long) As Long
‘ Устанавливаем координаты курсора в точку (300, 600)
Call SetCursorPos(300, 600)

[/vba]

А надо, чтобы в него вставились текущие координаты курсора.

Есть еще один макрос, определяющий координаты курсора:
[vba]

Код

Private Declare Function GetCursorPos Lib «user32» (lpPoint As POINTAPI) As Long

Private Type POINTAPI
X As Long
Y As Long
End Type

Dim z As POINTAPI

Private Sub Timer1_Timer()
GetCursorPos z
Label1 = «x: » & z.X
Label2 = «y: » & z.Y
End Sub

Private Sub Form_Load()
Timer1.Interval = 1
End Sub

[/vba]

Помогите, пожалуйста, их согласовать и расставить по порядку, а то я плохо в программировании подкован и не разбираюсь, где тут какие данные и тем более, какого они типа.


auto-teacher

Сообщение отредактировал auto-teacherСуббота, 29.10.2016, 02:10

 

Ответить

krosav4ig

Дата: Суббота, 29.10.2016, 04:56 |
Сообщение № 2

Группа: Друзья

Ранг: Старожил

Сообщений: 2346


Репутация:

989

±

Замечаний:
0% ±


Excel 2007,2010,2013


что конкретно понимаете под этим словом?
GetCursorPos определяет XY координаты указателя мыши относительно верхнего левого угла рабочего стола(экрана)


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460

Сообщение отредактировал krosav4igСуббота, 29.10.2016, 04:59

 

Ответить

auto-teacher

Дата: Понедельник, 31.10.2016, 14:36 |
Сообщение № 3

Группа: Пользователи

Ранг: Новичок

Сообщений: 20


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Спасибо за внимание! Подсказали — задачка решена.


auto-teacher

 

Ответить

Pelena

Дата: Понедельник, 31.10.2016, 14:38 |
Сообщение № 4

Группа: Админы

Ранг: Местный житель

Сообщений: 18797


Репутация:

4284

±

Замечаний:
±


Excel 2016 & Mac Excel

auto-teacher, поделитесь решением, кому-нибудь может пригодиться


«Черт возьми, Холмс! Но как??!!»
Ю-money 41001765434816

 

Ответить

auto-teacher

Дата: Пятница, 25.11.2016, 21:13 |
Сообщение № 5

Группа: Пользователи

Ранг: Новичок

Сообщений: 20


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Pelena!
Хорошо, пришлю.
Чтобы понять, зачем все это было нужно, требуется пояснение.
Если в доке есть сноска, ссылка или примечание, то при наведении на них указателя мыши всплывает подсказка.
Переходы по этим объектам я делаю горячими клавишами, используя штатные команды типа GoToNextFootnote.
Мне захотелось, чтобы подсказка всплыла без наведения указателя сразу после нахождения следующей сноски, то есть, автоматом.
Благодаря советам знатоков с нескольких форумов удалось решить несколько задач для достижения этой цели, создать макросы и даже обогатить их диалогами.
Перечислю по шагам используемые команды на обычном, человечьем языке (коды приведу на днях, потому что их надо привести в порядок для удобного понимания и потому, что там есть неожиданно найденное решение для использования самозакрывающихся диалоговых окон от Andrew Baker).
1) След. сноска.
2) Если сносок нет — сообщение, что их нет. (Закрывать окно не требуется, потому что оно гаснет через секунду).
3) Если курсор ниже последней сноски — сообщение с предложением искать выше. (Закрывать окно не требуется, потому что оно гаснет через секунду).
4) Если есть — переход курсора к след. сноске.
5) Если сноска последняя — сообщение об этом. (Закрывать окно не требуется, потому что оно гаснет через секунду).
6) Нахождение координат курсора.
7) Перевод указателя мыши на координаты курсора. (После этого перехода подсказка не всплывает.)
8) Имитация движения указателя мыши над сноской или, проще говоря, сдвиг указателя с найденных координат курсора на несколько пикселей вниз или в сторону. Как ни странно, эта мультипликация подействовала. Для этого применен цикл по таймеру системы. (Могу похвастаться, что это меня самого так осенило).
9) Подсказка всплывает и макрос заканчивается.

Продолжение следует…


auto-teacher

 

Ответить

auto-teacher

Дата: Пятница, 25.11.2016, 22:12 |
Сообщение № 6

Группа: Пользователи

Ранг: Новичок

Сообщений: 20


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Как известно, для просмотра и редактирования сносок, гиперссылок и примечаний есть встроенные макросы. Если это делать с ленты — то долго и нудно.
Автоматизации добиться можно только горячими клавишами.

Такие у меня стоят объявления (или как вы их там у себя называете) в модуле NewMacros (сверху — для курсора):

[vba]

Код

Private Declare Function GetCursorPos Lib «user32» (lpPoint As POINTAPI) As Long
Private Declare Function SetCursorPos Lib «user32» (ByVal X As Long, ByVal Y As Long) As Long
Private Type POINTAPI
X As Long
Y As Long
End Type

Public lRetVal As VbMsgBoxResult ‘ Постоянная часть процедуры всплывающего и гаснущего сообщения. См. модуль Messaging
Const interval As Long = 2500 ‘ Сообщения по умолчанию будут отображаться это время (в мсек), если не будут остановлены нажатием [ОК]. Можно ввести в конкретное сообщение число миллисекунд цифрами

[/vba]
____________________________________________________________________________
Такая должна быть макрокоманда (цикл по таймеру — моя фантазия), остальное все с форумов:

[vba]

Код

Sub СноскаОбычнаяСлед()
Dim cX As Long, cY As Long, i As Byte
If ActiveDocument.Footnotes.Count = 0 Then
        lRetVal = MsgboxOKDrop(«Обычных сносок еще никто не вставил!» & vbCrLf & _
        «Возможно, есть концевые сноски!», vbOKOnly + vbInformation, «Отсутствие сносок в тексте», interval)
    ElseIf Selection.StoryType = wdFootnotesStory Then ‘ Для концевых выбран другой вариант выделения
        Application.Run «GoToNextFootnote»
    Else ‘ Если курсор в основном тексте
        Application.Run «GoToNextFootnote»
            ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range
                For i = 0 To 2
                    SetCursorPos cX + i, cY + i
                    Dim Start
                    Start = Timer ‘ текущее время в секундах
                    Do While Timer < Start + 0.05
                    Loop
                Next i
Set R = Selection.Range
    If (R.Start <> Selection.Start) Or (R.END <> Selection.END) Then
    ElseIf Selection.Characters.First.Footnotes.Count <= 0 Then
        lRetVal = MsgboxOKDrop(«Ниже сносок больше нет!» & vbCrLf & _
        «Попробуй поискать вверх!», vbOKOnly + vbInformation, «Проверка сносок», interval)
        Exit Sub
    End If
Dim F As Footnote
    Set F = Selection.Characters.First.Footnotes(1)
    ‘ наличие следующей сноски
    Set R = Selection.Range.GoTo(What:=wdGoToFootnote, Which:=wdGoToNext, Count:=1)
    If R.Start <= Selection.Start Then
        lRetVal = MsgboxOKDrop(«Это последняя сноска в тексте!» & vbCrLf & _
        «Дальше можно не искать!», vbOKOnly + vbInformation, «Проверка сносок», interval)
    End If
    End If
End Sub

[/vba]


auto-teacher

Сообщение отредактировал auto-teacherПятница, 25.11.2016, 22:28

 

Ответить

auto-teacher

Дата: Пятница, 25.11.2016, 22:13 |
Сообщение № 7

Группа: Пользователи

Ранг: Новичок

Сообщений: 20


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

А это особый модуль гаснущего сообщения:

[vba]

Код

‘To display a timed Msgbox use the MsgboxOKDrop routine given below.
‘By Andrew Baker

Option Explicit

‘API calls for Msgbox2. Must be placed in a standard module
Private Declare Function SetTimer Lib «user32» (ByVal Hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib «user32» (ByVal Hwnd As Long, ByVal nIDEvent As Long) As Long
Private Declare Function FindWindow Lib «user32» Alias «FindWindowA» (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib «user32» Alias «SendMessageA» (ByVal Hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Private zsMessageTitle As String, lTimerId As Long

‘Purpose     :  Stops the timer routine
‘Inputs      :  N/A
‘Outputs     :  Returns True if the timer routine was stopped
‘Author      :  Andrew Baker
‘Date        :  15/10/2000 15:24
‘Notes       :  Code must be placed in a module
‘Revisions   :

Function EndTimer() As Boolean
    If lTimerId Then
        lTimerId = KillTimer(0&, lTimerId)
        lTimerId = 0
        EndTimer = True
    End If
End Function

‘Purpose     :  Starts the continuous calling of a private routine at a specific time interval.
‘Inputs      :  lInterval           The interval (in ms) at which to call the routine
‘Outputs     :  N/A
‘Author      :  Andrew Baker
‘Date        :  15/10/2000 15:30
‘Notes       :  Code must be placed in a module
‘Revisions   :

Sub StartTimer(lInterval As Long)
    If lTimerId Then
        ‘End Current Timer
        EndTimer
    End If
    lTimerId = SetTimer(0&, 0&, ByVal lInterval, AddressOf TimerRoutine)
End Sub

‘Purpose     :  Routine which is called repeatedly by the timer API.
‘Inputs      :  Inputs are automatically generated.
‘Outputs     :
‘Author      :  Andrew Baker
‘Date        :  15/10/2000 15:32
‘Notes       :
‘Revisions   :

Private Sub TimerRoutine(ByVal lHwnd As Long, ByVal lMsg As Long, ByVal lIDEvent As Long, ByVal lTime As Long)
    Const WM_CLOSE = &H10
    Dim lHwndMsgbox As Long

    ‘Find the Msgbox
    lHwndMsgbox = FindWindow(vbNullString, zsMessageTitle)
    ‘Close Msgbox
    Call SendMessage(lHwndMsgbox, WM_CLOSE, 0, ByVal 0&)
End Sub

‘Purpose     :  Extended version of Msgbox, has extra parameter to set time msgbox is displayed for
‘Inputs      :  As per Msgbox
‘               [DisplayTime]               The time in MS to display the message.
‘Outputs     :  As per Msgbox
‘Author      :  Andrew Baker
‘Date        :  03/01/2001 13:23
‘Notes       :
‘Revisions   :

Function MsgboxOKDrop(Prompt As String, Buttons As VbMsgBoxStyle, Title As String, Optional DisplayTime As Long = 3000) As VbMsgBoxResult
    If DisplayTime > 0 Then
        ‘Enable the timer
        StartTimer DisplayTime
        zsMessageTitle = Title
    End If
    MsgboxOKDrop = MsgBox(Prompt, Buttons, Title)
    ‘Stop the timer
    EndTimer
End Function

[/vba]

Если кому непонятно, как все это применить для гиперссылок и примечаний, — пришлю все, что у меня есть: полный набор макросов.


auto-teacher

 

Ответить

auto-teacher

Дата: Пятница, 25.11.2016, 22:30 |
Сообщение № 8

Группа: Пользователи

Ранг: Новичок

Сообщений: 20


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Пояснение.
Код цикла я, естественно, тоже где-то сдул. Фантазией было — применить его для имитации движения мыши.
Если кто-то знает, как «шевельнуть» мышь правильным способом — прошу сообщить.


auto-teacher

 

Ответить

Друзья, добрый день!
Решаю такую задачу: для работы макроса необходимо знать, где располагаются определенные элементы на мониторе в данный момент (расположение может быть разное, но в рамках одного цикла работы макроса элементы находятся в одном положении). Для этого хотелось бы, чтобы программа спросила через Inputbox или как-то еще, например, «Щелкните на элементе <плюсик>», пользователь щелкает мышкой на плюсике (либо же наводит на плюсик и нажимает какую-то кнопку, если мышкой нельзя щелкать) и координаты мыши добавляются в переменную, с которой потом уже будем работать.

Нашел такой код:

Код

Он отлично работает, встаю мышью куда мне надо, нажимаю F5, получаю координаты.
Как это реализовать применимо к описанной выше идее, что это должен быть диалог с пользователем?
Нужно какую-то свою форму рисовать? Покажите, пожалуйста, на примере «появилось окно с просьбой указать элемент — я кликаю на элемент — координаты попали в переменную».

Спасибо.

Update: или вот еще какую красоту нашел :-) (если запустить, и таймер бегает и в режиме реального времени координаты отображаются). Как прикрутить, чтобы спрашивало у пользователя кликнуть в точку, у которой нужно получить координаты.

Код

Изменено: whateverlover18.10.2021 15:29:05

Понравилась статья? Поделить с друзьями:
  • Vba excel как узнать имя пользователя
  • Vba excel как узнать имя активного листа
  • Vba excel как узнать защищен ли лист
  • Vba excel как узнать если лист
  • Vba excel как узнать длину массива