И все-таки это возможно.
Коротко и с готовым примером (файл прилагается).
Перед
надо выполнить
и NumLock меняться не будет.
В листе:
В модуле книги:
Теперь рассуждения что, и как работает.
Посмотрев по предложенным ссылкам и многим другим источникам, убедился- все это шляпа. И она не работает.
Я не то что не гуру, использую VBA около месяца. Потому, все что ниже (и выше, не счет "шляпы" может не соответствовать истине.
Кроме того, что бы придти к этому способу я сознательно подменил стандартные понятия своими, заведомо не верными, но работающими в данном контексте.
И так.
Первое понятие: команда {NUMLOCK} не посылает сигнал "нажать NumLock", а закрепляет NumLock, если он "изменчивый".
"Изменчивый" - это когда он меняет свое состояние, когда не должен, например при команде %{DOWN} которая по идее должна только сымитировать Alt+Down.
Экспериментальным путем выяснил, что NumLock имеет "стабильное" состояние и "изменчивое". Не путать с "включен" и "выключен", в любом из них он может быть как "изменчивым" так и "стабильным".
Второе понятие: строчки
GetKeyboardState keystat(0)
state = keystat(vbKeyNumlock)
определяют не текущее состояние NumLock, а его текущую стабильность. Если state = 0, то NumLock стабилен, иначе изменчив.
Теперь все просто.
Если NumLock стабилен, ничего не делаем, просто посылаем команду %{DOWN}.
Если NumLock изменчивый, посылаем команду стабилизации (закрепления) {NUMLOCK}, и после уже спокойно пишем %{DOWN}, зная, что NumLock не изменится.
Конечно понятия "стабильный" и "изменчивый" надуманы но тут они отлично подходят.
Несколько фактов из наблюдений.
В стабильном состоянии следущие команды не меняют NumLock
%{DOWN}
{NUMLOCK} {NUMLOCK} (т.е. два раз подряд послать нажатие NumLock)
В изменчивом состоянии те же команды его меняют регулярно (при каждой команде NumLock 1 раз меняется) оставляя его изменчивым.
При этом команда
{NUMLOCK} (т.е. один раз послать нажатие NumLock)
работает так (допустим сейчас стабильное состояние, и он включен (лампочка горит)):
1. {NUMLOCK} - NumLock изменился (погас), состояние стало изменчивым
2. {NUMLOCK} - NumLock не изменился (не горит), состояние стало стабильным
3. {NUMLOCK} - NumLock изменился (загорелся), состояние стало изменчивым
4. {NUMLOCK} - NumLock не изменился (горит), состояние стало стабильным
...... и далее по кругу
Еще немного мелочей.
Во многих гайдах пишут подключить библиотеку для работы GetKeyboardState keystat(0), а именно:
Declare PtrSafe Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long
PtrSafe - там отсутствует, что вызывает ошибку, т.к. сейчас почти у всех Windows 64 bit, а не 32. Для совместимости и надо добавить.
Так же в этом объявлении для совместимости с 64-битной версией, рекомендуют использовать тип LongLong вместо Long. Возможно это где-то оправдано. У меня работали оба варианта, но у одного из тех, кому я делал вылезла ошибка, что у него нет такого типа данных (LongLong). По этому пишу просо Long.
Что у меня, что у него Windows 7 64bit, Excel 2010.
P.S. мда, ну и накатал. Что значит заняться не чем было (5 часов разбирался). Ну да может пригодится кому.
Коротко и с готовым примером (файл прилагается).
Перед
Код |
---|
Application.SendKeys "%{DOWN}" |
Код |
---|
If Num_Not_Stable() Then Application.SendKeys "{NUMLOCK}" |
В листе:
Код |
---|
Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim lValidation As Long If Num_Not_Stable() Then Application.SendKeys "{NUMLOCK}" ' делает NumLock стабильным On Error Resume Next lValidation = ActiveCell.Validation.Type On Error GoTo 0 If lValidation = 3 Then Application.SendKeys "%{DOWN}" End Sub |
В модуле книги:
Код |
---|
Declare PtrSafe Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long ' Определяет, изменчивое ли состояние у NumLock или нет ' Возвращает false - стабильный, true - изменчевый Function Num_Not_Stable() As Boolean Dim keystat(0 To 255) As Byte Dim state As String GetKeyboardState keystat(0) state = keystat(vbKeyNumlock) If (state = 0) Then Num_Not_Stable = False Else Num_Not_Stable = True End If End Function |
Теперь рассуждения что, и как работает.
Посмотрев по предложенным ссылкам и многим другим источникам, убедился- все это шляпа. И она не работает.
Я не то что не гуру, использую VBA около месяца. Потому, все что ниже (и выше, не счет "шляпы" может не соответствовать истине.
Кроме того, что бы придти к этому способу я сознательно подменил стандартные понятия своими, заведомо не верными, но работающими в данном контексте.
И так.
Первое понятие: команда {NUMLOCK} не посылает сигнал "нажать NumLock", а закрепляет NumLock, если он "изменчивый".
"Изменчивый" - это когда он меняет свое состояние, когда не должен, например при команде %{DOWN} которая по идее должна только сымитировать Alt+Down.
Экспериментальным путем выяснил, что NumLock имеет "стабильное" состояние и "изменчивое". Не путать с "включен" и "выключен", в любом из них он может быть как "изменчивым" так и "стабильным".
Второе понятие: строчки
GetKeyboardState keystat(0)
state = keystat(vbKeyNumlock)
определяют не текущее состояние NumLock, а его текущую стабильность. Если state = 0, то NumLock стабилен, иначе изменчив.
Теперь все просто.
Если NumLock стабилен, ничего не делаем, просто посылаем команду %{DOWN}.
Если NumLock изменчивый, посылаем команду стабилизации (закрепления) {NUMLOCK}, и после уже спокойно пишем %{DOWN}, зная, что NumLock не изменится.
Конечно понятия "стабильный" и "изменчивый" надуманы но тут они отлично подходят.
Несколько фактов из наблюдений.
В стабильном состоянии следущие команды не меняют NumLock
%{DOWN}
{NUMLOCK} {NUMLOCK} (т.е. два раз подряд послать нажатие NumLock)
В изменчивом состоянии те же команды его меняют регулярно (при каждой команде NumLock 1 раз меняется) оставляя его изменчивым.
При этом команда
{NUMLOCK} (т.е. один раз послать нажатие NumLock)
работает так (допустим сейчас стабильное состояние, и он включен (лампочка горит)):
1. {NUMLOCK} - NumLock изменился (погас), состояние стало изменчивым
2. {NUMLOCK} - NumLock не изменился (не горит), состояние стало стабильным
3. {NUMLOCK} - NumLock изменился (загорелся), состояние стало изменчивым
4. {NUMLOCK} - NumLock не изменился (горит), состояние стало стабильным
...... и далее по кругу
Еще немного мелочей.
Во многих гайдах пишут подключить библиотеку для работы GetKeyboardState keystat(0), а именно:
Declare PtrSafe Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long
PtrSafe - там отсутствует, что вызывает ошибку, т.к. сейчас почти у всех Windows 64 bit, а не 32. Для совместимости и надо добавить.
Так же в этом объявлении для совместимости с 64-битной версией, рекомендуют использовать тип LongLong вместо Long. Возможно это где-то оправдано. У меня работали оба варианта, но у одного из тех, кому я делал вылезла ошибка, что у него нет такого типа данных (LongLong). По этому пишу просо Long.
Что у меня, что у него Windows 7 64bit, Excel 2010.
P.S. мда, ну и накатал. Что значит заняться не чем было (5 часов разбирался). Ну да может пригодится кому.