Excel движения мыши excel vba

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


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


 

добрый день!  

  программа висит в процессах и каждые 4 минуты сдвигает мышку на 1 пиксель влево-на 1 пиксель вправо. такое сложно написать? :)

 

Это чтобы скринсейвер не включался, что ли?  
Вот простой VBS скрипт, который периодически «нажимает» кнопку F15. Про эту кнопку «не знают» 99,99% программ, так что риск от нажатия этой кнопки ничтожен.  
Время в 3-й строке задается в миллисекундах  

  Set ws = CreateObject(«WScript.Shell»)  
Do  
Wscript.Sleep 240000  
ws.SendKeys «{F15}»  
Loop  

  Сохраняйте как .VBS и запускайте. Можно в автозагрузку.

 

{quote}{login=Казанский}{date=14.02.2011 05:53}{thema=}{post}  
Вот простой VBS скрипт, который периодически «нажимает» кнопку F15. Про эту кнопку «не знают» 99,99% программ,    
S{/post}{/quote}А что за кнопка? у меня последняя F12

 

vikttur

Пользователь

Сообщений: 47199
Регистрация: 15.09.2012

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

 
 

Казанский  
спасибо, вы меня правильно поняли :)  
только там не скринсейвер включается, а через 5 минут происходит блокировка рабочей станции. а у меня их две.  

  я правильно понимаю, Wscript.Sleep 240000 — задержка в 4 минуты?  

  Юрий М  
познавателыный топик, спасибо :) хороший пример

 

> там не скринсейвер включается, а через 5 минут происходит блокировка рабочей станции  
Проверял — работает против блокировки.  

  > я правильно понимаю, Wscript.Sleep 240000 — задержка в 4 минуты?  
да  

  > Михаил: А что за кнопка? у меня последняя F12  
У меня тоже :) Но в описании метода SendKeys упоминается даже F16! Видимо, есть зарезервированные коды кнопок F13-F16, которые распознаются ОС.

 

DJ_Serega

Пользователь

Сообщений: 109
Регистрация: 01.01.1970

{quote}{login=Казанский}{date=14.02.2011 05:53}{thema=}{post}Это чтобы скринсейвер не включался, что ли?  
Вот простой VBS скрипт, который периодически «нажимает» кнопку F15. Про эту кнопку «не знают» 99,99% программ, так что риск от нажатия этой кнопки ничтожен.  
Время в 3-й строке задается в миллисекундах  

  Set ws = CreateObject(«WScript.Shell»)  
Do  
Wscript.Sleep 240000  
ws.SendKeys «{F15}»  
Loop  

  Сохраняйте как .VBS и запускайте. Можно в автозагрузку.{/post}{/quote}  
на любом семействе win будет работать? ;)

I love 1C. I love CS 1.6 :)      

 

dd2d

Гость

#10

15.02.2011 17:33:11

{quote}{login=Казанский}{date=15.02.2011 03:37}{thema=}{post}> там не скринсейвер включается, а через 5 минут происходит блокировка рабочей станции  
Проверял — работает против блокировки.  

  > я правильно понимаю, Wscript.Sleep 240000 — задержка в 4 минуты?  
да  

  > Михаил: А что за кнопка? у меня последняя F12  
У меня тоже :) Но в описании метода SendKeys упоминается даже F16! Видимо, есть зарезервированные коды кнопок F13-F16, которые распознаются ОС.{/post}{/quote}  

  я тоже сейчас проверил, замечательно работает :) спасибо

You could use Excel VBA to move the mouse and click on things (left and right click). Below is an example of moving the mouse to the top left of the screen and then clicking. Just copy the code and paste it into macro window in Excel.

The SingleClick() subroutine is a single click, while DoubleClick() subroutine does a double click. The code is quite self explanatory and needs minimal instructions.

Note that SetCursorPos moves the mouse based on the coordinates supplied. The first parameter is the # of pixels to the right from the top left corner of the monitor (x-axis) and the second parameter is the # of pixels below the top left corner of the monitor (y-axis). If the user is using duel monitors, it will be top left corner of the the left most monitor.

Public Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Public 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)
Public Const MOUSEEVENTF_LEFTDOWN = &H2
Public Const MOUSEEVENTF_LEFTUP = &H4
Public Const MOUSEEVENTF_RIGHTDOWN As Long = &H8
Public Const MOUSEEVENTF_RIGHTUP As Long = &H10

Private Sub SingleClick()
  SetCursorPos 100, 100 'x and y position
  mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
  mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
End Sub

Private Sub DoubleClick()
  'Double click as a quick series of two clicks
  SetCursorPos 100, 100 'x and y position
  mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
  mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
  mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
  mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
End Sub

Private Sub RightClick()
  'Right click
  SetCursorPos 200, 200 'x and y position
  mouse_event MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0
  mouse_event MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0
End Sub

  20 people found this article useful

  20 people found this article useful

Лучший ответ Сообщение было отмечено как решение

Решение

Ура! Наконец-то разобрался как это сделать приемлимым способом =)

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

Visual Basic
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
'Подключение функции API Windows "mouse_event" из Виндосовской библиотеки "user32", которая позваляет управлять мышью
Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal dwData As Long, ByVal dwExtraInfo As Long)
'Значения параметра dwFlags, определяющие поведение функции mouse_event
Private Const MOUSEEVENTF_LEFTDOWN = &H2  'Нажать левую кнопку
Private Const MOUSEEVENTF_LEFTUP = &H4  'Отпустить левую кнопку
 
'Подключение функции API Windows "SetCursorPos", которая устанавливает позицию курсора мыши по координатам, соответствующим разрешению вашего монитора
Private Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
 
'Подключение функции API Windows "Sleep", её можно использовать вместо таймера, выставляя задержки в милисекундах
Private Declare Sub Sleep Lib "kernel32" (ByVal milliseconds As Long)
 
Sub MouseDragging(x1, y1, x2, y2) 'Перетаскивание объекта из координаты (x1,y1) в координаты (x2,y2)или выделение текста/изображения в прямоугольной области (x1, y1; x2, y2)
Call SetCursorPos(x1, y1)
mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
Call SetCursorPos(x2, y2)
mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
End Sub
 
Sub MouseClick(x, y) 'Клик мыши по координатам (x,y)
Call SetCursorPos(x, y)
mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
End Sub
 
Private Sub CommandButton1_Click()
Sleep (500)
Call MouseDragging(889, 490, 388, 467)
Sleep (2000)
Call MouseClick(768, 419)
End Sub

Управление мышью осуществляется с помощью стандартной функции API Windows под названием «mouse_event», чтобы она заработала, надо вставить строку «Private Declare Sub mouse_event…» в точности, как показано сверху в коде VB. Для того чтобы указать этой функции, что конкретно надо сделать, нужно установить параметр dwFlags, который может принимать следующие значения:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'Возможные значения параметра dwFlags, определяющие поведение функции mouse_event
Private Const MOUSEEVENTF_ABSOLUTE = &H8000  'Абсолютное перемещение
Private Const MOUSEEVENTF_LEFTDOWN = &H2  'Нажать левую кнопку
Private Const MOUSEEVENTF_LEFTUP = &H4  'Отпустить левую кнопку
Private Const MOUSEEVENTF_MIDDLEDOWN = &H20  'Нажать среднюю кнопку
Private Const MOUSEEVENTF_MIDDLEUP = &H40  'Отпустить среднюю кнопку
Private Const MOUSEEVENTF_RIGHTDOWN = &H8  'Нажать правую кнопку
Private Const MOUSEEVENTF_RIGHTUP = &H10  'Отпустить правую кнопку
Private Const MOUSEEVENTF_MOVE = &H1  'Переместить курсор
Private Const MOUSEEVENTF_WHEEL = &H800  'Вращение вертикального колеса мыши (если оно есть)
Private Const MOUSEEVENTF_HWHEEL = &H1000  'То ли вращение горизонтального колеса мыши, толи наклон вправо/влево обыного колеса мыши
Private Const MOUSEEVENTF_XDOWN = &H80  'Нажать на одну из дополнительных кнопок "Х" (номер кнопки задается параметром dwData)
Private Const MOUSEEVENTF_XUP = &H100  'Отпустить  кнопку "Х"
'Дополнительный параметр dwData, определяет поведение функции mouse_event
'при использовании dwFlags = MOUSEEVENTF_WHEEL, MOUSEEVENTF_HWHEEL, MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP

Наиболее подробная информация о функциональности этих всех параметров содержится на сайте майкрософт (на английском) Например, с помощью параметра MOUSEEVENTF_ABSOLUTE можно задавать координаты мыши с высокой точностью в диапазоне от 0 до 65535 по осям x и y. Правда мне так и не удалось понять, как работает этот параметр, у меня он вобще никакого влияния не оказывал на перемещение курсора, как я только над ним не извращался =)

Помучавшись, обнаружил прекрасную функцию «SetCursorPos», которая так же входит в стандартный набор Виндоус. Она четко ставит укозатель мыши в нужную позицию с координатами, соответствующими разрешению экрана (Например от 0х0 до 1280х800) независимо от настроек чувствительности и ускорения мыши, что очень удобно.

Для работы с медленно прогружающимися объектами (например с сайтами в интернете или тяжеловесными программами) бывает необходимо добавить временную задержку между кликами мыши на различные меню. Поскольку в VBA повидимому нет объекта типа таймера, то вместо него отлично подходит ещё одна стандартная функция Виндовс «Sleep», которая позваляет задавать задержку в милисекундах, что бывает даже удобнее.

Мне необходимо было использовать в своей основной программе две вещи — это перетаскивание объекта из точки 1 в точку 2 и клик мышкой в точке с заданными координатами (например на кнопку). Для реализации каждого из этих действий можно использовать связку из нескольких функций «SetCursorPos» и «mouse_event», но удобнее написать свои процедуры, котарые потом вставлять каждый раз в нужное место, что я и сделал в виде процедур «MouseDragging» и «MouseClick».

Процедура «MouseDragging(x1, y1, x2, y2)» с помощью функции «SetCursorPos(x1, y1)» устанавливает курсор над нужным объектом в координатах (x1, y1), затем с помощью «mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0» нажимает левую кнопку мыши и как бы удерживая её, перетаскивает обект в точку с координатами (x2, y2) с помощью функции «SetCursorPos(x2, y2)». Затем отпускает кнопку мыши с помощью функции «mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0».
С помощью процедуры «MouseDragging(x1, y1, x2, y2)» можно также выделить область текста в Ворде, несколько объектов в Экселе, Автокаде или часть изображения в Пэйнте.

Процедура «MouseClick(x, y)» выполняет клик мышью в точке с координатами (x, y). Сначала устанавливает указатель мыши с помощью функции «SetCursorPos(x, y)» в нужной точке, затем с помощью функции «mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0» совершает клик мышью в этой точке. Причем интересно, что запись параметра dwFlags в виде «MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP» сразу же обеспечивает и нажатие левой кнопки мыши и отпускание.

Здесь x, y, x1, y1, x2, y2 играют роль параметров, вместо которых мы при вызове процедур подставляем нужные нам значения.

Теперь вставляем всё это в процедуру нажатия на кнопку Button1, расположенную где-нибудь на нашей форме, и получаем следующее: при нажатии на кнопку происходит задержка 0,5 секунды, затем перетаскивание объекта из координат (889, 490) в точку с координатами (388, 467), затем после задержки в 2,0 секунды выполняется клик мышкой в точке с координатами (768, 419)

Может быть кому-то покажется странным такое длинное описание столь простой задачи, но мне пришлось потратить около месяца времени, чтобы разобраться во всем этом и найти подходящие решения. Надеюсь что данное описание поможет таким же чайникам как я разобраться в этом гораздо быстрее ;-)



19



I have not been able to figure out how to run an Excel macro by moving
my mouse over one or more cells in my spreadsheet.

Rhys Gibson's user avatar

Rhys Gibson

4,5183 gold badges41 silver badges45 bronze badges

asked Aug 24, 2014 at 23:34

Reggie Royal's user avatar

Whilst there is no formal OnMouseOver event, you can put together a VBA hack to get around it. It involves using the HYPERLINK function. There’s more detail here, but in summary:

If you create a new VBA module and then add a User Defined Function to do what you want:

Public Function OnMouseOver()
 Sheet1.Range("A2").Value = "You hovered over a cell"
End Function

You can then access this via a HYPERLINK call:

=IFERROR(HYPERLINK(OnMouseOver(),"Click here"), "Click here")

Note that it’s wrapped inside an IFERROR to avoid a #VALUE! error message because your function isn’t supposed to update a cell (but gets away with it as it’s called within HYPERLINK).

answered Aug 25, 2014 at 1:24

Rhys Gibson's user avatar

Rhys GibsonRhys Gibson

4,5183 gold badges41 silver badges45 bronze badges

1

There is no OnMouseOver in Excel VBA. I do not believe it can be done.

answered Aug 25, 2014 at 0:14

Keltari's user avatar

KeltariKeltari

71.4k26 gold badges178 silver badges228 bronze badges

1

The HYPERLINK approach is cute, very shrewd, but still deeply limited. E.g. you can’t even have sStr = «» in the UDF code (note, results may vary by Excel version). Much better is a transparent (or even opaque) label, which does have the MouseMove property. Put your code there instead. (I located a video link that nearly perfectly efficiently gives it to you step-by-step in under 4 minutes, with even better comments; if I created a step-by-step guide here you’d spend a half an hour :) . But if I show the link, this post will be deleted [again] by Stack Exchange, so PM me if you want it, and I’ll try to respond within a few days.)

answered Mar 14, 2016 at 15:54

MicrosoftShouldBeKickedInNuts's user avatar

4

You can use transparent ActiveX Label (.BackStyle = fmBackStyleTransparent, .Caption = "", .Visible = True) over the cells and handle it’s MouseMove event:

Private Sub Label1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Debug.Print Button, Shift, X, Y
End Sub

When the Label’s .Visible property is set to False, the MouseMove event will not trigger, but the cells behind it can be clicked (and vice-versa).

answered Jan 12, 2017 at 15:17

Slai's user avatar

SlaiSlai

1195 bronze badges

1

Понравилась статья? Поделить с друзьями:

А вот еще интересные статьи:

  • Excel движение по столбцам
  • Excel движение по листам
  • Excel двигаться по листам
  • Excel двигать стрелкой экран
  • Excel двигается лист а не ячейка

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии