Excel vba не работает прокрутка

  • Remove From My Forums

 locked

EXCEL — VBA — TextBox — Scrolling Problem ( when textbox activated defaults to the bottom of text )

  • Question

  • Hi Friends

    I have a problem with a textbox in which I have a lot of text.

    I have activated the Vertical Scrollbar and also the Multiline is set to TRUE.

    This all works fine the only problem I have is that when the textbox becomes active its shows the text from teh bottom or in other words the scroll bar is at the bottom instead of the top of the text.

    As it is a little help file within my project you don’t really want the user to start reading it from the end.

    HOW CAN I FIX THIS?

    Thank you in advance everyone.


    Marcin

Answers

  • The textbox will scroll to where the last insertion point was. To get around this I set the CurLine property to 1 on the GotFocus event…

    Private Sub TextBox1_GotFocus()
         TextBox1.CurLine = 1
    End Sub


    «The new phonebooks are here!»

    • Proposed as answer by

      Thursday, October 1, 2009 10:15 PM

    • Marked as answer by
      martin.thardis
      Friday, October 2, 2009 10:36 AM

  • SUZNAL you are the GOD (or GODDESS) :-)

    that code is just small, quick and what I needed!

    The other bit of code also worked, but is bigger, messier and hanged my Excel…

    ;-)


    Marcin

    • Marked as answer by
      martin.thardis
      Friday, October 2, 2009 10:36 AM

 

kaa

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

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

всем привет.  

  давно хотел спросить, но все время забывал: у меня одного не работает скролл в редакторе? если да, то как лечить?

 

kaa

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

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

всем привет.  

  давно хотел спросить, но все время забывал: у меня одного не работает скролл в редакторе? если да, то как лечить?

 

У всех, но лечится.  
Тут на формуме было, но выложу, так как искать…  
В приблуде, кроме скролла еще пара полезных примочек

 

У всех, но лечится.  
Тут на формуме было, но выложу, так как искать…  
В приблуде, кроме скролла еще пара полезных примочек

 

kaa

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

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

 

kaa

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

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

 

{quote}{login=kaa}{date=21.02.2008 01:16}{thema=скролл в редакторе VBA}{post}всем привет.  

  давно хотел спросить, но все время забывал: у меня одного не работает скролл в редакторе? если да, то как лечить?{/post}{/quote}  

  шо це таке? колесиком шо ли?  
у мине робит..

 

{quote}{login=kaa}{date=21.02.2008 01:16}{thema=скролл в редакторе VBA}{post}всем привет.  

  давно хотел спросить, но все время забывал: у меня одного не работает скролл в редакторе? если да, то как лечить?{/post}{/quote}  

  шо це таке? колесиком шо ли?  
у мине робит..

 

kaa

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

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

ага…  

  у меня теперь тоже   :)

 

drony

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

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

 

я пользуюсь драйвером мышы :

 

я пользуюсь драйвером мышы :

 
 

Hugo

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

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

У меня на работе всегда скролл работал, и ещё есть программа, где в определённой ситуации скролл работает только на работе. Мышь IBM, драйвер Mouse Suite.  
А дома пришлось для VBA спецпрогу пользовать, а та другая программа не мотает.

 

Guest

Гость

#15

19.06.2010 11:21:36

{quote}{login=*}{date=18.06.2010 04:43}{thema=}{post}Ребятя, СПАСИБО БОЛЬШОЕ!{/post}{/quote}  

  лучше позже :)

Прокрутка листа или обновление экрана?

Невилл

Дата: Суббота, 12.11.2016, 14:50 |
Сообщение № 1

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

Ранг: Участник

Сообщений: 79


Репутация:

2

±

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


Excel 2007

Ребята, буду очень благодарен, если подскажете, в чем проблема с этим файлом.
ПРЕДУПРЕЖДЕНИЕ: после исполнения макроса на листе «Звіт» у меня перестает работать то ли прокрутка листа, то ли ScreenUpdating (хотя, если верить vba, то вроде True) и сам файл закрыть получалось только с Ctrl+Alt+Del. Так что перед открытием, лучше закрыть свои другие файлы.
Подробности вот в анимашке:
Эта проблема у меня возникла дома на Excel2016, с Excel2010 на работе ничего подобного не было. И никак не могу ее решить…
Притом, в перспективе этот файл использовать придется ежедневно, и возможно, не только мне. Надо определить причину проблемы как-то…

Вкратце, я сейчас разрабатываю систему учета дебиторки. После нажатия на кнопку «Отчет» должна запуститься юзерформа.
После выбора параметров она их передает в Generate_Report и та, в свою очередь формируется отчет, обрабатывая данные других листов.

В оригинальном файле десятки тысяч строк, потому выполнение макроса без отключения ScreenUpdating и Calculation(Auto) ждать слишком долго.
В отдельном модуле OptimizeCode есть соответствующие процедуры. Может с ним, что не так? Хотя этот модуль от проекта к проекту копирую, проблем раньше не было.

Никто не сталкивался с чем-то подобным? Где я допустил ошибку? Связано ли это с юзерформой как-то?
Если можете, отпишите, у всех ли подобная проблема с этим файлом наблюдается (и версию офиса, пожалуйста).

К сообщению приложен файл:

0720693.xlsm
(80.5 Kb)

 

Ответить

Невилл

Дата: Суббота, 12.11.2016, 15:08 |
Сообщение № 2

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

Ранг: Участник

Сообщений: 79


Репутация:

2

±

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


Excel 2007

Хм… Попробовал еще раз поочередно поотключать процедуры, чтобы локализовать проблему.

Вероятно, моя проблема как-то связана вот с этими строчками в процедуре cmdGenerate_Click (в конце)
[vba]

Код

    ThisWorkbook.Sheets(«Звіт»).Activate
    ThisWorkbook.Sheets(«Звіт»).Cells(2, 1).Select

[/vba]
Только не пойму, почему именно происходит сбой…

 

Ответить

fairylive

Дата: Суббота, 12.11.2016, 16:54 |
Сообщение № 3

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 122


Репутация:

4

±

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


Excel 2016

А если отдельно сделать кнопку с процедурой
[vba]

Код

Sub ScreenUpdating()

Application.ScreenUpdating = True

End Sub

[/vba]
Иногда бывает макрос не доходит до конца, ошибки там всякие и так далее и обновление экрана не включается. Сам мучался. Потом как только заглючит таким образом жму кнопку — обновлять экран. Если дело в этом то допиши в конец программы оператор [vba]

Код

Аpplication.ScreenUpdating = True

[/vba]

 

Ответить

KuklP

Дата: Суббота, 12.11.2016, 18:30 |
Сообщение № 4

Группа: Проверенные

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

Сообщений: 2369


Репутация:

486

±

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


2003-2010

А если отдельно сделать кнопку с процедурой

У автора и так эта процедура отдельная. И нет смысла делать еще и кнопку. Есть волшебная клавишка F9 и волшебное слово Stop если уж совсем извращаться. Все это применимо к процедуре:
[vba]

Код

Sub OptimizeCode_End()
    Application.EnableEvents = True
    Stop
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
End Sub

[/vba]
У меня все отрабатывает без запинки, но на 2010. 2016 нет и ставить не планирую, поэтому помочь видимо, не смогу. :(


Ну с НДС и мы чего-то стoим! kuklp60@gmail.com
WM Z206653985942, R334086032478, U238399322728

 

Ответить

KuklP

Дата: Суббота, 12.11.2016, 18:36 |
Сообщение № 5

Группа: Проверенные

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

Сообщений: 2369


Репутация:

486

±

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


2003-2010

Невилл, попробуйте вместо двух строк вот это:
[vba]

Код

   Application.Goto Sheets(«Звіт»).Cells(2, 1)

[/vba]Наверняка проблему не решит, но снимет Ваши подозрения с тех строк :)


Ну с НДС и мы чего-то стoим! kuklp60@gmail.com
WM Z206653985942, R334086032478, U238399322728

 

Ответить

fairylive

Дата: Суббота, 12.11.2016, 18:44 |
Сообщение № 6

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 122


Репутация:

4

±

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


Excel 2016

У меня все отрабатывает без запинки, но на 2010.

А на 2016 спотыкается на какой-то ошибке. До глюка на как на картинке не добрался, чтобы проверить свою идею.

 

Ответить

KuklP

Дата: Суббота, 12.11.2016, 18:55 |
Сообщение № 7

Группа: Проверенные

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

Сообщений: 2369


Репутация:

486

±

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


2003-2010

До глюка на как на картинке не добрался

Т.е. у Вас 2016 и ситуации описанной автором, не возникает? Тогда может есть смысл говорить(возможно) о некорректной установке Офиса у автора? Стоит подождать других форумчан-обладателей 2016. Ребят пожалуйста, подтвердите или опровергните наличие глюка, описанного автором.


Ну с НДС и мы чего-то стoим! kuklp60@gmail.com
WM Z206653985942, R334086032478, U238399322728

 

Ответить

Невилл

Дата: Суббота, 12.11.2016, 20:40 |
Сообщение № 8

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

Ранг: Участник

Сообщений: 79


Репутация:

2

±

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


Excel 2007

Спасибо всем, кто попробовал файл. Значит, скорее всего какой-то конфликт с 2016 офисом. Хотя, имхо, в таком странном месте, что не понимаю совсем. И реально этот «глюк» вызывается все же активацией листа. Все уже перепробовал, что знал. Безуспешно…

KuklP, попробовал Application.Goto и в конце макроса формы, и потом перенес его в основной модуль. Оба раза повторился тот же глюк, что на анимации. Еще попробовал set wksReport = ThisWorkbook…, тоже без разницы. Имя листа писал латиницей, удалял его…

fairylive, а не могли бы Вы подсказать, что за ошибку выдает файл и в каком месте? Был бы очень признателен за скриншот или краткое описание.

 

Ответить

Невилл

Дата: Суббота, 12.11.2016, 20:54 |
Сообщение № 9

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

Ранг: Участник

Сообщений: 79


Репутация:

2

±

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


Excel 2007

P.S. Пока такой костыль прикрутил:
[vba]

Код

Sub CommandButton1_Click()
    ThisWorkbook.Sheets(«Звіт»).Select
    ReportMaster.Show
End Sub

[/vba]
Выходит, что проблема проявляется, если активировать, выделять или переходить на лист в процессе формирования отчета или выхода из юзерформы… А вот, если сделать это перед запуском ЮФ, то все норм? Ну, ок :(

Сообщение отредактировал НевиллСуббота, 12.11.2016, 20:55

 

Ответить

fairylive

Дата: Суббота, 12.11.2016, 22:33 |
Сообщение № 10

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 122


Репутация:

4

±

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


Excel 2016

Невилл, опиши последовательность действий которую надо сделать. Я просто открыл файл (предварительно разблокировав его в свойствах) и нажал на кнопку, после чего появляется форма. Там что надо выбирать? Я просто жму кнопку опять. Что должно произойти? На анимации не очень видны первые действия. Вобщем вот снимки экрана.
PS пока делал снимки разобрался в чем дело. Ошибки у меня возникали так как у меня нет таких стилей — Заголовок 1, Заголовок 2 и Примечание. Заменил их на те что у меня есть Обычный 2. Программа стала выполняться. Глюк подтверждаю. И как говорил раньше он лечится макросом. У меня этот макрос на отдельной кнопке на моей вкладке с моими макросами
[vba]

Код

Sub ScreenUpdating()

Application.ScreenUpdating = True

End Sub

[/vba]
Просто вставь в самую последнюю процедуру в конец Application.ScreenUpdating = True
Я не знаю какая последняя. Поэтому не проверял сработает или нет. Но по идее должно.

Сообщение отредактировал fairyliveСуббота, 12.11.2016, 22:37

 

Ответить

wild_pig

Дата: Суббота, 12.11.2016, 23:01 |
Сообщение № 11

Группа: Проверенные

Ранг: Обитатель

Сообщений: 516


Репутация:

97

±

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


2003, 2013

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

 

Ответить

Невилл

Дата: Воскресенье, 13.11.2016, 10:45 |
Сообщение № 12

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

Ранг: Участник

Сообщений: 79


Репутация:

2

±

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


Excel 2007

fairylive, ScreenUpdating не помогло, увы. У меня в коде он, к слову, как раз в конце и использовался.
Я понимаю, в чем суть, но такое решение мне не подходит (лишние кнопки другие пользователи нажимать не захотят, да и должно оно работать само). Как сказал wild pig, ручной переход между листами тоже решает проблема. Еще если зайти в VBA и выйти, экран тоже раздупляется.

Спасибо за подсказку по стилям. Честно сказать, думал, что стили вместе с файлом сохраняются, а не зависят от версии офиса. Попробую разобраться, как их зафиксировать точно.

UPD:
Если не затруднит, проверьте еще разок мой файл (на 2013 и 2016), пожалуйста. Попробовал стили прописать, как советовали на одном западном форуме, а активацию листа перенес до выполнения самого макроса. У меня на 2016 уже работает, но уверенность пошатнулась уже <_<

К сообщению приложен файл:

5276513.xlsm
(81.5 Kb)

 

Ответить

KuklP

Дата: Воскресенье, 13.11.2016, 13:20 |
Сообщение № 13

Группа: Проверенные

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

Сообщений: 2369


Репутация:

486

±

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


2003-2010

Невилл, Вы можете еще в чисто исследовательских целях скопировать данные в новый файл, пересоздать там формы и скопировать туда код. Бывало и уже не раз, в том числе на этом форуме, что виной был глючный файл. После вышеуказанных действий проблема исчезала. Только не копируйте листы и формы, а именно пересоздайте.


Ну с НДС и мы чего-то стoим! kuklp60@gmail.com
WM Z206653985942, R334086032478, U238399322728

 

Ответить

fairylive

Дата: Воскресенье, 13.11.2016, 15:01 |
Сообщение № 14

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 122


Репутация:

4

±

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


Excel 2016

Невилл, Про кнопку я всего лишь говорил что это проверка. У меня она решала проблему. Значит надо подправить код в нужном месте.
Проверил последний файл. Всё чётко. Без глюков и ошибок.

 

Ответить

HeinzBr

Дата: Пятница, 16.11.2018, 16:41 |
Сообщение № 15

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

Ранг: Прохожий

Сообщений: 1


Репутация:

0

±

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


Excel 2016

Понимаю, что прошло два года, но сам столкнулся с такой же проблемой и очень долго искал ответ.
Возможно, кому-нибудь поможет: необходимо установить свойство формы Showmodal = False, после этого страница нормально работает и скроллится.

 

Ответить

У меня в редакторе VBA не работает колесо мышки (Excel2000). Это у всех так?

6 ответов

Цитата:

Originally posted by gacol
У меня в редакторе VBA не работает колесо мышки (Excel2000). Это у всех так?

Должно работать. А что за мышь?

258

05 мая 2003 года

SergeySV

1.5K / / 19.03.2003

У меня на работе стояла мышь — Genius NetScroll+, которая по умолчанию стояла в системе как Microsoft Mouse (IntellMouse) или что-то в этом роде, вообщем что-то такое стандартное Microsft’кое для мышей без своих дров. При этом колесико везде работало, кроме VBA редакторов (в Excel, Access и т.д.)
Потом поставил родные драйверы от Genius и теперь везде колесико работает… проблема как правила в дровах, родные обычно должны везде работать (если их хорошо написали, хотя бывают и исключения)

Цитата:

Originally posted by SergeySV
У меня на работе стояла мышь — Genius NetScroll+, которая по умолчанию стояла в системе как Microsoft Mouse (IntellMouse) или что-то в этом роде, вообщем что-то такое стандартное Microsft’кое для мышей без своих дров. При этом колесико везде работало, кроме VBA редакторов (в Excel, Access и т.д.)
Потом поставил родные драйверы от Genius и теперь везде колесико работает… проблема как правила в дровах, родные обычно должны везде работать (если их хорошо написали, хотя бывают и исключения)

К Нетскролл+ обязательно надо дрова ставить — они «умощняют» эту мышь значительно.

459

05 мая 2003 года

gacol

273 / / 12.02.2003

Цитата:

Originally posted by SergeySV
У меня на работе стояла мышь — Genius NetScroll+, которая по умолчанию стояла в системе как Microsoft Mouse (IntellMouse) или что-то в этом роде, вообщем что-то такое стандартное Microsft’кое для мышей без своих дров. При этом колесико везде работало, кроме VBA редакторов (в Excel, Access и т.д.)
Потом поставил родные драйверы от Genius и теперь везде колесико работает… проблема как правила в дровах, родные обычно должны везде работать (если их хорошо написали, хотя бывают и исключения)

Спасибо! Теперь заживу.
(И Gutty S. тоже мерси боку)

36K

09 марта 2008 года

Euga

3 / / 09.03.2008

На некоторых крысках действительно не работает прокрутка в VBA, даже если все дрова поставлены. Есть полезная прога — прилепил линк в конце сообщения, после ее установки в настройках нужно поставить Enhanced Mode — и прокрутка будет работать!
Прога: http://depositfiles.com/files/4017012

21K

10 марта 2008 года

tolikt

3 / / 25.09.2006

Давно делал, чтоб работало колёсико, но быстро убрал. Ибо тогда другая проблема: при предпросмотре (надо мне!) движение колёсика перелистывает не по одной странице, а по несколько (причём непостоянное количество!). Так что из двух зол оставил меньшее зло — несрабатывание колёсика в VBA.
Мышь A4-Tech NB-50 — самая суперная мышь!

Пользовательские формы изначально не поддерживают прокрутку колесиком мыши (AFAIK)

Я публикую код здесь, чтобы был доступен 64-битный ответ.


На основе этот ответ


Шаги:

1- Добавьте этот код в свою пользовательскую форму:

Private Sub UserForm_Initialize() 
    HookFormScroll Me 
End Sub 
 
 
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) 
    UnhookFormScroll 
End Sub 

2-Добавьте одно из следующего к Module в зависимости от архитектура вашего офиса

Если Office находится на 32-разрядной версии:

Option Explicit 
 ' Based on code from Peter Thornton here:
 ' http://social.msdn.microsoft.com/Forums/en-US/7d584120-a929-4e7c-9ec2-9998ac639bea/mouse-scroll-in-userform-listbox-in-excel-2010?forum=isvvba
Private Type POINTAPI 
    x                               As Long 
    y                               As Long 
End Type 
Private Type MOUSEHOOKSTRUCT 
    pt                              As POINTAPI 
    hwnd                            As Long 
    wHitTestCode                    As Long 
    dwExtraInfo                     As Long 
End Type 
 
Private Declare Function FindWindow Lib "user32" _ 
Alias "FindWindowA" ( _ 
ByVal lpClassName As String, _ 
ByVal lpWindowName As String) As Long 
 
Private Declare Function GetWindowLong Lib "user32.dll" _ 
Alias "GetWindowLongA" ( _ 
ByVal hwnd As Long, _ 
ByVal nIndex As Long) As Long 
 
Private Declare Function SetWindowsHookEx Lib "user32" _ 
Alias "SetWindowsHookExA" ( _ 
ByVal idHook As Long, _ 
ByVal lpfn As Long, _ 
ByVal hmod As Long, _ 
ByVal dwThreadId As Long) As Long 
 
Private Declare Function CallNextHookEx Lib "user32" ( _ 
ByVal hHook As Long, _ 
ByVal nCode As Long, _ 
ByVal wParam As Long, _ 
lParam As Any) As Long 
 
Private Declare Function UnhookWindowsHookEx Lib "user32" ( _ 
ByVal hHook As Long) As Long 
 
Private Declare Function PostMessage Lib "user32.dll" _ 
Alias "PostMessageA" ( _ 
ByVal hwnd As Long, _ 
ByVal wMsg As Long, _ 
ByVal wParam As Long, _ 
ByVal lParam As Long) As Long 
 
Private Declare Function WindowFromPoint Lib "user32" ( _ 
ByVal xPoint As Long, _ 
ByVal yPoint As Long) As Long 
 
Private Declare Function GetCursorPos Lib "user32.dll" ( _ 
ByRef lpPoint As POINTAPI) As Long 
 
Private Const WH_MOUSE_LL          As Long = 14 
Private Const WM_MOUSEWHEEL        As Long = &H20A 
Private Const HC_ACTION            As Long = 0 
Private Const GWL_HINSTANCE        As Long = (-6) 
 
Private Const WM_KEYDOWN           As Long = &H100 
Private Const WM_KEYUP             As Long = &H101 
Private Const VK_UP                As Long = &H26 
Private Const VK_DOWN              As Long = &H28 
Private Const WM_LBUTTONDOWN       As Long = &H201 
 
Private Const cSCROLLCHANGE        As Long = 10 
 
Private mLngMouseHook              As Long 
Private mFormHwnd                  As Long 
Private mbHook                     As Boolean 
Dim mForm                          As Object 
 
 
Sub HookFormScroll(oForm As Object) 
    Dim lngAppInst                  As Long 
    Dim hwndUnderCursor             As Long 
     
    Set mForm = oForm 
    hwndUnderCursor = FindWindow("ThunderDFrame", oForm.Caption) 
    Debug.Print "Form window: " & hwndUnderCursor 
    If mFormHwnd <> hwndUnderCursor Then 
        UnhookFormScroll 
        Debug.Print "Unhook old proc" 
        mFormHwnd = hwndUnderCursor 
        lngAppInst = GetWindowLong(mFormHwnd, GWL_HINSTANCE) 
        If Not mbHook Then 
            mLngMouseHook = SetWindowsHookEx( _ 
            WH_MOUSE_LL, AddressOf MouseProc, lngAppInst, 0) 
            mbHook = mLngMouseHook <> 0 
            If mbHook Then Debug.Print "Form hooked" 
        End If 
    End If 
End Sub 
 
Sub UnhookFormScroll() 
    If mbHook Then 
        UnhookWindowsHookEx mLngMouseHook 
        mLngMouseHook = 0 
        mFormHwnd = 0 
        mbHook = False 
    End If 
End Sub 
 
Private Function MouseProc( _ 
    ByVal nCode As Long, ByVal wParam As Long, _ 
    ByRef lParam As MOUSEHOOKSTRUCT) As Long 
    On Error Goto errH 'Resume Next
    If (nCode = HC_ACTION) Then 
        Debug.Print "action" 
        Debug.Print "right window" 
        If wParam = WM_MOUSEWHEEL Then 
            Debug.Print "mouse scroll" 
            MouseProc = True 
            If lParam.hwnd > 0 Then 
                mForm.ScrollTop = Application.Max(0, mForm.ScrollTop - cSCROLLCHANGE) 
            Else 
                mForm.ScrollTop = Application.Min(mForm.ScrollHeight - mForm.InsideHeight, mForm.ScrollTop + cSCROLLCHANGE) 
            End If 
            Exit Function 
        End If 
    End If 
    MouseProc = CallNextHookEx( _ 
    mLngMouseHook, nCode, wParam, ByVal lParam) 
    Exit Function 
errH: 
    UnhookFormScroll 
End Function 

Если Office работает в 64-разрядной версии:

Option Explicit
 ' Based on code from Peter Thornton here:
 ' http://social.msdn.microsoft.com/Forums/en-US/7d584120-a929-4e7c-9ec2-9998ac639bea/mouse-scroll-in-userform-listbox-in-excel-2010?forum=isvvba
Private Type POINTAPI
    x                               As Long
    y                               As Long
End Type
Private Type MOUSEHOOKSTRUCT
    pt                              As POINTAPI
    hwnd                            As Long
    wHitTestCode                    As Long
    dwExtraInfo                     As Long
End Type
 
Private Declare PtrSafe Function FindWindow Lib "user32" _
Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
 
Private Declare PtrSafe Function GetWindowLong Lib "user32.dll" _
Alias "GetWindowLongA" ( _
ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
 
Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" _
Alias "SetWindowsHookExA" ( _
ByVal idHook As Long, _
ByVal lpfn As LongPtr, _
ByVal hmod As Long, _
ByVal dwThreadId As Long) As Long
 
Private Declare PtrSafe Function CallNextHookEx Lib "user32" ( _
ByVal hHook As Long, _
ByVal nCode As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
 
Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" ( _
ByVal hHook As Long) As Long
 
Private Declare PtrSafe Function PostMessage Lib "user32.dll" _
Alias "PostMessageA" ( _
ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
 
Private Declare PtrSafe Function WindowFromPoint Lib "user32" ( _
ByVal xPoint As Long, _
ByVal yPoint As Long) As Long
 
Private Declare PtrSafe Function GetCursorPos Lib "user32.dll" ( _
ByRef lpPoint As POINTAPI) As Long
 
Private Const WH_MOUSE_LL          As Long = 14
Private Const WM_MOUSEWHEEL        As Long = &H20A
Private Const HC_ACTION            As Long = 0
Private Const GWL_HINSTANCE        As Long = (-6)
 
Private Const WM_KEYDOWN           As Long = &H100
Private Const WM_KEYUP             As Long = &H101
Private Const VK_UP                As Long = &H26
Private Const VK_DOWN              As Long = &H28
Private Const WM_LBUTTONDOWN       As Long = &H201
 
Private Const cSCROLLCHANGE        As Long = 10
 
Private mLngMouseHook              As Long
Private mFormHwnd                  As Long
Private mbHook                     As Boolean
Dim mForm                          As Object
 
 
Sub HookFormScroll(oForm As Object)
    Dim lngAppInst                  As Long
    Dim hwndUnderCursor             As Long
     
    Set mForm = oForm
    hwndUnderCursor = FindWindow("ThunderDFrame", oForm.Caption)
    Debug.Print "Form window: " & hwndUnderCursor
    If mFormHwnd <> hwndUnderCursor Then
        UnhookFormScroll
        Debug.Print "Unhook old proc"
        mFormHwnd = hwndUnderCursor
        lngAppInst = GetWindowLong(mFormHwnd, GWL_HINSTANCE)
        If Not mbHook Then
            mLngMouseHook = SetWindowsHookEx( _
            WH_MOUSE_LL, AddressOf MouseProc, lngAppInst, 0)
            mbHook = mLngMouseHook <> 0
            If mbHook Then Debug.Print "Form hooked"
        End If
    End If
End Sub
 
Sub UnhookFormScroll()
    If mbHook Then
        UnhookWindowsHookEx mLngMouseHook
        mLngMouseHook = 0
        mFormHwnd = 0
        mbHook = False
    End If
End Sub
 
Private Function MouseProc( _
    ByVal nCode As Long, ByVal wParam As Long, _
    ByRef lParam As MOUSEHOOKSTRUCT) As Long
    On Error GoTo errH 'Resume Next
    If (nCode = HC_ACTION) Then
        Debug.Print "action"
        Debug.Print "right window"
        If wParam = WM_MOUSEWHEEL Then
            Debug.Print "mouse scroll"
            MouseProc = True
            If lParam.hwnd > 0 Then
                mForm.ScrollTop = Application.Max(0, mForm.ScrollTop - cSCROLLCHANGE)
            Else
                mForm.ScrollTop = Application.Min(mForm.ScrollHeight - mForm.InsideHeight, mForm.ScrollTop + cSCROLLCHANGE)
            End If
            Exit Function
        End If
    End If
    MouseProc = CallNextHookEx( _
    mLngMouseHook, nCode, wParam, ByVal lParam)
    Exit Function
errH:
    UnhookFormScroll
End Function

person
Ricardo Diaz
  
schedule
06.01.2021

Workbook demo

The following generic code enables MouseWheel scrolling for UserForms and Frames … You just need to pass the UserForm or the Frame to the SetScrollHook routine in the UserForm_Activate event as follows :

Code:

Private Sub UserForm_Activate()
    [COLOR=#008000]'Call SetScrollHook(Me)           '.. Apply the mousewheel scrolling to the Userform[/COLOR]
    Call SetScrollHook(Me.Frame1)     [COLOR=#008000]'.. Apply the mousewheel scrolling to the Frame[/COLOR]
End Sub

You can’t apply the mousewheel functionality to more than one object simultaniously (I’ll try to modify the code later to make it work with the userform and with different frames within the form simultaniously)

In order to scroll the frame

horizontally

, have the Ctl key held down

Proceedings:

1- Create a new UserForm (UserForm1) and add a frame to it (Frame1)

2- Place this code in the UserForm Module :

Code:

Private Sub UserForm_Activate()
    'Call SetScrollHook(Me)           '.. Apply the mousewheel scrolling to the Userform
    Call SetScrollHook(Me.Frame1)     '.. Apply the mousewheel scrolling to the Frame
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    RemoveScrollHook
End Sub

3- Add a Standard Module to the project and place the following code in it:

Code:

Option Explicit

Private Type POINTAPI
    X As Long
    Y As Long
End Type
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
Private Type MOUSEHOOKSTRUCT
    pt As POINTAPI
    hwnd As Long
    wHitTestCode As Long
    dwExtraInfo As Long
End Type

Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Declare Function PtInRect Lib "user32" (lpRect As RECT, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function GetActiveWindow Lib "user32" () As Long
Private Declare Function SetRect Lib "user32" (lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer

Private Const WH_MOUSE_LL As Long = 14
Private Const WM_MOUSEWHEEL As Long = &H20A
Private Const HC_ACTION As Long = 0
Private Const POINTSPERINCH As Long = 72
Private Const LOGPIXELSX As Long = 88
Private Const LOGPIXELSY As Long = 90
Private Const SCROLL_CHANGE As Long = 5

Private lMouseHook As Long
Private lFormHwnd As Long
Private bHookIsSet As Boolean
Private oScrollableObject As Object


Public Sub SetScrollHook(ByVal ScrollableObject As Object)
    If Not (IsObjectUserForm(ScrollableObject) Or TypeName(ScrollableObject) = "Frame") Then Exit Sub
    Set oScrollableObject = ScrollableObject
    lFormHwnd = GetActiveWindow
    With ScrollableObject
        .ScrollBars = fmScrollBarsBoth
        .KeepScrollBarsVisible = fmScrollBarsBoth
        .PictureAlignment = fmPictureAlignmentTopLeft
        ' Adjust the values of the scroll width and height properties as required
        .ScrollWidth = ScrollableObject.InsideWidth * 3
        .ScrollHeight = ScrollableObject.InsideHeight * 2
    End With
    If Not bHookIsSet Then
        lMouseHook = SetWindowsHookEx( _
        WH_MOUSE_LL, AddressOf MouseProc, Application.Hinstance, 0)
        bHookIsSet = lMouseHook <> 0
    End If
End Sub

Public Sub RemoveScrollHook(Optional ByVal Dummy As Boolean)
    If bHookIsSet Then
        UnhookWindowsHookEx lMouseHook
        lMouseHook = 0
        bHookIsSet = False
    End If
End Sub

Private Function MouseProc(ByVal nCode As Long, ByVal wParam As Long, ByRef lParam As MOUSEHOOKSTRUCT) As Long

    Dim tTopLeft As POINTAPI
    Dim tBottomRight As POINTAPI
    Dim tRect As RECT
    
    GetClientRect lFormHwnd, tRect
    With oScrollableObject
        If IsObjectUserForm(oScrollableObject) Then
            tTopLeft.X = tRect.Left
            tTopLeft.Y = tRect.Top
            tBottomRight.X = tRect.Right
            tBottomRight.Y = tRect.Bottom
        Else
            tTopLeft.X = PTtoPX(.Left, False) + tRect.Left
            tTopLeft.Y = PTtoPX(.Top, True) + tRect.Top
            tBottomRight.X = PTtoPX(.Left + .Width, False) + tRect.Left
            tBottomRight.Y = PTtoPX(.Top + .Height, True) + tRect.Top
        End If
    End With
    ClientToScreen lFormHwnd, tTopLeft
    ClientToScreen lFormHwnd, tBottomRight
    SetRect tRect, tTopLeft.X, tTopLeft.Y, tBottomRight.X, tBottomRight.Y
    On Error GoTo errH
    If (nCode = HC_ACTION) And CBool(PtInRect(tRect, lParam.pt.X, lParam.pt.Y)) Then
        If wParam = WM_MOUSEWHEEL Then
            With oScrollableObject
                Select Case GetAsyncKeyState(VBA.vbKeyControl)
                    Case Is = 0 'vertical scroll
                        If lParam.hwnd > 0 Then
                            .ScrollTop = Application.Max(0, .ScrollTop - SCROLL_CHANGE)
                        Else
                            .ScrollTop = Application.Min(.ScrollHeight - .InsideHeight, .ScrollTop + SCROLL_CHANGE)
                        End If
                    Case Else ' horiz scroll when the Ctl key down
                        If lParam.hwnd > 0 Then
                            .ScrollLeft = Application.Max(0, .ScrollLeft - SCROLL_CHANGE)
                        Else
                            .ScrollLeft = Application.Min(.ScrollWidth - .InsideWidth, .ScrollLeft + SCROLL_CHANGE)
                        End If
                End Select
            End With
        End If
    End If
    MouseProc = CallNextHookEx( _
    lMouseHook, nCode, wParam, ByVal lParam)
    Exit Function
errH:
    RemoveScrollHook
End Function

Private Function ScreenDPI(bVert As Boolean) As Long
    Static lDPI(1), lDC
    If lDPI(0) = 0 Then
        lDC = GetDC(0)
        lDPI(0) = GetDeviceCaps(lDC, LOGPIXELSX)
        lDPI(1) = GetDeviceCaps(lDC, LOGPIXELSY)
        lDC = ReleaseDC(0, lDC)
    End If
    ScreenDPI = lDPI(Abs(bVert))
End Function

Private Function PTtoPX _
(Points As Single, bVert As Boolean) As Long
    PTtoPX = Points * ScreenDPI(bVert) / POINTSPERINCH
End Function

Private Function IsObjectUserForm(ByVal obj As Object) As Boolean
    Dim oTemp As Object
    On Error Resume Next
        Set oTemp = obj.Parent
        Set oTemp = Nothing
        IsObjectUserForm = Err.Number = 438
    On Error GoTo 0
End Function

Понравилась статья? Поделить с друзьями:
  • Excel vba оператор выбора
  • Excel vba не работает for
  • Excel vba оператор set
  • Excel vba не находит файл
  • Excel vba не выдавать ошибку