Пользовательские формы(UserForm) разрабатываются специально для удобства взаимодействия пользователей с программой, и в основном для ввода и записи данных(напомню, что создается форма из редактора VBA: Insert -UserForm). Наиболее часто используемым элементом форм является TextBox, который позволяет вводить любую текстовую информацию. И если с ручным вводом проблем обычно не возникает, то с вставкой в TextBox данных из буфера обмена могут возникнуть сложности. Иначе говоря, пользователь скопировал откуда-то текст и хочет вставить его в TextBox. Или наоборот - надо скопировать и перенести в другой TextBox или еще куда-то. Но не может. И не потому, что такой возможности в принципе нет, а потому, что «из коробки» TextBox в VBA не имеет своего меню «Вырезать-Копировать-Вставить» и копирование-вставка в них возможна только сочетаниями горячих клавиш Ctrl++C(копировать), Ctrl++V(вставить), Ctrl+X(вырезать). А зачастую формы(UserForm) разрабатываются для таких пользователей, которые могут даже не подозревать о горячих клавишах. И обязанность разработчика снабдить такие формы подобными командами. Чтобы по правому клику в TextBox появлялось свое меню с заветными командами:
Свое меню Копировать-Вырезать-Вставить
Что интересно – сами команды копирования-вырезки-вставки есть в TextBox-ах «из коробки», а вот меню для них – нет. И именно меню и его обработку мы и научимся делать.
На самом деле все не так уж сложно, но начинающим программировать в VBA может показаться иначе. Первое, что необходимо сделать – это создать свое меню, которое будет обрабатывать копирование-вырезку-вставку. Притом создавать его мы будем при первом старте UserForm(событие UserForm_Initialize). А при закрытии формы меню правильно будет удалить. За все это у нас будут отвечать коды ниже:

'при вызове формы
'   создаем свое меню "Вырезать-Копировать-Вставить" для вызова из TextBox
Private Sub UserForm_Initialize()
    Call DelCustomCCPMenu  'на всякий случай удаляем меню, если вдруг оно уже есть
    Set oPopupMenu = Application.CommandBars.Add("CustomCCP_PopupMenu", msoBarPopup)
    With oPopupMenu
        With .Controls.Add(msoControlButton)
            .Caption = "Копировать"               'текст кнопки
            .FaceId = "19"                        'код иконки для кнопки
            .OnAction = "MyPopupMenuButtonCClick" 'имя процедуры, которая будет выполнена при нажатии кнопки
        End With
        With .Controls.Add(msoControlButton)
            .Caption = "Вставить"                 'текст кнопки
            .FaceId = "22"                        'код иконки для кнопки
            .OnAction = "MyPopupMenuButtonPClick" 'имя процедуры, которая будет выполнена при нажатии кнопки
        End With
        With .Controls.Add(msoControlButton)
            .Caption = "Вырезать"                   'текст кнопки
            .FaceId = "21"                          'код иконки для кнопки
            .OnAction = "MyPopupMenuButtonCutClick" 'имя процедуры, которая будет выполнена при нажатии кнопки
        End With
    End With
End Sub
'при закрытии формы
'удаляем свое меню "Вырезать-Копировать-Вставить" для вызова из TextBox
Private Sub UserForm_Terminate()
    Call DelCustomCCPMenu 'вызов функции удаления меню
End Sub
'функция удаления созданного ранее меню
Function DelCustomCCPMenu()
    On Error Resume Next 'пропускаем ошибки, если вдруг меню было удалено ранее
    Application.CommandBars("CustomCCP_PopupMenu").Delete
End Function

По сути код выше достаточно просто вставить «внутрь» формы: правая кнопка мыши на форме -View Code -вставляем приведенный выше код. Имя самой формы нигде менять не надо. Это означает, что строки Private Sub UserForm_Initialize() и Private Sub UserForm_Terminate должны оставаться именно такими независимо от того, какое имя у формы.
Теперь останется для TextBox-а на форме прописать код вызова нашего меню при нажатии правой кнопки мыши:

'отслеживаем нажатие правой кнопки мыши внутри TextBox-а
'   Button = 1 - левая кнопка
'   Button = 2 - правая кнопка
Private Sub TextBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If Button = 2 Then
        Set tbxAct = TextBox1
        Application.CommandBars("CustomCCP_PopupMenu").ShowPopup
    End If
End Sub

Напомню, что все эти коды мы должны прописать в модуль UserForm. И последний штрих – в любом стандартном модуле(Insert -Module) прописываем обработку копирования-вставки:

'копировать
Private Sub MyPopupMenuButtonCClick()
    UserForm1. TextBox1.Copy
End Sub
'вставить
Private Sub MyPopupMenuButtonPClick()
    UserForm1. TextBox1.Paste
End Sub
'вырезать
Private Sub MyPopupMenuButtonCutClick()
    UserForm1. TextBox1.Cut
End Sub

Это основной принцип использования меню. По такому же принципу можно добавить и другие команды в меню, но в зависимости от их функционала будет зависеть сложность итогового кода.
Плюс, выше приведен пример всего для одного TextBox-а. Но как быть, если их два, три и более? По-хорошему код надо модифицировать, добавлять еще пару переменных и обработок. В приложенном к статье файле именно так и сделано – там показана обработка двух TextBox-ов:
Скачать пример:

  Свое меню Копировать-Вставить в TextBox.xls (77,5 КиБ, 433 скачиваний)


Хотя и это не предел: можно автоматом делать это для всех TextBox-ов на форме, если привлечь модули классов. Но поняв принцип приведенного в этой статье кода и принцип работы модулей классов(а так же изучив код из файла-примера), сделать это самостоятельно уже не составит труда. Ниже приложен файл с реализацией обработки через модули классов - т.е. меню будет автоматом добавлено для ВСЕХ TextBox-ов на форме:
Скачать пример:

  Свое меню Копировать-Вставить в TextBox - классы.xls (85,0 КиБ, 376 скачиваний)

Так же см.:
Что такое модуль? Какие бывают модули?
Работа с модулями классов
Как быстро заполнить/очистить элементы на форме(TextBox-ы, ComboBox-ы)

Loading

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.