[VBA] Как задать сочетание горячих клавиш для запуска макроса?

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
7,814
Реакции
6,593
Как задать сочетание горячих клавиш для запуска макроса?

Для MS Excel.

1) Автоматически при записи макроса:

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

Нажмите Alt+F8. В диалоговом окне "Макрос" нужно определить место нахождения макроса, выбрать имя макроса, для которого необходимо назначить сочетание клавиш и нажать кнопку "Параметры...". После этого, в диалоговом окне "Параметры макроса" можно задать сочетание клавиш для запуска выбранного макроса.

1.JPG


Присвоенное таким способом сочетание хранится вместе с модулем и его не видно в коде.
Чтобы его просмотреть или перенести в другой документ вместе с сочитанием:
Откройте редктор VBA (клавиши левый ALT + F11)
В левой части нажмите правой кнопкой по модулю, Export...

Excel_Export_module.png


В новой книге сделайте аналогично, но с клавишей Import...
Внутри файла сочетание будет выглядеть так:

Excel_module_View.png

2) Временно, через код макроса

Возможно, вы хотите включить сочетание клавиш на время выполнения каких-то операций, и
выключить егопри дальнейшей работе. Следующая строка кода временно присваивает процедуре MoveDown вызов сочетанием клавиш Ctrl + m:
VB.NET / VBA:
Application.OnKey Key:="^m", Procedure:="MoveDown"
Чтобы отменить комбинацию, используйте строку:
VB.NET / VBA:
Application.OnKey Key:="^m"

3) Постоянно, через код макроса:

Чтобы окончательно изменить клавишу быстрого доступа с помощью кода, используйте строку:
VB.NET / VBA:
Application.MacroOptions Macro:="MoveDown", ShortcutKey:="^m"

Все доступные спецсимволы и спец. клавишы вроде Ctrl, Shift ... для сочетаний вы можете посмотреть здесь: Application.OnKey Method (Excel)

Для MS Word

1) Во время записи макроса

Для Word 2003. Меню "Сервис", Макрос, Начать запись.
Выберите, где хранить макрос - текущем документе или в Normal.dot (тогда макрос будет доступен из-под любого документа)
Нажмите пиктограмму Клаиватуры.

word_hotkeys_keybrd.jpg


Поставьте курсор в поле "Новое сочетание клавиш" и нажмите на клавиатуре желаемое сочетание.
Выберите расположение, где хотите сохранить сочетание - в текущем документе, или доступное из-под всех документов.

word_Export_module2.png


Выполните действия в документе, которые хотите записать. В конце, завершите запись кнопкой "Стоп":
word_stop_record.png


Для Word 2008 и новее, см. здесь: Настройка сочетаний клавиш - Word

2) Программно из-под кода макроса (временное, для текущего документа)

В некоторых случаях бывает необходимо в пакетном режиме назначить в Word тем или иным командам и макросам «горячие клавиши».
Макрокоманда, назначающая «горячие клавиши», имеет следующий принципиальный вид:
VB.NET / VBA:
   CustomizationContext = NormalTemplate
    KeyBindings.Add KeyCode:=BuildKeyCode(<Сочетание_клавиш>), _
        KeyCategory:=wdKeyCategoryCommand, Command:="<Наименование_команды/макроса>"
Элемент <Сочетание_клавиш>:

wdKey<Буква/цифра>, [wdKeyControl,] [wdKeyShift,] [wdKeyAlt]
где:
- wdKey<Буква/цифра> – нажатие клавиши, соответствующей указанной букве или цифре,
- wdKeyControl – нажатие клавиши Ctrl,
- wdKeyShift – нажатие клавиши Shift,
- wdKeyAlt – нажатие клавиши Alt.

Например:
wdKeyS, wdKeyControl – сочетание клавиш Ctrl+S
wdKeyQ, wdKeyControl, wdKeyAlt
– сочетание клавиш Ctrl+Alt+Q
wdKeyP, wdKeyControl, wdKeyShift, wdKeyAlt
– сочетание клавиш Ctrl+Shift+Alt+P

Элемент <Наименование_команды/макроса> можно взять из окна Настройка клавиатуры (для Word 2013: Файл – Параметры – Настроить ленту – Настройка…). Например:
FileSave – команда сохранения файла
InsertPicture – вставка рисунка из графического файла и т.д.

Для описания наименования макроса используется следующая конструкция:

<Имя_шаблона.Имя_модуля.Имя_макроса>
Указанные параметры можно найти в окне редактора VBA.
Например:
Normal.NewMacros.CompletePreparationSelection – шаблон Normal.dotm или Normal.dot, модуль (обычно в разделе Modules) NewMacros, макрос CompletePreparationSelection.

Пример модуля, назначающего «горячие клавиши»:
VB.NET / VBA:
Sub HotKeys()
'
   CustomizationContext = NormalTemplate
    KeyBindings.Add KeyCode:=BuildKeyCode(wdKeyQ, wdKeyControl, wdKeyAlt), _
        KeyCategory:=wdKeyCategoryCommand, Command:="DocEncryption"
     ' Команде DocEncryption назначается сочетание клавиш Ctrl+Alt+Q

    CustomizationContext = NormalTemplate
    KeyBindings.Add KeyCode:=BuildKeyCode(wdKeyS, wdKeyControl), KeyCategory:= _
        wdKeyCategoryCommand, Command:="FileSave"
     ' Команде FileSave назначается сочетание клавиш Ctrl+S

    CustomizationContext = NormalTemplate
    KeyBindings.Add KeyCode:=BuildKeyCode(wdKeyP, wdKeyControl, wdKeyShift, _
        wdKeyAlt), KeyCategory:=wdKeyCategoryCommand, Command:="Normal.NewMacros.CompletePreparationSelection"
     ' Макросу Normal.NewMacros.CompletePreparationSelection назначается сочетание клавиш Ctrl+Shift+Alt+P:

End Sub

Чтобы иметь возможность удалить назначенное сочетание клавиш необходимо использовать чуть другой синтаксис при назначении комбинации (с ключевым словом set):

Пример назначения и отмены:
VB.NET / VBA:
Private oKey1 as KeyBinding

Public Sub BindKey()
    'Назначение клавиш Alt + Crl + Num4 (цифра 4 на цифровой клавиатуре)
    With Application
        .CustomizationContext = ThisDocument
        Set oKey1 = .KeyBindings.Add( _
            KeyCode:=BuildKeyCode(wdKeyAlt, wdKeyControl, wdKeyNumeric4), _
            KeyCategory:=wdKeyCategoryCommand, _
            Command:="GotoNoteBack")
    end with
end sub

'очистка сочетания
Private Sub UnBind()
    oKey1.Clear
End Sub

ВАЖНОЕ ЗАМЕЧАНИЕ:
У этого способа есть неприятный момент, при переходе к другому документу, комбинация сбрасывается. Как это обойти читайте в пункте 3:

3) Программно из-под кода макроса (постоянное, для текущего документа)

Это просто хак, который выполняет роль постоянного назначения на базе предыдущего примера.
Мы просто будем вызывать KeyBindings через событие автозапуска документа.

А чтобы сочетание не сбрасывалось мы его будем каждый раз восстанавливать с помощью события WindowActivate.

Нижеуказанный код поместите в модуль ThisDocument !!! и перезапустите Word:

VB.NET / VBA:
Option Explicit

Private WithEvents appWord As Word.Application

Dim oKey1 As KeyBinding

Private Sub appWord_WindowActivate(ByVal Doc As Word.Document, ByVal Wn As Word.Window)
    Call BindKey
End Sub

Private Sub Document_Close()
    On Error Resume Next
    oKey1.Clear
End Sub

Private Sub Document_Open()
    Set appWord = Word.Application
    Call BindKey
End Sub

Private Sub BindKey()
    With Application
        .CustomizationContext = ThisDocument
        Set oKey1 = .KeyBindings.Add( _
            KeyCode:=BuildKeyCode(wdKeyAlt, wdKeyControl, wdKeyNumeric4), _
            KeyCategory:=wdKeyCategoryCommand, _
            Command:="Macro1")
    End With
End Sub

Public Sub Macro1()
    msgbox "Вызвана процедура Macro1"
End Sub

Примечание: Макрос, вызываемый через KeyBindings, должен иметь область видимости Public.

Доступные для назначения клавиши можно посмотреть по ссылке: WdKey Enumeration (Word)

Другие способы и замечания:

Стандартно, сочетания можно назначать не на все клавиши. А часть сочетаний уже задействована под служебные функции.
Однако, есть способ это обойти, хотя и небезопасный.
Я протестировал API-функцию RegisterHotkey, которая с этим замечательно справляется.
Один большой минус, чтобы "Словить" сочетание требуется создание сабклассинга оконной процедуры. А это непростая тема для VBA, так как я ещё не видел надёжного кода сабклассинга под MS Office, который бы не обрушил программу (крэш) при выполнении некоторых операций.
По понятным причинам код не выкладываю. Однако, вы можете попросить мой вариант в ЛС.

На основе материалов:
Настройка сочетаний клавиш - Word
Application.OnKey Method (Excel)
Как задать сочетание горячих клавиш для запуска макроса в Excel?
http://baguzin.ru/wp/wp-content/uploads/2015/11/Назначение-макросу-сочетания-клавиш.pdf
Макрос, назначающий командам и макросам Word «горячие клавиши»
RegisterHotKey function (Windows)
WdKey Enumeration (Word)
Ну и конечно собственные эксперименты Dragokas
 
Последнее редактирование:
Стандартно, сочетания можно назначать не на все клавиши. А часть сочетаний уже задействована под служебные функции.
Однако, есть способ это обойти, хотя и небезопасный.
Я протестировал API-функцию RegisterHotkey, которая с этим замечательно справляется.

Этим своим сообщением Вы вселяете в меня надежду на решение многолетней проблемы, которая появилась в Word'ах с ленточным интерфейсом!
Указанные ниже восемь комбинаций не поддаются штатными способами для назначения на них макрокоманд в Word 2013:
Alt+Num /......................Alt+Shift+Num /
Alt+Num *......................Alt+Shift+Num *
Alt+Num -......................Alt+Shift+Num -
Alt+Num +.....................Alt+Shift+Num +

Можете ли Вы, уважаемый Dragokas, выяснить, что именно этому препятствует?
Не поможет ли упоминаемая Вами API-функция RegisterHotkey справиться с этими тугими сочетаниями?
 
Последнее редактирование:
auto-teacher, можно. И я проверял, это работает.
Этому препятствует необходимость зайдействовать код так называемого сабклассинга оконных сообщений, который используется чтобы поймать нажатие зарегистрированного сочетания клавиш.
Этот код небезопасен, точнее еще не нашлось автора который смог бы под MS Office его написать безопасным. В итоге, при попытке, например, остановить выполнение макроса весь процесс Winword.exe и открытые в нём документы рухнут (крэш). Это только один из вариантов; может рухнуть, например, если попытаться что-то сделать в режиме конструктора (детально не проверял).
Именно поэтому я не выкладываю в открытый доступ этот код.
Тем не менее, Вы можете попросить в ЛС мою модификацию этого кода. Собственно, он выложен на vbforums.com: [vba] Ways for improvement of MS Office window subclassing-VBForums
Уверен, что для банальной задачи, вроде открыть только один документ, выполнить простейшие операции по редактированию текста, затем закрыть документ (тем самым прекратив сабклассинг), это будет вполне безопасно. Но для редактирования кода макроса желательно открывать такой документ с отключёнными макросами.
 
Последнее редактирование:
Уважаемый Dragokas!
Как-то странно получается.
На нескольких крутых форумах я пытаюсь найти решение, которое позволило бы мне применить указанные сочетания для внутренних макрокоманд Word, и никто даже близко не подошел к сути проблемы. Где же они - знатоки Windows?
Даже если кто-то и пытается что-то посоветовать - (включая и эту тему API-функций, и вмешательство через административные шаблоны Офиса, и редактирование реестра Windows) - никто не может дознаться: а какая собственно прога в системе этими комбинациями распоряжается. Раньше-то эти сочетания были доступными!
Как все-таки узнать, где: в системе или в программе Word - лежит эта инфа? Какой ресурс держит для себя эти сочетания?
Почему, например, любое из указанных сочетаний срабатывает для запуска Проводника, Блокнота, браузера, но не принимает внутренние команды Word?
Что касается Вашего кода, то мне не ясно, что значит: "поймать нажатие зарегистрированного сочетания клавиш"? Как это? Вроде как оно в какой-то службе зарегистрировано, а мы его раньше нее поймаем, а потом себе возьмем? Так что ли?
Не проще ли определить, где зарегистрированы эти сочетания по умолчанию? И отменить их.

В связи с этим я должен напомнить еще одну проблему, которая мне попалась в Windows 8 и Word 2013. Она мне крови попортила, пока чудом не пришло решение. Суть такая: есть две кнопки Alt - левая и правая, но отдельно работает только одна левая.
Чтобы увидеть это, надо Вам проверить все на своем компе (Вы же недавно Word 2013 поставили?).
1. Назначьте для макроса TableInsertTable такое сочетание: Alt+t.
2. А для макроса PageSetupMargins назначьте: Ctrl+Alt+t.
Теперь:
если Вы нажмете Left_Alt+t - произойдет вставка таблицы.
если нажмете Left_Ctrl+Left_Alt+t - откроются параметры страницы.
а если нажмете Right_Alt+t, то смею предположить, что в Вашем Word'е правый Alt сработает как Ctrl+Alt, и вместо вставки таблицы, откроются параметры страницы. Так это или нет?
 
Назад
Сверху Снизу