Part 7: Making the Scroll Bar “Stretch”
This is where the magic happens.
Remember that part earlier where we made a call to another macro named “UpdateProgress”? We passed that macro a value stored in a variable named Pct.
The value in Pct serves two purposes:
- The value of Pct is displayed in the Caption of the Frame
- Pct is used to calculate the Width property of the label object.
- The .Repaint instruction forces the label object to be visually refreshed based on the newly calculated Width
By redrawing the label object at an ever-increasing larger width, we achieve the illusion that the label object is growing. Ingenious, no?
The “DoEvents” instruction allows VBA to detect user-interaction via the keyboard. This is helpful during long-duration macros where the user may wish to break out of a loop prematurely.
Using multiple sets of OptionButtons
Figure 18-7 shows a custom dialog box with three sets of OptionButtons. If your UserForm contains more than one OptionButtons set, make sure that each set of OptionButtons works as a set. You can do so in either of two ways:
Enclose each set of OptionButtons in a Frame control. This approach is the best and also makes the dialog box look better. It’s easier to add the Frame before adding the OptionButtons. You can, however, also drag existing OptionButtons into a Frame.
Make sure that each set of OptionButtons has a unique GroupName property. If the OptionButtons are in a Frame, you don’t have to be concerned with the GroupName property.Figure 18-7:This dialog box contains three sets of Option Button controls.
Only one OptionButton in a group can have a value of True. To specify a default option for a set of OptionButtons, just set the Value property for the default item to True. You can do this directly in the Properties box or do it using VBA code:
This example is available at this topic’s Web site. It also has code that displays the selected options when the user clicks OK.
Визуальное программирование
В конце ХХ века широкое распространение получило визуальное программирование – технология, предоставляющая программисту наглядные средства конструирования интерфейса. Объектно-ориентированное программирование удачно использует концепцию визуального программирования.
VBA – это интегрированная среда разработки, которая предоставляет программисту возможность создания форм, на которых размещают компоненты (в терминах VBA — controls, элементы управления), имеющиеся в библиотеке VBA или созданные пользователем. Все компоненты (формы, элементы управления, меню и панели инструментов) являются объектами со своими свойствами и методами и способны реагировать на определенные события.
Компоненты могут быть:
- визуальными – т.е. видимыми при работе приложения; немедленно отображаются на экране при проектировании в таком же виде, в каком их увидит пользователь во время выполнения приложения;
- не визуальными – отображаются на форме в процессе проектирования в виде значка, но пользователю во время выполнения программы не видны; выполняют некоторые служебные функции.
- можно легко изменять размеры и расположение компонентов на форме (с помощью простых манипуляций мышью);
- в процессе проектирования постоянно виден результат – изображение формы и расположенных на ней компонентов (не надо запускать приложение для проверки внешнего вида окна и последующего изменения программного кода для подбора более удачного размера и расположения компонентов);
- (основное) во время проектирования формы и размещения на ней компонентов редактор кода автоматически генерирует код программы, включая в нее фрагменты, описывающие данный компонент (далее можно изменять свойства компонентов и писать обработчики событий).
- создание пользовательской формы;
- размещение на созданной форме нужных компонентов (элементов управления);
- задание определенных свойств этих компонентов;
- написание, при необходимости, обработчиков событий.
Пользовательские формы
При работе в Excel, как и в большинстве, других приложениях, приходиться сталкиваться с такими элементами интерфейса, как диалоговые окна. Диалоговые окна используются повсеместно для получения информации для ввода и вывода сообщений и данных.
Одним из объектов VBA, объектом визуализации являются UserForm — пользовательские формы — это диалоговые окна интерфейса процедур VBA. С их помощью пользователь может эффективно передавать данные в процедуры и получать результаты их работы. Пользовательские формы дают возможность пользователю создавать диалоговые окна в разрабатываемых приложениях и размещать в окнах элементы управления.
В VBA есть две функции — MsgBox и InputBox, которые позволяют отображать простые диалоговые окна, не создавая пользовательскую форму. Эти окна можно видоизменять, использовать управляющие ими параметры, но они не имеют тех широких и эффективных возможностей опций, которые предоставляют пользовательские формы.
VBA предлагает обширные возможности, которые можно использовать при создании пользовательских диалоговых окон, для программирования элементов управления, размещаемых непосредственно на листах Excel, или для работы с диалоговыми окнами, встроенными в Excel.
Создание пользовательской формы
Чтобы создать форму, откройте редактор Visual Basic для этотого нажмите (Alt + F11) или выберете на ленте вкладку « Разработчик», а на ней Visual Basic
В открывшемся окне Microsoft Visual Basic выбрать на ленте вкладку Insert. В открывшемся меню выбрать UserForm.
На экране появилась пустая форма UserForml, инструментальная панель Toolbox и при нажатии правой кнопки мыши контекстное меню с предложением Properties — свойства формы.
Элементы управления
На инструментальной панели Toolbox расположены следующие элементы управления, которые являются объектами VBA :
- TextBox — поле,
- Label — надпись,
- CommandButton — кнопка,
- ListBox — список,
- ComboBox — поле со списком,
- ScrollBar — полоса прокрутки,
- SpinButton — счетчик,
- OptionButton — переключатель,
- CheckBox — флажок ,
- ToggleButton — выключатель,
- Frame — рамка,
- Image — рисунок,
- RefEdit — RefEdit,
- MultiPage — набор страниц.
Любой из этих элементов управления, объектов можно разместить на форме.
Например, можно поместить кнопку. Для этого мышью перетаскиваем на форму объект или элемент управления под названием CommandBatton, расположенный вторым слева в третьем ряду панели Toolbox. На форме появится кнопка CommandBatton1
Свойства элементов управления
Выбрав — свойства формы, в открывшемся окне можно изменить заголовок элементов формы, в частности кнопки, её шрифт, цвет фона, добавить картинки, добавить и изменить многие другие свойства.
Наиболее часто используемые свойства объекта UserForm:
- Name — возвращает имя пользовательской формы,
- Caption — возвращает текст, отображаемый в строке заголовка формы,
- BackColor — возвращает цвет фона формы,
- BorderStyle — устанавливает тип границы,
- Picture — указывает рисунок, отображаемый как фон формы.
Связь пользовательской формы с процедурой
После двойного щелчка по кнопке откроется окно редактора VBA, где уже будет создана заготовка вашей процедуры обработки нажатия на кнопку.
Теперь в тело этой процедуры можно вводить команды (операторы), которые будут выполняться, если событие в заголовке — Click мыши — произойдет. Это событие считается стандартным для кнопок, флажков, рисунков, рамок, переключателей и окон отображения текста.
Для остальных элементов — полей ввода текста, полос прокрутки, счетчиков и др. — стандартным считается событие Change, то есть их изменение.
Объекты, методы, свойства и события
VBA относится к языкам объектно-ориентированного программирования.
Объект — основной элемент VBA. В VBA Excel объектами являются рабочая книга, рабочий лист и его составляющие, например:
- Sheet — лист Excel;
- Cell — ячейка;
- Range — диапазон ячеек;
- Application — приложение;
- UserForm — пользовательская форма;
- CommandButton -кнопка,
и другие.
Работа с объектами возможна через его методы и свойства.
Над объектами можно совершать различные действия. Методы — это действия, совершаемые над объектами.
Например, ячейку или диапазон ячеек можно очистить (Clear), можно выбрать (Select), приложение закрыть (Quit), пользовательскую форму показать (Show) или скрыть (Hide).
Название метода отделяется от названия объекта точкой:
название объект . название метода
Range(«B2:E2»).Select — выбрать диапазон ячеек B2:E2;
Range(«C1:C5»).Clear — очистить диапазон ячеек C1:C5;
UserForm2.Hide — скрыть форму под номером 2;
UserForm5.Show — показать форму под номером 5;
Application.Quit — выйти из приложения.
Свойства служат для описания, задания характеристик объектов. Например, размера и цвета шрифта, положения формы на экране или состояние объекта (доступность, видимость), задания значений. Чтобы задать или изменить характеристику объекта, надо изменить значение его свойства, т.е. присвоить ему определенные значения.
Синтаксис задания значения свойства следующий:
Объект.Свойство = Значение Свойства
Cell(1,2).Value = 2011 — поместить в ячейку В1 значение 2011.
Range(«A1:A12»).Text = «Программа» — поместить в диапазон ячеек А1:А12 текст Программа.
Range(«C2»).Font.Size = 18 — в ячейке С2 установить размер шрифта 18.
Свойства:
- Value ( позволяет задать значение),
- Text (ввод текста),
- Font.Size (задание размера шрифта).
В VBA для каждого объекта определен набор стандартных событий.
Команды Default, NoDefault и Stored
Эти команды называют спецификаторами хранения. Они не оказывают никакого действия на выполнение программы, но управляют способом сохранения значений свойств из раз-дела Published в Dfin-файле.
Команда Default позволяет указать значение, каким конструктор класса будет инициализировать соответствующее поле оно будут инициализировано нулевым значением.
Примечания: • Этот раздел можно указывать только для порядковых типов данных и множества. Допустим он и для данных типа указатель с единственным значением Nil, поэтому фактически нецелесообразен. • Пункт со значением по умолчанию сам по себе не устанавливает значение свойства — ответственность за это лежит на программисте, и необходимо в конструкторе класса явно написать оператор, присваивающий свойству предусмотренное по умолчанию значение. • Команда Default лишь информирует транслятор о том, каким значением будет инициализировано свойство. Это позволяет при считывании и записи в файлы формы и компонентов узнавать, нужно ли записывать в файл *.Dfm значение свойства. Если текущее значение свойства такое же, как в команде Default, то его можно не записывать, уменьшая таким образом размер файла. • Для свойств-массивов команда Default объявляет соответствующее свойство-массив свойством по умолчанию, что позволяет упростить доступ к элементам такого массива. При обращении к такому свойству его имя можно не упоминать, а индексы в квадратных скобках указывать у имени объекта. Очевидно, что только одно свойство-массив класса и его потомков может иметь такую команду. В классах-потомках нельзя отметить эту команду. AnyObject:=’Bтоpoй способ — при указании свойства Default’;
Команда NoDefault используется для сообщения о том, что не существует никакого значения, действующего по умолчанию. Обычно она применяется для наследованных свойств, которые имели заданное по умолчанию значение, и для тех же типов данных, что и команда Default.
в) Команда Stored используется для того, чтобы указать на необходимость сохранения значения свойства. За командой Stored могут стоять либо ключевые слова: True False, либо указана Команда Index
Команда Index используется в связи с методами доступа к нескольким свойствам. Если несколько свойств имеют идентичные методы доступа для чтения и/или записи, то выбор свойства внутри таких методов может быть сделан с помощью оператора Case и значения цело-численного параметра команды Index.
Примечания: • Эта команда указывается первой в списке команд объявления свойств. • Методы доступа к свойству, имеющему раздел Index должны иметь дополнительный параметр, объявленный как Integer. Для метода чтения этот параметр должен быть последним в списке параметров функции, а для метода записи этот параметр должен быть предпоследним в списке параметров процедуры — предшествовать параметру, определяющему значение свойства.
Пример использования
<!DOCTYPE html> <html> <head> <title>Пример таблицы, составленной на HTML</title> </head> <body> <table border = “1”> <!–начало содержимого таблицы–> <caption>Элементарная таблица</caption> <!– наименование таблицы–> <tr> <!–описываем первую строку–> <th>Ячейка заголовка 1</th> <th>Ячейка заголовка 2</th> <th>Ячейка заголовка 3</th> </tr> <tr> <!–описываем вторую строку–> <td>Ячейка данных 1 Строка 2</td> <td>Ячейка данных 2 Строка 2</td> <td>Ячейка данных 3 Строка 2</td> </tr> <tr> <!– описываем третью строку–> <td>Ячейка данных 1 Строка 3</td> <td>Ячейка данных 2 Строка 3</td> <td>Ячейка данных 3 Строка 3</td> </tr> </table> <!– конец таблицы–> </body> </html>
К данной таблице для наглядности мы добавили атрибут border (граница) и установили равным 1. Атрибут граница практически не используется в HTML, в данном случае использование CSS было бы предпочтительнее и давало бы более гибкие возможности.
Результат нашего примера:
Пример таблицы, составленной на HTML.
Объединение столбцов
Объединение столбцов в элементах <td> или <th> допускается производить с помощью атрибута colspan (при этом ячейка растягивается вправо на заданное количество ячеек).
<!DOCTYPE html> <html> <head> <title>Пример таблицы с объединёнными столбцами</title> </head> <body> <table border = “1”> <!–начало содержимого таблицы–> <caption>Элементарная таблица</caption> <!–наименование таблицы–> <tr> <!–описываем первую строку–> <th colspan = “2”>Ячейка заголовка 1</th> <!–растягиваем на 2 ячейки–> <th>Ячейка заголовка 2</th> </tr> <tr> <!–описываем вторую строку–> <td>Ячейка данных 1 Строка 2</td> <td>Ячейка данных 2 Строка 2</td> <td>Ячейка данных 3 Строка 2</td> </tr> <tr> <!–описываем третью строку–> <td>Ячейка данных 1 Строка 3</td> <td>Ячейка данных 2 Строка 3</td> <td>Ячейка данных 3 Строка 3</td> </tr> </table> <!–конец таблицы–> </body> </html>
Результат нашего примера:
Пример таблицы с объединёнными столбцами на HTML.
Объединение строк
Объединение строк в элементах <td> или <th> допускается с помощью атрибута rowspan (диапазон ячеек задается сверху вниз и охватывает несколько строк – ячейка растягивается вниз).
<!DOCTYPE html> <html> <head> <title>Пример таблицы с объединёнными столбцами и строками</title> </head> <body> <table border = “1”> <!– начало содержимого таблицы–> <caption>Элементарная таблица</caption> <!–наименование таблицы–> <tr> <!–описываем первую строку–> <th colspan =”2″>Ячейка заголовка 1</th><!–растягиваем на 2 ячейки–> <th>Ячейка заголовка 2</th> </tr> <tr><!–описываем вторую строку–> <td rowspan = “2”>Ячейка данных 1 Строка 2</td> <td>Ячейка данных 2 Строка 2</td> <td>Ячейка данных 2 Строка 3</td> </tr> <tr> <!–описываем третью строку (первая ячейка занята предыдущей строкой) –> <td>Ячейка данных 2 Строка 3</td> <td>Ячейка данных 3 Строка 3</td> </tr> </table> <!–конец таблицы–> </body> </html>
Результат нашего примера:
Пример таблицы с объединёнными столбцами и строками на HTML.
Закрытие формы
Закрыть форму можно методом Close. При этом в закрывающейся форме возникает последовательность событий, которые можно обрабатывать. Их назначение — проверить возможность закрытия формы и указать, что именно подразумевается под закрытием формы. Проверка возможности закрытия формы необходима, например, для того, чтобы проанализировать, сохранил ли пользователь документ, с которым он работал в данной форме и который изменял. Если не сохранил, приложение должно спросить его о необходимости сохранения и, в зависимости от ответа пользователя, сохранить документ, закрыть приложение без сохранения или вообще отменить закрытие.
Рассмотрим последовательность событий, возникающих при выполнении метода Close.
Первым возникает событие onCloseQuery. В его обработчик передается булева переменная CanClose, определяющая, должно ли продолжаться закрытие формы. По умолчанию CanClose равно true, что означает продолжение закрытия. Но если из анализа текущего состояния приложения или из ответа пользователя на запрос о закрытии формы следует, что закрывать ее не надо, параметру CanClose должно быть присвоено значение false. Тогда последующих событий, связанных с закрытием формы не будет.
Задание 1: Откройте разрабатываемый вами текстовый редактор (или создайте новое приложение и установите RichEdit). Создайте обработчик события формы onCloseQuery и внесите следующий код:if RichEdit1.Modified thenif MessageDlg(‘Документ не сохранен. Вы действительно хотите завершить работу?’, mtConfirmation, ,0)=mrNo then CanClose:=False;
Если пользователь в диалоговом окне с запросом о сохранении ответит Нет, то CanClose будет равно false и окно не закроется. Причем этот обработчик сработает при любой попытке пользователя закрыть приложение: нажатии в нем кнопки или раздела меню Выход, нажатии кнопки системного меню в полосе заголовка окна и т.п.
Если обработчик события onCloseQuery отсутствует или если в его обработчике сохранено значение true параметра CanClose, то следом наступает событие OnClose. В обработчик этого события передается переменная Action, которой можно задавать значения:
- сaNone — не закрывать форму. Это позволяет и в обработчике данного события еще отказаться от закрытия формы.
- caHide — при этом значении закрыть форму будет означать сделать ее невидимой. Для пользователя она исчезнет с экрана, однако вся хранящаяся в форме информация сохранится.
- caMinimize — при этом значении закрыть форму будет означать свернуть ее до пиктограммы. Как и в предыдущем случае, вся информация в форме будет сохранена.
- сaFree — при этом значении закрыть форму будет означать уничтожение формы и освобождение занимаемой ею памяти. Если эта форма в дальнейшем потребуется еще раз, ее надо будет создавать методом CreateForm.
Атрибуты
Этот элемент включает глобальные атрибуты.
Устаревшие атрибуты
Следующие атрибуты устаревшие и не должны использоваться. Они описаны ниже для справки при обновлении кода и для общего сведения.
align Этот пронумерованный атрибут указывает как заголовок должен быть выравнен по отношению к таблице. Он может иметь одно или несколько следующих значений : left Заголовок отображается слева от таблицы. top Заголовок отображается над таблицей. right Заголовок отображается справа от таблицы. bottom Заголовок отображается под таблицей.
Примчание к использованию: Не используйте этот атрибут, так как он устарел. Элемент <caption> должен быть стилизован с использованием свойств CSS caption-side иtext-align.
Add remaining textboxes and labels
You’ll add three more textboxes and labels to the UserForm. A quick way to create additional textboxes is to copy the existing textbox, click on the UserForm, and paste.
Follow these steps to create the additional textboxes and labels:
- Click on the Part label to select it
- Press the Ctrl key, and click on the Part textbox, to also select it
- On the Edit menu, click Copy (or use the Ctrl + C shortcut)
- On the Edit menu, click Paste (or use the Ctrl + V shortcut)
- Drag the pasted textbox and label down, if necessary, so they are below the first textbox and label.
- Repeat steps 4 and 5, twice, to paste and position two more textboxes and labels. If necessary, make the UserForm larger, by dragging down on the handle on its bottom border.
Name the New Textboxes
Next, follow the steps below, to name each of the new textboxes, and change its label’s caption.
- Click on the second textbox, and change its name to txtLoc
Change its label caption to Location.
.
- Click on the third textbox, and change its name to txtDate
Change its label caption to Date.
.
- Click on the fourth textbox, and change its name to txtQty
Change its label caption to Quantity
.
Align Textboxes and Labels
If the textboxes are not aligned, you can follow these steps to align them:
- Click on one of the textboxes
- Hold the Ctrl key, and click on the remaining textboxes
- Click the Format menu, then click Align, and click Lefts
- NOTE: The selected controls will align with the control that has the white handles – the one that was selected last
- Next, repeat the steps abovc, to align the labels
- Finally, save the workbook
Метки пользователя Userform VBA Excel: особенности и примеры
Метки пользователя (Userform) в VBA Excel представляют собой инструмент, который позволяет создавать пользовательские диалоговые окна и интерфейсы в программе Excel. Метки пользователя позволяют отображать и редактировать информацию, вводить данные и взаимодействовать с пользователем.
Особенностью меток пользователя является их гибкость и настраиваемость. Они могут быть оформлены в соответствии с корпоративным стилем, а также могут содержать текст, изображения, гиперссылки и другие элементы управления.
Пример использования меток пользователя может быть следующим:
- Предоставление пользователю возможности выбрать один или несколько вариантов из списка.
- Отображение информации о текущем состоянии выполнения задачи или процесса.
- Ввод и редактирование текста или числовых данных.
- Создание пользовательского интерфейса для взаимодействия с базой данных.
Для создания метки пользователя в VBA Excel необходимо использовать контрол UserForm.Label. Затем можно настроить его свойства, такие как текст (Caption), положение (Top, Left), шрифт (Font), цвет (ForeColor, BackColor) и многие другие.
Пример кода для создания метки пользователя в VBA Excel:
В данном примере создается объект метки пользователя, задается ее текст (Caption) и положение (Left, Top). Затем можно настроить другие свойства метки пользователя, если это необходимо.
Метки пользователя Userform VBA Excel предоставляют широкие возможности для создания пользовательских интерфейсов и взаимодействия с данными в программе Excel. Они позволяют отобразить информацию, сделать ее доступной для редактирования и взаимодействия с пользователем
Важно учитывать особенности работы с метками пользователя и правильно настраивать их свойства, чтобы получить желаемый результат
Step 4: Add code to populate the category combo box
As the number of categories is dynamic, we will have to dynamically populate the category combo box each time the form is loaded.
Code module of a form is referred to using “newForm.CodeModule”. The InsertLines method is used to add a line of code at a particular line number.
Note that we have started inserting the code at line 2. This is because, if “Require Variable Declaration” is enabled, first line of the code will always be “Option Explicit” and we want our code to be placed after that.
“UserForm_Initialize” is the sub that will be called when a user form is loaded. So, we will insert our code in this sub. The AddItem method is used to populate the combo box.
Кнопки опций (Option Buttons)
Пользователь может выбрать только одну кнопку-опцию на «группу» в отличие от чекбоксов.
Чтобы создать «группу», сначала вставьте Frame, а затем OptionButton :
Здесь вы можете посмотреть пример в готовом Excel файле: userform3.xls
Как только форма была отправлена, мы введем данные в ячейку, которая связана с названием колонки и row_value chosen.
Для того, чтобы знать какие опции были выбраны, мы могли бы сделать то же самое что и в предыдущем примере (с чекбоксами), но мы используем цикл, чтобы уменьшить размер кода.
Мы собираемся использовать цикл For Each , тип цикла, который мы еще до этого не рассматривали. Этот цикл позволяет выполнять инструкции для каждого объекта в «группе объектов»:
Private Sub CommandButton1_Click () Dim column_value As String, row_value As String 'Цикл для каждого элемента управления Frame_column For Each column_button In Frame_column.Controls "Если значение элем. управления = True (тогда, если выбрано) ... If column_button.Value Then 'Переменная "column_value" принимает значение текста кнопки column_value = column_button.Caption End If Next 'Цикл для другого блока For Each row_button In Frame_row.Controls If row_button.Value Then row_value = row_button.Caption End If Next Range (column_value & row_value) = "Cell chosen!" 'Ячейка выбрана Unload Me End Sub
Сейчас эта форма вводит значение «Ячейка выбрана!» в ячейку, которая была выбрана.
Чтобы избежать баги, нам необходимо проверить , что пользователь выбрал правильно с двух наборов опций.
В этом примере, когда форма еще не завершена, кнопка «Подтверждение» («Confirm») появится в сером (будет деактивирована). Это не самое простое решение, но это хороший пример того, почему функции/процедуры является Полезные внутри формы (UserForm).
Измените текст и свойство Enabled , чтобы деактивировать кнопку.
Результат будет следующий:
В предыдущем коде мы использовали два For Each цикла, чтобы получить значение опционных кнопок (option buttons). Сейчас нам нужно использовать те же значения для кнопки «Подтверждение» («Confirm») и событие Click для десяти опций.
Для этого нам не нужно копировать циклы для каждого события, мы вызовем их через функцию.
Начнем с предыдущего кода и модифицируя его, мы достигнем этого результата:
Private Function column_value() 'Функция, которая возвращает текстовое значение для выбранной кнопки (column_value) For Each column_button In Frame_column.Controls If column_button.Value Then column_value = column_button.Caption End If Next End Function Private Function row_value() 'Функция, которая возвращает текстовое значение для выбранной кнопки (row_value) For Each row_button In Frame_row.Controls If row_button.Value Then row_value = row_button.Caption End If Next End Function Private Sub CommandButton1_Click () 'Действие, происходит при нажатии "Confirm your selection" ("Подтвердите свой выбор") Range (column_value & row_value) = "Cell chosen!" 'column_value и row_value являются значениями, которые возвращаються этими функциями Unload Me End Sub
Все что нам осталось сделать, это создать процедуру, которая проверяет , что кнопки опций были выбраны корректно (через вызов двух функций), и которые активируют эту кнопку когда нужно.
Опять же, проверка выполняется в отдельной процедуре, чтобы избежать копирования кода 10 раз для каждого события каждого опционной кнопки:
Private Sub activate_button () 'Активация кнопки, если условие успешно проверено If column_value "" And row_value "" Then 'column_value и row_value являются значениями, которые возвращаються этими функциями CommandButton1.Enabled = True CommandButton1.Caption = "Confirm your selection" End If End Sub Private Sub OptionButton11_Click () activate_button 'Запускаем процедуру "activate_button" End Sub Private Sub OptionButton12_Click() activate_button End Sub Private Sub OptionButton13_Click() activate_button End Sub Private Sub OptionButton14_Click() activate_button End Sub Private Sub OptionButton15_Click() activate_button End Sub Private Sub OptionButton16_Click() activate_button End Sub Private Sub OptionButton17_Click() activate_button End Sub Private Sub OptionButton18_Click() activate_button End Sub Private Sub OptionButton19_Click() activate_button End Sub Private Sub OptionButton20_Click() activate_button End Sub
Здесь вы можете посмотреть пример в готовом Excel файле: userform3b.xls
VBA-Урок 12.1. Пользовательские формы (UserForm)
VBA-Урок 12.3. Элементы управления (Controls)