Разработка и Конфигурация · 11 мин
1С: как заполнить реквизит формы при открытии
Как заполнить реквизит формы при открытии в 1С 8.3: обработчики ПриСозданииНаСервере и ПриОткрытии, параметры формы, примеры кода и типичные ошибки.
Заполнение реквизита формы при открытии — стандартная задача при разработке и доработке конфигураций 1С:Предприятие 8.3. Например, требуется подставить текущего пользователя, дату, организацию по умолчанию или значение, переданное из другой формы. Для этого используются два основных обработчика событий управляемой формы: ПриСозданииНаСервере и ПриОткрытии.
Выбор обработчика принципиален. ПриСозданииНаСервере выполняется на сервере до того, как форма показана пользователю, и имеет доступ к данным информационной базы без дополнительных серверных вызовов. ПриОткрытии выполняется на клиенте уже после отображения формы и подходит для действий, связанных с интерфейсом: установки фокуса, предупреждений, работы с оборудованием.
Ниже разобраны оба способа, передача значений через параметры формы, заполнение реквизитов объекта и типовые ошибки, из-за которых значение «сбрасывается» или форма падает с ошибкой.
Где именно заполнять реквизит: выбор обработчика
У управляемой формы есть несколько событий жизненного цикла, но для начального заполнения используются два. ПриСозданииНаСервере вызывается один раз при создании формы, до её отображения. Внутри него доступен контекст сервера: можно выполнять запросы, вызывать функции общих модулей, читать константы и регистры сведений без лишних обращений к серверу.
ПриОткрытии срабатывает на клиенте, когда форма уже сформирована и показана. Здесь нельзя напрямую обращаться к базе данных — любой запрос потребует серверного вызова, что замедляет открытие. Этот обработчик оправдан, когда значение зависит от клиентского окружения: настроек на компьютере пользователя, подключённого оборудования, выбора из диалога.
Если реквизит нужно заполнить значением из базы (склад по умолчанию, курс валюты, настройка пользователя) — правильный выбор ПриСозданииНаСервере. Если значение определяется интерактивно или зависит от клиента — ПриОткрытии либо клиентская процедура с последующим серверным вызовом.
Как выбрать обработчик
Заполнение реквизита формы в ПриСозданииНаСервере
Сначала добавьте реквизит формы: откройте форму в конфигураторе, перейдите на закладку «Реквизиты» и создайте реквизит нужного типа, например ТекущийСклад с типом «СправочникСсылка.Склады». Затем перетащите его на дерево элементов формы, чтобы он отображался пользователю.
Далее в модуле формы создайте обработчик события. Проще всего это сделать через палитру свойств формы: найдите событие «ПриСозданииНаСервере» и нажмите кнопку открытия — платформа сгенерирует шаблон процедуры.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Заполняем реквизит формы значением из настроек пользователя
ТекущийСклад = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(
"НастройкиСклада", "ОсновнойСклад");
Если Не ЗначениеЗаполнено(ТекущийСклад) Тогда
ТекущийСклад = Справочники.Склады.НайтиПоНаименованию("Основной");
КонецЕсли;
КонецПроцедуры
Обратите внимание: реквизит формы доступен в обработчике напрямую по имени. Если реквизит не создан в дереве реквизитов формы, обращение к нему вызовет ошибку «Поле объекта не обнаружено». Также проверяйте заполненность значения, полученного из настроек, — при первом запуске настройки могут быть пустыми.
Заполнение реквизита объекта (документа или справочника)
Когда открывается форма нового документа, значения по умолчанию правильно задавать не в форме, а в модуле объекта — в процедуре ОбработкаЗаполнения. Тогда заполнение сработает при любом способе создания: из формы списка, копированием, программно, при вводе на основании.
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Ответственный = Пользователи.ТекущийПользователь();
Дата = ТекущаяДатаСеанса();
КонецПроцедуры
Если же заполнение требуется именно в форме (например, логика специфична для конкретной формы и не должна работать при программном создании), используйте ПриСозданииНаСервере с проверкой, что объект новый:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Объект.Ссылка.Пустая() Тогда
Объект.Организация = Справочники.Организации.ОрганизацияПоУмолчанию();
КонецЕсли;
КонецПроцедуры
Проверка на пустую ссылку обязательна: без неё при открытии существующего документа вы перезапишете сохранённое значение, и пользователь потеряет данные после записи.
Передача значения через параметры формы
Часто заполнить реквизит нужно значением, которое известно вызывающей стороне: например, из формы списка открывается форма с отбором по контрагенту. Для этого используется коллекция Параметры, доступная в ПриСозданииНаСервере.
// Код, открывающий форму:
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Контрагент", ТекущийКонтрагент);
ОткрытьФорму("Обработка.ПечатьДоговора.Форма.ФормаОбработки", ПараметрыФормы);
// В модуле открываемой формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("Контрагент") Тогда
Контрагент = Параметры.Контрагент;
КонецЕсли;
КонецПроцедуры
Проверка Параметры.Свойство("Контрагент") обязательна: форму могут открыть и без параметров, тогда обращение к несуществующему свойству вызовет ошибку. Альтернатива — объявить параметр формы в конфигураторе (закладка «Параметры» формы) и пометить его как ключевой, если от него зависит уникальность открываемой формы.
Через параметры можно передавать примитивные типы, ссылки, структуры и массивы. Передавать объекты типа ДокументОбъект или наборы записей нельзя — передавайте ссылку и читайте данные внутри формы.
- 1В вызывающем коде сформируйте структуру с нужными значениями и передайте её в ОткрытьФорму
- 2В модуле открываемой формы создайте обработчик ПриСозданииНаСервере
- 3Проверьте наличие параметра через Параметры.Свойство()
- 4Присвойте значение реквизиту формы или реквизиту объекта
- 5Откройте форму и убедитесь, что поле заполнено и форма не выдаёт ошибок
Заполнение в ПриОткрытии и работа с клиентским контекстом
Обработчик ПриОткрытии выполняется на клиенте после отображения формы. Он подходит, когда нужно установить курсор в конкретное поле, показать предупреждение, начать опрос подключённого оборудования или запустить обработчик ожидания.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ЭтаФорма.ТекущийЭлемент = Элементы.Комментарий;
Если Не ЗначениеЗаполнено(Объект.Организация) Тогда
ПоказатьПредупреждение(, "Организация не заполнена. Проверьте настройки.");
КонецЕсли;
КонецПроцедуры
Если в ПриОткрытии всё же нужны данные из базы, делайте один серверный вызов и заполняйте сразу все нужные реквизиты — множество мелких серверных вызовов заметно замедляют открытие формы, особенно при работе через веб-клиент или медленное соединение.
Частая причина «тормозов» при открытии формы — тяжёлые запросы в ПриОткрытии, выполняемые по одному на каждый реквизит. Перенесите всю серверную логику в ПриСозданииНаСервере или объедините в один серверный вызов: форма откроется заметно быстрее.
Проверка результата и типичные ошибки
После внесения изменений обновите конфигурацию базы данных (F7) и откройте форму в режиме предприятия. Проверьте три сценария: открытие нового объекта, открытие существующего объекта и открытие формы без параметров. Во всех трёх случаях форма должна открываться без ошибок, а сохранённые ранее данные — не изменяться.
Если значение «не подставляется», сначала убедитесь, что реквизит существует именно как реквизит формы (или объекта), а не только как элемент на форме. Элемент формы без связанного реквизита не хранит значение. Затем проверьте в отладчике, что обработчик вообще выполняется и ветка условия не пропускается.
Как проверить результат
Реквизиты заполнены значениями по умолчанию, ошибок нет
Поля пустые или появляется сообщение об ошибке
Сохранённые значения на месте и не изменились
Значения заменены значениями по умолчанию
Форма открывается, реквизиты остаются пустыми или заполняются по умолчанию
Ошибка обращения к несуществующему параметру
FAQ: частые вопросы
Чем реквизит формы отличается от реквизита объекта?
Реквизит формы живёт только внутри формы и не сохраняется в базу данных — он нужен для промежуточных вычислений и элементов интерфейса. Реквизит объекта (документа, справочника) хранится в базе и записывается вместе с объектом. Если значение должно попасть в учётные данные, заполняйте реквизит объекта.
Как заполнить реквизит при копировании документа?
При копировании в ПриСозданииНаСервере доступен Параметры.ЗначениеКопирования — ссылка на исходный объект. Проверив её заполненность, можно скорректировать реквизиты: например, очистить номер договора или подставить текущую дату вместо скопированной.
Почему значение, установленное в ПриСозданииНаСервере, пропадает?
Наиболее вероятные причины: значение присваивается локальной переменной, а не реквизиту формы; реквизит перезаписывается в другом обработчике (например, ПриЧтенииНаСервере); либо элемент формы связан с другим реквизитом. Пройдите отладчиком по всем серверным обработчикам формы.
Можно ли заполнить реквизит формы списка при открытии?
Да. В форме списка в ПриСозданииНаСервере обычно устанавливают отбор динамического списка через Список.Отбор или параметры компоновки данных. Например, можно отобрать документы только текущего пользователя, установив элемент отбора программно.
Как передать в форму таблицу значений?
Таблицу значений напрямую через параметры передать нельзя. Варианты: преобразовать её в массив структур и передать массив, либо поместить таблицу во временное хранилище (ПоместитьВоВременноеХранилище) и передать в форму адрес хранилища — внутри формы данные извлекаются по этому адресу.
Работает ли этот подход в обычных формах?
В обычных формах (толстый клиент) используются обработчики ПриОткрытии и ПередОткрытием, и разделения на клиент и сервер там нет — весь код выполняется в одном контексте. Принцип тот же: заполняйте реквизиты до отображения формы и проверяйте, новый ли объект.
Что важно запомнить
Заполняйте реквизиты в ПриСозданииНаСервере, если нужны данные базы, и в ПриОткрытии — если нужен клиентский контекст. Значения по умолчанию для новых объектов задавайте в ОбработкаЗаполнения модуля объекта, внешние значения передавайте через Параметры с обязательной проверкой их наличия, а перед записью существующих объектов всегда проверяйте, что данные не перезаписываются.