Программное создание пользовательской формы из кода VBA Excel. Добавление на форму кнопки и события Click в модуль созданной формы. Удаление формы.
Программная работа с формой
Чтобы программно создавать формы и модули, в настройках Excel должна быть установлена галочка в опции «Доверять доступ к объектной модели проектов VBA», расположенной по адресу: «Файл» >> «Параметры» >> «Центр управления безопасностью» >> «Параметры центра управления безопасностью» >> «Параметры макросов».
Создание
Пользовательская форма программно (динамически) может быть создана только как элемент коллекции VBComponents проекта VBA:
Dim myForm As Object Set myForm = ThisWorkbook.VBProject.VBComponents.Add(3) |
Число (3) означает, что создается форма, если заменить его на (1), будет создан стандартный модуль.
Значения свойствам формы myForm, как элемента коллекции VBComponents, присваиваются следующим образом:
With myForm .Properties(«Name») = «myForm1» ‘Иногда эта строка вызывает ошибку .Properties(«Caption») = «Эта форма создана программно» .Properties(«Width») = 300 .Properties(«Height») = 150 End With |
Присвоенные значения параметров динамической формы, как элемента коллекции VBComponents, сохраняются при закрытии формы.
Для элемента коллекции UserForms присвоение значений свойств будет выглядеть следующим образом:
Dim myForm As Object, myFormForms As Object ‘Создаем форму как элемент коллекции VBComponents Set myForm = ThisWorkbook.VBProject.VBComponents.Add(3) ‘На основе myForm создаем элемент коллекции UserForms Set myFormForms = UserForms.Add(myForm.Name) With myFormForms .Caption = «Эта форма создана программно» .Width = 300 .Height = 150 .Show End With |
Присвоенные значения параметров динамической формы, как элемента коллекции UserForms, не сохраняются при закрытии формы.
Я не рекомендую работать из кода VBA Excel с программно созданной формой, как элементом коллекции UserForms, кроме случая, когда необходимо отобразить динамическую форму на экране. В других случаях можно получить непредсказуемые результаты, например, могут не работать программно созданные кнопки, а также они будут исчезать при закрытии формы.
Отображение
Здесь возникает проблема: у динамической формы, созданной как элемент коллекции VBComponents, нет метода, который позволил бы ее отобразить на экране.
Чтобы обойти это препятствие, преобразуем нашу форму myForm в элемент коллекции UserForms, как в предыдущем примере, и выводим ее на экран с помощью метода Show:
‘извлекая имя из объектной переменной UserForms.Add(myForm.Name).Show ‘или сразу по ранее присвоенному имени UserForms.Add(«myForm1»).Show |
Удаление
Удаление программно созданных форм, если это не однократное действие, крайне важно. Если этого не предусмотреть, то все вновь создаваемые формы будут сохраняться и накапливаться в проекте VBA.
Удаляем динамически созданную форму с именем myForm1 следующим образом:
With ThisWorkbook.VBProject.VBComponents .Remove .Item(«myForm1») End With |
Программно удалить форму можно только через элемент коллекции VBComponents, так как у элемента коллекции UserForms удаление не предусмотрено (нет соответствующего метода).
Добавление кнопки на форму
Код VBA Excel, добавляющий командную кнопку на динамически созданную форму и задающий ее свойства:
Dim myButton As Control Set myButton = myForm.Designer.Controls.Add(«Forms.CommandButton.1») With myButton .Name = «myCommandButton» .Caption = «Новая кнопка» .Font.Size = 10 .Left = 100 .Top = 80 .Width = 100 .Height = 20 End With |
Здесь, при создании кнопки на основе элемента коллекции VBComponents, добавляется только объект Designer, которого нет при программном создании элементов управления на основе элемента коллекции UserForms (также смотрите пример кода ниже). Константы, указывающие на класс создаваемого элемента управления, используются те же.
Запись процедуры в модуль
В модуль динамически созданной формы myForm запишем код, который будет выполняться при клике по программно созданной в предыдущем примере кнопке myButton (объектная переменная) с именем «myCommandButton». Этот код создает на форме элемент управления Label, выравнивает его и записывает в него текст: «Ура! Новая кнопка работает!».
Текст процедуры
Обработка события Click для кнопки с именем «myCommandButton»:
Private Sub myCommandButton_Click() Dim myLabel As Object Set myLabel = Me.Controls.Add(«Forms.Label.1») With myLabel .Caption = «Ура! Новая кнопка работает!» .Font.Size = 10 .Left = 85 .Top = 30 .Width = 200 .Height = 20 End With End Sub |
Способ 1
Первый способ предназначен для записи в модуль формы myForm кода процедуры целиком. Для этого используется метод AddFromString:
myForm.CodeModule.AddFromString («Private Sub myCommandButton_Click()» & vbNewLine & _ «Dim myLabel As Object» & vbNewLine & _ «Set myLabel = Me.Controls.Add(« & Chr(34) & «Forms.Label.1» & Chr(34) & «)» & vbNewLine & _ «With myLabel» & vbNewLine & _ «.Caption = « & Chr(34) & «Ура! Новая кнопка работает!» & Chr(34) & vbNewLine & _ «.Font.Size = 10» & vbNewLine & _ «.Left = 85» & vbNewLine & _ «.Top = 30» & vbNewLine & _ «.Width = 200» & vbNewLine & _ «.Height = 20» & vbNewLine & _ «End With» & vbNewLine & _ «End Sub») |
Все прямые кавычки из текста процедуры заменены на функцию Chr(34), где 34 – числовой код парной прямой кавычки.
Способ 2
Этот способ предполагает запись кода процедуры в модуль формы myForm построчно. Для этого используется метод InsertLines:
Dim n As Integer With myForm.CodeModule n = .CountOfLines .InsertLines n + 1, «Private Sub myCommandButton_Click()» .InsertLines n + 2, «Dim myLabel As Object» .InsertLines n + 3, «Set myLabel = Me.Controls.Add(« & Chr(34) & «Forms.Label.1» & Chr(34) & «)» .InsertLines n + 4, «With myLabel» .InsertLines n + 5, «.Caption = « & Chr(34) & «Ура! Новая кнопка работает!» & Chr(34) .InsertLines n + 6, «.Font.Size = 10» .InsertLines n + 7, «.Left = 85» .InsertLines n + 8, «.Top = 30» .InsertLines n + 9, «.Width = 200» .InsertLines n + 10, «.Height = 20» .InsertLines n + 11, «End With» .InsertLines n + 12, «End Sub» End With |
Свойство модуля CountOfLines возвращает количество уже имеющихся в модуле строк, что позволяет с помощью переменной n добавлять новые строки ниже. Это актуально, если используется для записи кода уже существующий модуль, или новый модуль, в который записывается сразу несколько процедур.
Пример создания и удаления формы
Пример кода VBA Excel по динамическому созданию новой пользовательской формы, добавлению на нее командной кнопки и программного кода в ее модуль:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
Sub AddNewForm() ‘Создаем форму, как новый экземпляр коллекции VBComponents Dim myForm As Object Set myForm = ThisWorkbook.VBProject.VBComponents.Add(3) ‘Присваиваем значения свойствам формы myForm With myForm .Properties(«Name») = «myForm1» .Properties(«Caption») = «Эта форма создана программно» .Properties(«Width») = 300 .Properties(«Height») = 150 End With ‘Создаем командную кнопку Dim myButton As Control Set myButton = myForm.Designer.Controls.Add(«Forms.CommandButton.1») ‘Присваиваем значения свойствам кнопки With myButton .Name = «myCommandButton» .Caption = «Новая кнопка» .Font.Size = 10 .Left = 100 .Top = 80 .Width = 100 .Height = 20 End With ‘Записываем текст процедуры в модуль формы myForm Dim n As Integer With myForm.CodeModule n = .CountOfLines .InsertLines n + 1, «Private Sub myCommandButton_Click()» .InsertLines n + 2, «Dim myLabel As Object» .InsertLines n + 3, «Set myLabel = Me.Controls.Add(« & Chr(34) & «Forms.Label.1» & Chr(34) & «)» .InsertLines n + 4, «With myLabel» .InsertLines n + 5, «.Caption = « & Chr(34) & «Ура! Новая кнопка работает!» & Chr(34) .InsertLines n + 6, «.Font.Size = 10» .InsertLines n + 7, «.Left = 85» .InsertLines n + 8, «.Top = 30» .InsertLines n + 9, «.Width = 200» .InsertLines n + 10, «.Height = 20» .InsertLines n + 11, «End With» .InsertLines n + 12, «End Sub» End With ‘Отображаем форму на экране UserForms.Add(myForm.Name).Show Set myForm = Nothing End Sub |
Пример удаления формы «myForm1», созданной процедурой «AddNewForm»:
Sub RemoveForm() With ThisWorkbook.VBProject.VBComponents .Remove .Item(«myForm1») End With End Sub |
Вы можете скопировать этот код в стандартный модуль и проверить его работоспособность. После отображения динамически созданной пользовательской формы, нажмите кнопку «Новая кнопка». Результат работы кода:
Если хотите увидеть программно записанный код в модуле формы, кликните по форме правой кнопкой мыши и выберите в контекстном меню «View Code».
После удаления программно созданной формы, создать новую с тем же именем без перезагрузки Excel не получится. Без перезагрузки можно создавать любое количество динамических форм с разными именами.
Перезагрузка Excel – это закрытие всех открытых рабочих книг с последующим открытием любой книги.
Как скопировать пользовательскую форму из одной книги Excel в другую книгу с помощью кода VBA смотрите в статье Экспорт и импорт пользовательской формы.
Динамическое создание пользовательской формы
25.02.2018, 16:58. Показов 8492. Ответов 2
Возникла необходимость создать форму не вручную, используя встроенный редактор, а программно, в зависимости от внешних условий. Нашел пример как можно создать форму, поместить на нее заданное количество текстовых полей и кнопку. А также указать обработчики событий для каждого элемента.
Т.е. сначала программно добавляется в проект форма, затем на эту форму добавляются компоненты, далее компоненты связываются с событиями. В проекте создается три модуля: обычный программный модуль и два модуля класса. В одном модуле класса определяются коллекции, в которые добавляются компоненты по мере их добавления на форму. Второй класс будет отвечать за события, происходящие с компонентами.
Программный модуль:
Visual Basic | ||
|
Модуль класса 1:
Visual Basic | ||
|
Модуль класса 2:
Visual Basic | ||
|
При запуске ругается на отсутствие объявления пользовательских типов ControlsOnForm, EventsOfControls.
Пожалуйста, помогите довести скрипт до работоспособного состояния.
0
Одной из лучших книг по VBA является книга Джона Уокенбаха «Профессиональное программирование на VBA в Excel 2002». У этого автора есть такая же книга и для более поздних версий Excel.
Сейчас появилась возможность кое-что вспомнить по применению VBA. Сам Уокенбах относится к динамическому созданию форм как к не имеющему практической пользы приёму. Но это не всегда так.
Например, сейчас я решил потратить часть своего времени на создание некоего модуля на VBA по заполнению таблиц мониторинга по кадрам по школе. Таких кадровых таблиц около 10. Главное связать все расчеты периодов и количества лет к конкретной дате. Конечно, для этого сначала надо иметь выверенную базу данных по каждому учителю школы, чтобы создавать правильно заполненные листы Excel, содержащие отдельные таблицы по кадрам. После получения отчетов в Excel останется тупо перенести данные руками на сайт мониторинга.
Для ведения базы данных необходимо иметь модуль заполнения и корректировки данных по каждому учителю. Так как полей может быть множество, то появляется уже смысл в динамическом создании формы ввода и корректировки данных.
Все предлагаемые сейчас в Интернете методы оказались или неработоспособны, или в них надо долго разбираться, или надо каждый раз регистрироваться на сайте, чтобы получить доступ к выложенным файлам. Поэтому я и обратился к указанной выше книге и автору. Советы от него и предлагаемые макросы просто прекрасны.
Предлагаю переделанный модуль для динамического программирования конкретной формы. Возникла лишь одна проблема с именами контролов. Их изменить программно не получается, поэтому я и пошёл по пути получения имён TextBox через текст в них.
У меня всё работает. До сих пор я использую по старинке офис 2003, хотя опробовал в работе и 2016, у которого очень много дополнительных возможностей. В примере список полей берётся с последнего листа, а сам этот список получен транспонированием шапки.
Шапка – пока лишь некоторая заготовка.
Содержание
- Применение инструментов заполнения
- Способ 1: встроенный объект для ввода данных Excel
- Способ 2: создание пользовательской формы
- Вопросы и ответы
Для облегчения ввода данных в таблицу в Excel можно воспользоваться специальными формами, которые помогут ускорить процесс заполнения табличного диапазона информацией. В Экселе имеется встроенный инструмент позволяющий производить заполнение подобным методом. Также пользователь может создать собственный вариант формы, которая будет максимально адаптирована под его потребности, применив для этого макрос. Давайте рассмотрим различные варианты использования этих полезных инструментов заполнения в Excel.
Применение инструментов заполнения
Форма заполнения представляет собой объект с полями, наименования которых соответствуют названиям колонок столбцов заполняемой таблицы. В эти поля нужно вводить данные и они тут же будут добавляться новой строкой в табличный диапазон. Форма может выступать как в виде отдельного встроенного инструмента Excel, так и располагаться непосредственно на листе в виде его диапазона, если она создана самим пользователем.
Теперь давайте рассмотрим, как пользоваться этими двумя видами инструментов.
Способ 1: встроенный объект для ввода данных Excel
Прежде всего, давайте узнаем, как применять встроенную форму для ввода данных Excel.
- Нужно отметить, что по умолчанию значок, который её запускает, скрыт и его нужно активировать. Для этого переходим во вкладку «Файл», а затем щелкаем по пункту «Параметры».
- В открывшемся окне параметров Эксель перемещаемся в раздел «Панель быстрого доступа». Большую часть окна занимает обширная область настроек. В левой её части находятся инструменты, которые могут быть добавлены на панель быстрого доступа, а в правой – уже присутствующие.
В поле «Выбрать команды из» устанавливаем значение «Команды не на ленте». Далее из списка команд, расположенного в алфавитном порядке, находим и выделяем позицию «Форма…». Затем жмем на кнопку «Добавить».
- После этого нужный нам инструмент отобразится в правой части окна. Жмем на кнопку «OK».
- Теперь данный инструмент располагается в окне Excel на панели быстрого доступа, и мы им можем воспользоваться. Он будет присутствовать при открытии любой книги данным экземпляром Excel.
- Теперь, чтобы инструмент понял, что именно ему нужно заполнять, следует оформить шапку таблицы и записать любое значение в ней. Пусть табличный массив у нас будет состоять из четырех столбцов, которые имеют названия «Наименование товара», «Количество», «Цена» и «Сумма». Вводим данные названия в произвольный горизонтальный диапазон листа.
- Также, чтобы программа поняла, с каким именно диапазонам ей нужно будет работать, следует ввести любое значение в первую строку табличного массива.
- После этого выделяем любую ячейку заготовки таблицы и щелкаем на панели быстрого доступа по значку «Форма…», который мы ранее активировали.
- Итак, открывается окно указанного инструмента. Как видим, данный объект имеет поля, которые соответствуют названиям столбцов нашего табличного массива. При этом первое поле уже заполнено значением, так как мы его ввели вручную на листе.
- Вводим значения, которые считаем нужными и в остальные поля, после чего жмем на кнопку «Добавить».
- После этого, как видим, в первую строку таблицы были автоматически перенесены введенные значения, а в форме произошел переход к следующему блоку полей, который соответствуют второй строке табличного массива.
- Заполняем окно инструмента теми значениями, которые хотим видеть во второй строке табличной области, и снова щелкаем по кнопке «Добавить».
- Как видим, значения второй строчки тоже были добавлены, причем нам даже не пришлось переставлять курсор в самой таблице.
- Таким образом, заполняем табличный массив всеми значениями, которые хотим в неё ввести.
- Кроме того, при желании, можно производить навигацию по ранее введенным значениям с помощью кнопок «Назад» и «Далее» или вертикальной полосы прокрутки.
- При необходимости можно откорректировать любое значение в табличном массиве, изменив его в форме. Чтобы изменения отобразились на листе, после внесения их в соответствующий блок инструмента, жмем на кнопку «Добавить».
- Как видим, изменение сразу произошло и в табличной области.
- Если нам нужно удалить, какую-то строчку, то через кнопки навигации или полосу прокрутки переходим к соответствующему ей блоку полей в форме. После этого щелкаем по кнопке «Удалить» в окошке инструмента.
- Открывается диалоговое окно предупреждения, в котором сообщается, что строка будет удалена. Если вы уверены в своих действиях, то жмите на кнопку «OK».
- Как видим, строчка была извлечена из табличного диапазона. После того, как заполнение и редактирование закончено, можно выходить из окна инструмента, нажав на кнопку «Закрыть».
- После этого для предания табличному массиву более наглядного визуального вида можно произвести форматирование.
Способ 2: создание пользовательской формы
Кроме того, с помощью макроса и ряда других инструментов существует возможность создать собственную пользовательскую форму для заполнения табличной области. Она будет создаваться прямо на листе, и представлять собой её диапазон. С помощью данного инструмента пользователь сам сможет реализовать те возможности, которые считает нужными. По функционалу он практически ни в чем не будет уступать встроенному аналогу Excel, а кое в чем, возможно, превосходить его. Единственный недостаток состоит в том, что для каждого табличного массива придется составлять отдельную форму, а не применять один и тот же шаблон, как это возможно при использовании стандартного варианта.
- Как и в предыдущем способе, прежде всего, нужно составить шапку будущей таблицы на листе. Она будет состоять из пяти ячеек с именами: «№ п/п», «Наименование товара», «Количество», «Цена», «Сумма».
- Далее нужно из нашего табличного массива сделать так называемую «умную» таблицу, с возможностью автоматического добавления строчек при заполнении соседних диапазонов или ячеек данными. Для этого выделяем шапку и, находясь во вкладке «Главная», жмем на кнопку «Форматировать как таблицу» в блоке инструментов «Стили». После этого открывается список доступных вариантов стилей. На функционал выбор одного из них никак не повлияет, поэтому выбираем просто тот вариант, который считаем более подходящим.
- Затем открывается небольшое окошко форматирования таблицы. В нем указан диапазон, который мы ранее выделили, то есть, диапазон шапки. Как правило, в данном поле заполнено все верно. Но нам следует установить галочку около параметра «Таблица с заголовками». После этого жмем на кнопку «OK».
- Итак, наш диапазон отформатирован, как «умная» таблица, свидетельством чему является даже изменение визуального отображения. Как видим, помимо прочего, около каждого названия заголовка столбцов появились значки фильтрации. Их следует отключить. Для этого выделяем любую ячейку «умной» таблицы и переходим во вкладку «Данные». Там на ленте в блоке инструментов «Сортировка и фильтр» щелкаем по значку «Фильтр».
Существует ещё один вариант отключения фильтра. При этом не нужно даже будет переходить на другую вкладку, оставаясь во вкладке «Главная». После выделения ячейки табличной области на ленте в блоке настроек «Редактирование» щелкаем по значку «Сортировка и фильтр». В появившемся списке выбираем позицию «Фильтр».
- Как видим, после этого действия значки фильтрации исчезли из шапки таблицы, как это и требовалось.
- Затем нам следует создать саму форму ввода данных. Она тоже будет представлять собой своего рода табличный массив, состоящий из двух столбцов. Наименования строк данного объекта будут соответствовать именам столбцов основной таблицы. Исключение составляют столбцы «№ п/п» и «Сумма». Они будут отсутствовать. Нумерация первого из них будет происходить при помощи макроса, а расчет значений во втором будет производиться путем применения формулы умножения количества на цену.
Второй столбец объекта ввода данных оставим пока что пустым. Непосредственно в него позже будут вводиться значения для заполнения строк основного табличного диапазона.
- После этого создаем ещё одну небольшую таблицу. Она будет состоять из одного столбца и в ней разместится список товаров, которые мы будем выводить во вторую колонку основной таблицы. Для наглядности ячейку с заголовком данного перечня («Список товаров») можно залить цветом.
- Затем выделяем первую пустую ячейку объекта ввода значений. Переходим во вкладку «Данные». Щелкаем по значку «Проверка данных», который размещен на ленте в блоке инструментов «Работа с данными».
- Запускается окно проверки вводимых данных. Кликаем по полю «Тип данных», в котором по умолчанию установлен параметр «Любое значение».
- Из раскрывшихся вариантов выбираем позицию «Список».
- Как видим, после этого окно проверки вводимых значений несколько изменило свою конфигурацию. Появилось дополнительное поле «Источник». Щелкаем по пиктограмме справа от него левой клавишей мыши.
- Затем окно проверки вводимых значений сворачивается. Выделяем курсором с зажатой левой клавишей мыши перечень данных, которые размещены на листе в дополнительной табличной области «Список товаров». После этого опять жмем на пиктограмму справа от поля, в котором появился адрес выделенного диапазона.
- Происходит возврат к окошку проверки вводимых значений. Как видим, координаты выделенного диапазона в нем уже отображены в поле «Источник». Кликаем по кнопке «OK» внизу окна.
- Теперь справа от выделенной пустой ячейки объекта ввода данных появилась пиктограмма в виде треугольника. При клике на неё открывается выпадающий список, состоящий из названий, которые подтягиваются из табличного массива «Список товаров». Произвольные данные в указанную ячейку теперь внести невозможно, а только можно выбрать из представленного списка нужную позицию. Выбираем пункт в выпадающем списке.
- Как видим, выбранная позиция тут же отобразилась в поле «Наименование товара».
- Далее нам нужно будет присвоить имена тем трем ячейкам формы ввода, куда мы будем вводить данные. Выделяем первую ячейку, где уже установлено в нашем случае наименование «Картофель». Далее переходим в поле наименования диапазонов. Оно расположено в левой части окна Excel на том же уровне, что и строка формул. Вводим туда произвольное название. Это может быть любое наименование на латинице, в котором нет пробелов, но лучше все-таки использовать названия близкие к решаемым данным элементом задачам. Поэтому первую ячейку, в которой содержится название товара, назовем «Name». Пишем данное наименование в поле и жмем на клавишу Enter на клавиатуре.
- Точно таким же образом присваиваем ячейке, в которую будем вводить количество товара, имя «Volum».
- А ячейке с ценой – «Price».
- После этого точно таким же образом даем название всему диапазону из вышеуказанных трех ячеек. Прежде всего, выделим, а потом дадим ему наименование в специальном поле. Пусть это будет имя «Diapason».
- После последнего действия обязательно сохраняем документ, чтобы названия, которые мы присвоили, смог воспринимать макрос, созданный нами в дальнейшем. Для сохранения переходим во вкладку «Файл» и кликаем по пункту «Сохранить как…».
- В открывшемся окне сохранения в поле «Тип файлов» выбираем значение «Книга Excel с поддержкой макросов (.xlsm)». Далее жмем на кнопку «Сохранить».
- Затем вам следует активировать работу макросов в своей версии Excel и включить вкладку «Разработчик», если вы это до сих пор не сделали. Дело в том, что обе эти функции по умолчанию в программе отключены, и их активацию нужно выполнять принудительно в окне параметров Excel.
- После того, как вы сделали это, переходим во вкладку «Разработчик». Кликаем по большому значку «Visual Basic», который расположен на ленте в блоке инструментов «Код».
- Последнее действие приводит к тому, что запускается редактор макросов VBA. В области «Project», которая расположена в верхней левой части окна, выделяем имя того листа, где располагаются наши таблицы. В данном случае это «Лист 1».
- После этого переходим к левой нижней области окна под названием «Properties». Тут расположены настройки выделенного листа. В поле «(Name)» следует заменить кириллическое наименование («Лист1») на название, написанное на латинице. Название можно дать любое, которое вам будет удобнее, главное, чтобы в нем были исключительно символы латиницы или цифры и отсутствовали другие знаки или пробелы. Именно с этим именем будет работать макрос. Пусть в нашем случае данным названием будет «Producty», хотя вы можете выбрать и любое другое, соответствующее условиям, которые были описаны выше.
В поле «Name» тоже можно заменить название на более удобное. Но это не обязательно. При этом допускается использование пробелов, кириллицы и любых других знаков. В отличие от предыдущего параметра, который задает наименование листа для программы, данный параметр присваивает название листу, видимое пользователю на панели ярлыков.
Как видим, после этого автоматически изменится и наименование Листа 1 в области «Project», на то, которое мы только что задали в настройках.
- Затем переходим в центральную область окна. Именно тут нам нужно будет записать сам код макроса. Если поле редактора кода белого цвета в указанной области не отображается, как в нашем случае, то жмем на функциональную клавишу F7 и оно появится.
- Теперь для конкретно нашего примера нужно записать в поле следующий код:
Sub DataEntryForm()
Dim nextRow As Long
nextRow = Producty.Cells(Producty.Rows.Count, 2).End(xlUp).Offset(1, 0).Row
With Producty
If .Range("A2").Value = "" And .Range("B2").Value = "" Then
nextRow = nextRow - 1
End If
Producty.Range("Name").Copy
.Cells(nextRow, 2).PasteSpecial Paste:=xlPasteValues
.Cells(nextRow, 3).Value = Producty.Range("Volum").Value
.Cells(nextRow, 4).Value = Producty.Range("Price").Value
.Cells(nextRow, 5).Value = Producty.Range("Volum").Value * Producty.Range("Price").Value
.Range("A2").Formula = "=IF(ISBLANK(B2), """", COUNTA($B$2:B2))"
If nextRow > 2 Then
Range("A2").Select
Selection.AutoFill Destination:=Range("A2:A" & nextRow)
Range("A2:A" & nextRow).Select
End If
.Range("Diapason").ClearContents
End With
End Sub
Но этот код не универсальный, то есть, он в неизменном виде подходит только для нашего случая. Если вы хотите его приспособить под свои потребности, то его следует соответственно модифицировать. Чтобы вы смогли сделать это самостоятельно, давайте разберем, из чего данный код состоит, что в нем следует заменить, а что менять не нужно.
Итак, первая строка:
Sub DataEntryForm()
«DataEntryForm» — это название самого макроса. Вы можете оставить его как есть, а можете заменить на любое другое, которое соответствует общим правилам создания наименований макросов (отсутствие пробелов, использование только букв латинского алфавита и т.д.). Изменение наименования ни на что не повлияет.
Везде, где встречается в коде слово «Producty» вы должны его заменить на то наименование, которое ранее присвоили для своего листа в поле «(Name)» области «Properties» редактора макросов. Естественно, это нужно делать только в том случае, если вы назвали лист по-другому.
Теперь рассмотрим такую строку:
nextRow = Producty.Cells(Producty.Rows.Count, 2).End(xlUp).Offset(1, 0).Row
Цифра «2» в данной строчке означает второй столбец листа. Именно в этом столбце находится колонка «Наименование товара». По ней мы будем считать количество рядов. Поэтому, если в вашем случае аналогичный столбец имеет другой порядок по счету, то нужно ввести соответствующее число. Значение «End(xlUp).Offset(1, 0).Row» в любом случае оставляем без изменений.
Далее рассмотрим строку
If .Range("A2").Value = "" And .Range("B2").Value = "" Then
«A2» — это координаты первой ячейки, в которой будет выводиться нумерация строк. «B2» — это координаты первой ячейки, по которой будет производиться вывод данных («Наименование товара»). Если они у вас отличаются, то введите вместо этих координат свои данные.
Переходим к строке
Producty.Range("Name").Copy
В ней параметр «Name» означат имя, которое мы присвоили полю «Наименование товара» в форме ввода.
В строках
.Cells(nextRow, 2).PasteSpecial Paste:=xlPasteValues
.Cells(nextRow, 3).Value = Producty.Range("Volum").Value
.Cells(nextRow, 4).Value = Producty.Range("Price").Value
.Cells(nextRow, 5).Value = Producty.Range("Volum").Value * Producty.Range("Price").Value
наименования «Volum» и «Price» означают названия, которые мы присвоили полям «Количество» и «Цена» в той же форме ввода.
В этих же строках, которые мы указали выше, цифры «2», «3», «4», «5» означают номера столбцов на листе Excel, соответствующих колонкам «Наименование товара», «Количество», «Цена» и «Сумма». Поэтому, если в вашем случае таблица сдвинута, то нужно указать соответствующие номера столбцов. Если столбцов больше, то по аналогии нужно добавить её строки в код, если меньше – то убрать лишние.
В строке производится умножение количества товара на его цену:
.Cells(nextRow, 5).Value = Producty.Range("Volum").Value * Producty.Range("Price").Value
Результат, как видим из синтаксиса записи, будет выводиться в пятый столбец листа Excel.
В этом выражении выполняется автоматическая нумерация строк:
If nextRow > 2 Then
Range("A2").Select
Selection.AutoFill Destination:=Range("A2:A" & nextRow)
Range("A2:A" & nextRow).Select
End If
Все значения «A2» означают адрес первой ячейки, где будет производиться нумерация, а координаты «A» — адрес всего столбца с нумерацией. Проверьте, где именно будет выводиться нумерация в вашей таблице и измените данные координаты в коде, если это необходимо.
В строке производится очистка диапазона формы ввода данных после того, как информация из неё была перенесена в таблицу:
.Range("Diapason").ClearContents
Не трудно догадаться, что («Diapason») означает наименование того диапазона, который мы ранее присвоили полям для ввода данных. Если вы дали им другое наименование, то в этой строке должно быть вставлено именно оно.
Дальнейшая часть кода универсальна и во всех случаях будет вноситься без изменений.
После того, как вы записали код макроса в окно редактора, следует нажать на значок сохранения в виде дискеты в левой части окна. Затем можно его закрывать, щелкнув по стандартной кнопке закрытия окон в правом верхнем углу.
- После этого возвращаемся на лист Excel. Теперь нам следует разместить кнопку, которая будет активировать созданный макрос. Для этого переходим во вкладку «Разработчик». В блоке настроек «Элементы управления» на ленте кликаем по кнопке «Вставить». Открывается перечень инструментов. В группе инструментов «Элементы управления формы» выбираем самый первый – «Кнопка».
- Затем с зажатой левой клавишей мыши обводим курсором область, где хотим разместить кнопку запуска макроса, который будет производить перенос данных из формы в таблицу.
- После того, как область обведена, отпускаем клавишу мыши. Затем автоматически запускается окно назначения макроса объекту. Если в вашей книге применяется несколько макросов, то выбираем из списка название того, который мы выше создавали. У нас он называется «DataEntryForm». Но в данном случае макрос один, поэтому просто выбираем его и жмем на кнопку «OK» внизу окна.
- После этого можно переименовать кнопку, как вы захотите, просто выделив её текущее название.
В нашем случае, например, логично будет дать ей имя «Добавить». Переименовываем и кликаем мышкой по любой свободной ячейке листа.
- Итак, наша форма полностью готова. Проверим, как она работает. Вводим в её поля необходимые значения и жмем на кнопку «Добавить».
- Как видим, значения перемещены в таблицу, строке автоматически присвоен номер, сумма посчитана, поля формы очищены.
- Повторно заполняем форму и жмем на кнопку «Добавить».
- Как видим, и вторая строка также добавлена в табличный массив. Это означает, что инструмент работает.
Читайте также:
Как создать макрос в Excel
Как создать кнопку в Excel
В Экселе существует два способа применения формы заполнения данными: встроенная и пользовательская. Применение встроенного варианта требует минимум усилий от пользователя. Его всегда можно запустить, добавив соответствующий значок на панель быстрого доступа. Пользовательскую форму нужно создавать самому, но если вы хорошо разбираетесь в коде VBA, то сможете сделать этот инструмент максимально гибким и подходящим под ваши нужды.
Visual Basic is an excellent language for automating repetitive tasks in Excel. Imagine taking your automation up a notch by creating highly functional user forms that also look tidy to the end-users.
User forms in VBA present you with a blank canvas; you can design and organize the forms to fit your needs at any given time.
In this guide, you will learn to create a student-based data entry form that captures relevant information in linked Excel sheets.
Creating a User Form With Excel VBA
Open a new Excel workbook and perform a few preliminary steps before you start creating your data-entry form.
Save your workbook with the desired name; don’t forget to change the file’s type to an Excel Macro-Enabled Workbook.
Add two sheets to this workbook, with the following names:
- Sheet1: Home
- Sheet2: Student Database
Feel free to change these names as per your requirements.
In the Home sheet, add a button to control the user form macro. Go to the Developer tab and click on the Button option from the Insert drop-down list. Place the button anywhere on the sheet.
Once you’ve placed the button, rename it. Right-click on it, and click on New to assign a new macro to show the form.
Enter the following code in the editor window:
Sub Button1_Click()UserForm.ShowEnd Sub
Once the Home and Student Database sheets are ready, it’s time to design the user form. Navigate to the Developer tab, and click on Visual Basic to open the Editor. Alternatively, you can press ALT+F11 to open the editor window.
Click on the Insert tab and select UserForm.
A blank user form is ready for use; an accompanying toolbox opens along with the form, which has all the essential tools to design the layout.
From the toolbox, select the Frame option. Drag this to the user form and resize it.
In the (name) option, you can change the name of the frame. To showcase the name on the front-end, you can change the name in the Caption column.
Next, select the Label option from the toolbox and insert two labels within this frame. Rename the first one as Application Number and the second as Student ID.
The same renaming logic applies; change the names via the Caption option within the Properties window. Make sure you select the respective label before changing its name.
Next, insert two text boxes next to the label boxes. These will be used to capture the user’s inputs. Change the names of two text boxes via the (Name) column within the Properties window. The names are as follows:
- Textbox1: txtApplicationNo
- Textbox2: txtStudentID
Designing the Student Details Frame
Insert a vertical frame and add 10 labels and 10 text boxes. Rename each of them in the following manner:
- Label3: Name
- Label4: Age
- Label5: Address
- Label6: Phone
- Label7: City
- Label8: Country
- Label9: Date of Birth
- Label10: Zip Code
- Label11: Nationality
- Label12: Gender
Insert corresponding text boxes next to these labels; insert two (or more) optionbutton boxes from the user form toolbox next to the gender label. Rename them Male and Female (along with Custom), respectively.
Designing the Course Details Frame
Add another vertical frame and insert six labels and six text boxes corresponding to each label. Rename the labels as follows:
- Label13: Course Name
- Label14: Course ID
- Label15: Enrollment Start Date
- Label16: Enrollment End Date
- Label17: Course duration
- Label18: Department
Designing the Payment Details Frame
Insert a new frame; add a new label and rename it «Do you wish to update the Payment details?» Insert two optionbuttons; rename them Yes and No.
Similarly, add a new frame containing two additional labels and two combo boxes. Rename the labels as follows:
- Label19: Payment Received
- Label20: Mode of Payment
Designing the Navigation Pane
In the final frame, add three buttons from the toolbox, which will contain code for the execution of the forms.
Rename the buttons in the following manner:
- Button1: Save Details
- Button2: Clear Form
- Button3: Exit
Writing the Automated Form Code: Save Details Button
Double-click on the Save Details button. In the ensuing module, insert the following code:
Private Sub CommandButton2_Click()‘declare the variables used throughout the codesDim sht As Worksheet, sht1 As Worksheet, lastrow As Long'Add validations to check if character values are being entered in numeric fields.If VBA.IsNumeric(txtApplicationNo.Value) = False ThenMsgBox "Only numeric values are accepted in the Application Number", vbCriticalExit SubEnd IfIf VBA.IsNumeric(txtStudentID.Value) = False ThenMsgBox "Only numeric values are accepted in the Student ID", vbCriticalExit SubEnd IfIf VBA.IsNumeric(txtAge.Value) = False ThenMsgBox "Only numeric values are accepted in Age", vbCriticalExit SubEnd IfIf VBA.IsNumeric(txtPhone.Value) = False ThenMsgBox "Only numeric values are accepted in Phone Number", vbCriticalExit SubEnd IfIf VBA.IsNumeric(Me.txtCourseID.Value) = False ThenMsgBox "Only numeric values are accepted in Course ID", vbCriticalExit SubEnd If'link the text box fields with the underlying sheets to create a rolling databaseSet sht = ThisWorkbook.Sheets("Student Database")'calculate last populated row in both sheetslastrow = sht.Range("a" & Rows.Count).End(xlUp).Row + 1'paste the values of each textbox into their respective sheet cellsWith sht.Range("a" & lastrow).Value = txtApplicationNo.Value.Range("b" & lastrow).Value = txtStudentID.Value.Range("c" & lastrow).Value = txtName.Value.Range("d" & lastrow).Value = txtAge.Value.Range("e" & lastrow).Value = txtDOB.Value.Range("g" & lastrow).Value = txtAddress.Value.Range("h" & lastrow).Value = txtPhone.Value.Range("i" & lastrow).Value = txtCity.Value.Range("j" & lastrow).Value = txtCountry.Value.Range("k" & lastrow).Value = txtZip.Value.Range("l" & lastrow).Value = txtNationality.Value.Range("m" & lastrow).Value = txtCourse.Value.Range("n" & lastrow).Value = txtCourseID.Value.Range("o" & lastrow).Value = txtenrollmentstart.Value.Range("p" & lastrow).Value = txtenrollmentend.Value.Range("q" & lastrow).Value = txtcourseduration.Value.Range("r" & lastrow).Value = txtDept.ValueEnd Withsht.Activate'determine gender as per user's inputIf optMale.Value = True Then sht.Range("g" & lastrow).Value = "Male"If optFemale.Value = True Then sht.Range("g" & lastrow).Value = "Female"'Display a message box, in case the user selects the Yes radio buttonIf optYes.Value = True ThenMsgBox "Please select the payment details below"Else:Exit SubEnd IfEnd Sub
If you’re not sure what parts or any of the code means, don’t worry. We’ll explain it thoroughly in the next section.
Automated Form Code Explained
The textboxes will contain a mix of text and numeric values, so it’s essential to restrict the user’s input. The Application Number, Student ID, Age, Phone, Course ID, and Course Duration should contain only numbers, while the rest will contain text.
Using an IF statement, the code triggers error pop-ups if the user enters a character or text value in any of the numeric fields.
Since the error validations are in place, you need to link the text boxes with the sheet cells.
The lastrow variables will calculate the last populated row, and store the values in them for dynamic use.
Finally, the values are pasted from the text boxes into the linked Excel sheet.
Clear Form and Exit Button Codes
In the clear button, you need to write the code to clear the existing values from the user form. This can be done in the following manner:
With Me.txtApplicationNo.Value = "".txtStudentID.Value = ""..txtName.Value = "".txtAge.Value = "".txtAddress.Value = "".txtPhone.Value = "".txtCity.Value = "".txtCountry.Value = "".txtDOB.Value = "".txtZip.Value = "".txtNationality.Value = "".txtCourse.Value = "".txtCourseID.Value = "".txtenrollmentstart.Value = "".txtenrollmentend.Value = "".txtcourseduration.Value = "".txtDept.Value = "".cmbPaymentMode.Value = "".cmbPayment.Value = "".optFemale.Value = False.optMale.Value = False.optYes.Value = False.optNo.Value = FalseEnd With
In the exit button, enter the following code to close the user form.
Private Sub CommandButton5_Click()Unload MeEnd Sub
As a last step, you need to input a few final pieces of code to create the drop-down values for the combo boxes (within the payment frames).
Private Sub UserForm_Activate()With cmbPayment.Clear.AddItem "".AddItem "Yes".AddItem "No"End WithWith cmbPaymentMode.Clear.AddItem "".AddItem "Cash".AddItem "Card".AddItem "Check"End WithEnd Sub
VBA Automation Makes Work Easier
VBA is a multi-faceted language that serves many purposes. User forms are only one aspect within VBA—there are many other uses like consolidating workbooks and worksheets, merging multiple Excel sheets, and other handy automation uses.
No matter the automation goal, VBA is up to the task. If you keep learning and getting practice in, there’s no aspect of your workflow you can’t improve.