Добавляем кнопку заполнения на форму в конфигураторе 1С 8.3

· 9 мин

Содержание

Кнопка заполнения на форме документа или обработки в 1С 8.3 состоит из трёх частей: команды формы, кнопки (элемента формы), привязанной к этой команде, и процедуры-обработчика. Всё делается в конфигураторе: откройте форму, на вкладке Команды создайте команду, перетащите её на вкладку Элементы, затем нажмите на команде ссылку действия и создайте процедуру.

Ниже пример для управляемой формы документа с табличной частью. Принцип тот же для формы справочника, обработки или отчёта. Правки вносят в конфигурацию, которая не стоит на поддержке или стоит с разрешёнными изменениями. Для типовых конфигураций (БП, ЗУП, УТ) поступайте аккуратнее и используйте расширение, об этом в конце.

Правьте форму в копии базы. Конфигуратор откроет её для редактирования, а сохранение попадёт в конфигурацию сразу после обновления конфигурации базы данных.

Что нужно знать до начала

Управляемая форма работает в двух контекстах. Часть кода выполняется на клиенте (в окне пользователя), часть на сервере. Из клиентской процедуры нельзя напрямую запросить данные из базы и нельзя обратиться к объекту так, как это делает серверный модуль.

Поэтому схема всегда одна:

  1. Пользователь нажимает кнопку.
  2. Срабатывает клиентская процедура с директивой &НаКлиенте.
  3. Она вызывает серверную процедуру с директивой &НаСервере.
  4. Сервер заполняет данные формы и возвращает управление.

Что понадобится:

  • 🛠️ Конфигуратор с открытой конфигурацией (режим Конфигуратор, не 1С:Предприятие);
  • 📄 объект, у которого уже есть управляемая форма (документ, справочник, обработка);
  • 🔑 роль с правом на конфигурирование, если вы работаете не под администратором.

Если у объекта форма ещё не создана, откройте объект в дереве конфигурации, на вкладке Формы нажмите кнопку добавления и выберите форму документа. В мастере оставьте основной режим и завершите создание.

Создание команды и кнопки

Откройте форму двойным щелчком. Внизу окна редактора есть вкладки: Элементы, Реквизиты, Команды, Параметры, а также Модуль для кода.

Порядок действий:

  1. Перейдите на вкладку Команды.
  2. Нажмите кнопку добавления в командной панели вкладки. Появится новая строка.
  3. В окне свойств задайте Имя (латиницей и кириллицей допускаются буквы без пробелов, например ЗаполнитьТовары) и Заголовок («Заполнить»).
  4. При желании выберите картинку и подсказку: она появится при наведении курсора.
  5. Перейдите на вкладку Элементы.
  6. Выберите группу, куда поставите кнопку. Чаще всего это командная панель формы или группа над табличной частью.
  7. Перетащите команду из вкладки Команды в нужную группу либо добавьте кнопку кнопкой добавления и в свойстве Имя команды выберите созданную команду.

Тип элемента получится Кнопка формы. Если нужна кнопка именно над табличной частью, выделите таблицу, откройте у неё свойства и найдите командную панель: кнопку добавляют в неё.

У кнопки есть свойство Вид: обычная кнопка, гиперссылка или кнопка с выпадающим списком. Для команды, которая заполняет большую часть документа, обычная кнопка заметнее.

Расположение влияет на то, как пользователь воспринимает действие. Если команда заполняет всю табличную часть, пусть кнопка стоит над таблицей. Если она заполняет шапку, поставьте её рядом с реквизитами или в общую командную панель.

Если кнопка нужна в нескольких местах

Одну команду можно привязать к нескольким кнопкам. Например, одну в командной панели формы, другую внутри табличной части. Обработчик останется единым, меняется только внешний вид и положение.

Обработчик: клиентская часть

На вкладке Команды выделите свою команду и в окне свойств у поля Действие нажмите лупу. Конфигуратор предложит создать обработчик на клиенте или на сервере. Выбирайте На клиенте: тогда создастся процедура в модуле формы.

Получится заготовка:

&НаКлиенте
Процедура ЗаполнитьТовары(Команда)
	
КонецПроцедуры

Сюда пишут то, что связано с интерфейсом: вопрос пользователю, проверку того, что шапка заполнена, вызов сервера.

Пример с проверкой и подтверждением:

&НаКлиенте
Процедура ЗаполнитьТовары(Команда)
	
	Если Объект.Товары.Количество() > 0 Тогда
		Оповещение = Новый ОписаниеОповещения("ЗаполнитьТоварыЗавершение", ЭтотОбъект);
		ПоказатьВопрос(Оповещение, 
			"Табличная часть будет очищена и заполнена заново. Продолжить?", 
			РежимДиалогаВопрос.ДаНет);
		Возврат;
	КонецЕсли;
	
	ЗаполнитьТоварыНаСервере();
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьТоварыЗавершение(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = КодВозвратаДиалога.Да Тогда
		ЗаполнитьТоварыНаСервере();
	КонецЕсли;
	
КонецПроцедуры

Вопрос нужен, потому что таблица очищается. Без него пользователь потеряет введённые вручную строки одним щелчком.

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

Обработчик: серверная часть и работа с данными

Серверная процедура получает доступ к базе. Она объявляется директивой &НаСервере:

&НаСервере
Процедура ЗаполнитьТоварыНаСервере()
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ ПЕРВЫЕ 50
		|	Номенклатура.Ссылка КАК Номенклатура
		|ИЗ
		|	Справочник.Номенклатура КАК Номенклатура
		|ГДЕ
		|	НЕ Номенклатура.ЭтоГруппа
		|	И НЕ Номенклатура.ПометкаУдаления
		|
		|УПОРЯДОЧИТЬ ПО
		|	Номенклатура.Наименование";
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	Объект.Товары.Очистить();
	Пока Выборка.Следующий() Цикл
		НоваяСтрока = Объект.Товары.Добавить();
		НоваяСтрока.Номенклатура = Выборка.Номенклатура;
		НоваяСтрока.Количество = 1;
	КонецЦикла;
	
КонецПроцедуры

Это пример-образец: подставьте имена своей табличной части и реквизитов. Условие в ГДЕ замените на реальное правило отбора, иначе кнопка принесёт в документ первые 50 позиций справочника.

Что здесь важно:

  • 📌 Объект — это данные редактируемого документа. На сервере в них можно писать, форма обновится сама после возврата в клиентскую часть;
  • 📌 Очистить() стоит до цикла, а не внутри него;
  • 📌 запрос выбирает только нужные поля: чем меньше колонок, тем быстрее работает кнопка;
  • 📌 документ не записывается. Заполнение лишь меняет данные в форме, пользователь сам решает, записывать их или нет.

Откуда брать данные для заполнения

ИсточникКогда подходитНа что смотреть
Запрос к справочнику или региструНужно подтянуть набор строк по условиюУсловие отбора и объём выборки
Другой документВвод на основании: взять строки из заказа или поступленияСсылка на документ-основание должна быть заполнена
Реквизиты формыЗаполнение шапки из контрагента, договораНе затирайте значения, которые ввёл пользователь
Константа или настройкаЗначения по умолчаниюПрава на чтение константы

Если заполнение идёт из одного документа в другой, поищите штатный механизм Ввод на основании. Он уже есть в платформе и не требует кнопки: пользователь выбирает Создать на основании, а код пишут в обработчике ОбработкаЗаполнения модуля объекта.

Если нужно заполнять не данные формы, а саму ссылку

Иногда кнопка меняет реквизит, влияющий на другие поля. Например, вы выбрали склад, а цены зависят от него. В таких случаях после заполнения вызывают процедуру пересчёта. Не копируйте код пересчёта в два места: вынесите его в отдельную процедуру и вызывайте из обработчика кнопки и из обработчика изменения реквизита.

Права доступа и видимость кнопки

По умолчанию кнопку видят все, кто открывает форму. Ограничить показ можно двумя способами.

Свойство Видимость и Доступность. Кнопка скрывается или блокируется кодом, обычно при открытии формы:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Элементы.ЗаполнитьТовары.Видимость = ПравоДоступа("Изменение", Метаданные.Документы.ЗаказПоставщику);
	
КонецПроцедуры

Здесь ЗаказПоставщику — имя вашего документа из дерева конфигурации. Функция ПравоДоступа проверяет право текущего пользователя на изменение, поэтому читатель документа кнопки не увидит.

Свойство Доступность для режима «только просмотр». Если документ открыт без права записи, кнопка вызовет ошибку при попытке записать результат. Закройте её заранее.

Ещё один вариант: у самой команды есть свойство Использование и привязка к функциональным опциям. Если опция выключена, команда пропадает со всех форм сразу. Это удобно, когда кнопка нужна только части организаций.

Скрытая кнопка не защищает данные. Если пользователь не должен менять документ, закрывайте это правами роли, а не только видимостью.

Проверка условий внутри обработчика тоже пригодится. Например, не заполнять таблицу, пока не выбран склад:

Если НЕ ЗначениеЗаполнено(Объект.Склад) Тогда
	ПоказатьПредупреждение(, "Сначала выберите склад.");
	Возврат;
КонецЕсли;

Реквизит Склад здесь условный: подставьте тот, который есть у вашего объекта.

Обратная связь пользователю после заполнения

Кнопка без отклика вызывает вопрос: сработало или нет? Покажите итог. Серверная процедура может вернуть число добавленных строк, а клиентская покажет оповещение.

Для этого серверную часть оформляют функцией:

&НаСервере
Функция ЗаполнитьТоварыНаСервере()
	
	// ... заполнение табличной части, как выше ...
	
	Возврат Объект.Товары.Количество();
	
КонецФункции

А в клиентской процедуре вызов становится таким:

Количество = ЗаполнитьТоварыНаСервере();
ПоказатьОповещениеПользователя("Заполнение завершено", , 
	"Добавлено строк: " + Формат(Количество, "ЧГ=0"));

Формат ЧГ=0 убирает разделитель групп разрядов, чтобы число не превратилось в «1 250». Склейку числа и строки без Формат или СтрШаблон не используйте: на разных настройках результат отличается.

Если выборка оказалась пустой, не оставляйте таблицу пустой молча. Сообщите пользователю, что подходящих данных нет, и предложите проверить условие: выбранный склад, период, организацию.

Длительное заполнение

Когда строк тысячи, а запрос тяжёлый, пользователь будет смотреть на «часики» и может нажать кнопку повторно. Два простых приёма:

  • 🔒 заблокируйте кнопку на время работы, выставив ей Доступность = Ложь в начале клиентской процедуры и вернув Истина после вызова сервера;
  • 📉 ограничьте выборку условием отбора и выбирайте в запросе только нужные поля.

Если выборка действительно огромна, это повод вынести заполнение в фоновое задание. Для типового заполнения формы обычно хватает обычного серверного вызова.

Кнопка в форме обработки

В обработке принцип тот же, отличаются данные: вместо Объект.Товары вы работаете с реквизитами формы или реквизитами обработки. Табличную часть обработки заполняют так же, через Очистить() и Добавить(). Серверный вызов остаётся обязательным, если нужны данные из базы.

Проверка и отладка

После правки модуля сохраните конфигурацию и запустите её командой Отладка → Начать отладку (клавиша F5). Конфигуратор сам обновит конфигурацию базы данных и откроет предприятие.

Что проверить на форме:

  • ✅ кнопка на своём месте и подписана;
  • ✅ при пустой таблице данные подтягиваются без вопроса;
  • ✅ при заполненной таблице появляется подтверждение, а «Нет» ничего не меняет;
  • ✅ под пользователем с ограниченной ролью кнопки нет или она недоступна;
  • ✅ после заполнения документ можно записать и провести.

Если нужно посмотреть, что происходит внутри, поставьте точку останова: щёлкните слева от нужной строки в модуле формы или нажмите F9. Выполнение остановится на строке, а в окне Вычислить выражение (Shift+F9) можно посмотреть значения. Серверный код отлаживается тем же способом, если запущена отладка на сервере.

Хороший приём: сначала выведите результат запроса в сообщение и убедитесь, что выборка непустая, и только потом пишите цикл. Сообщение выводит метод Сообщить(...); на сервере оно появится в окне сообщений после завершения вызова.

Типичные ошибки

Разберём четыре ситуации, которые встречаются чаще всего.

  • ❌ Поле объекта не обнаружено (ЗаполнитьТоварыНаСервере) или похожий текст. Причина — в коде указано имя реквизита, которого нет у объекта. Проверьте написание: регистр в 1С не важен, а опечатка важна.
  • ❌ Кнопка есть, но ничего не происходит. Откройте свойства команды: поле Действие должно быть заполнено. Если оно пустое, процедуры нет. Ещё один вариант: обработчик создан, но в нём нет вызова серверной процедуры.
  • ❌ Ошибка про недопустимый вызов на клиенте. Вы пытаетесь выполнить запрос или обратиться к справочнику в процедуре с &НаКлиенте. Перенесите это в серверную процедуру.
  • ❌ После заполнения форма не показывает новые строки. Проверьте, что заполняется Объект.Товары, а не собственная переменная, и что код не завершился исключением до цикла.

Когда кнопка добавлена в типовую конфигурацию , обновление может затереть вашу правку. Чтобы этого избежать, делайте доработку расширением конфигурации: оно хранится отдельно, а штатная форма остаётся нетронутой. Расширения доступны с платформы 8.3.6. В расширении создайте объект, заимствующий форму, добавьте команду и кнопку в нём, а при загрузке .cfe обновите конфигурацию базы данных отдельным шагом.

Частые вопросы

Можно ли добавить кнопку заполнения без программирования?
Саму кнопку и команду создать можно без кода, но без обработчика она ничего не сделает. Для простых случаев используйте штатные механизмы: ввод на основании или заполнение по умолчанию в свойствах реквизита.
Где хранится код кнопки?
В модуле формы, на вкладке Модуль редактора формы. Процедуры команд лежат в одном модуле с другими обработчиками формы.
Чем отличается кнопка от команды?
Команда описывает действие и обработчик. Кнопка только отображает команду на форме. Одну команду можно показать несколькими кнопками.
Нужно ли записывать документ после заполнения?
Нет, заполнение меняет данные только в форме. Документ сохранится, когда пользователь нажмёт запись или проведение.
Будет ли кнопка работать в тонком и веб-клиенте?
Да, управляемые формы работают в обоих клиентах. Ограничения касаются только отдельных методов, например работы с файлами на компьютере.