К статье
Практический материал

Разработка и Конфигурация · 11 мин

1С: управляемая форма — как заполнить форму документа

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

Заполнение формы документа в управляемом приложении 1С — одна из базовых задач разработчика и внедренца. Управляемая форма строится на разделении клиента и сервера, поэтому подходы, привычные по обычным формам, здесь работают иначе: данные готовятся на сервере, а на клиенте только отображаются и обрабатываются интерактивные действия пользователя.

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

Материал ориентирован на платформу 1С:Предприятие 8.3 с управляемыми формами. Примеры кода приведены для типовых конструкций и подходят для большинства конфигураций, однако имена реквизитов и параметров в вашей конфигурации могут отличаться.

Как устроена управляемая форма документа

Управляемая форма документа содержит реквизит объекта, обычно называемый Объект типа «ДанныеФормыСтруктура». Все поля ввода на форме связаны с реквизитами этого объекта, поэтому заполнить форму — значит заполнить данные объекта, а не элементы формы напрямую. Это принципиальное отличие от обычных форм, где можно было обращаться к элементам управления.

Код формы разделён на клиентскую и серверную части с помощью директив компиляции: &НаКлиенте, &НаСервере, &НаСервереБезКонтекста. Работа с данными объекта (запросы, обращение к справочникам, вычисления) выполняется на сервере. На клиенте доступен только ограниченный набор операций: работа с текущими данными формы, диалоги, навигация.

Ключевые события жизненного цикла формы документа: ПриСозданииНаСервере — форма создаётся, данные объекта загружены; ПриОткрытии — форма отображается пользователю; ПередЗаписью и ПриЗаписи — сохранение документа. Понимание последовательности этих событий определяет, где именно размещать код заполнения.

Заполнение реквизитов при создании нового документа

Стандартное место для заполнения нового документа — событие ПриСозданииНаСервере. Здесь данные объекта уже доступны, форма ещё не показана пользователю, и можно безопасно установить значения по умолчанию: организацию, склад, ответственного, валюту, дату.

Перед заполнением следует проверить, что документ действительно новый, иначе код перезапишет данные существующего документа при каждом открытии. Проверка выполняется через свойство Параметры.Ключ: если ключ пустой, документ создаётся.

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Если Параметры.Ключ.Пустая() Тогда

Объект.Организация = Справочники.Организации.ОрганизацияПоУмолчанию();

Объект.Ответственный = Пользователи.ТекущийПользователь();

Объект.Дата = ТекущаяДатаСеанса();

КонецЕсли;

КонецПроцедуры

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

Порядок действий
  1. 1
    Откройте модуль формы документа в конфигураторе
  2. 2
    Добавьте обработчик ПриСозданииНаСервере
  3. 3
    Проверьте Параметры.Ключ.Пустая() для признака нового документа
  4. 4
    Заполните реквизиты через Объект.<ИмяРеквизита>
  5. 5
    Запустите режим предприятия и создайте новый документ для проверки

Заполнение при вводе на основании

Ввод на основании — типовой механизм, при котором новый документ создаётся из другого объекта, например «Реализация товаров» из «Заказа клиента». В управляемом приложении ссылка на основание передаётся в форму через параметр Основание, а само заполнение правильнее выполнять в обработчике ОбработкаЗаполнения в модуле объекта документа, а не в форме.

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

// Модуль объекта документа

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)

Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказКлиента") Тогда

Организация = ДанныеЗаполнения.Организация;

Контрагент = ДанныеЗаполнения.Контрагент;

Для Каждого СтрокаТовара Из ДанныеЗаполнения.Товары Цикл

НоваяСтрока = Товары.Добавить();

ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТовара);

КонецЦикла;

КонецЕсли;

КонецПроцедуры

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

Программное создание и заполнение документа из кода

Когда документ нужно создать без участия пользователя — из обработки, регламентного задания или обмена — форма вообще не используется. Работа ведётся напрямую с объектом документа через менеджер документа.

НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

НовыйДокумент.Дата = ТекущаяДатаСеанса();

НовыйДокумент.Организация = ОрганизацияПоУмолчанию;

НовыйДокумент.Контрагент = ВыбранныйКонтрагент;

СтрокаТовара = НовыйДокумент.Товары.Добавить();

СтрокаТовара.Номенклатура = НоменклатураСсылка;

СтрокаТовара.Количество = 5;

СтрокаТовара.Цена = 1200;

НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);

При программном создании не выполняются клиентские обработчики формы, поэтому все обязательные реквизиты нужно заполнить явно. Если конфигурация использует механизмы типа «Значения заполнения» или подписки на события, часть реквизитов может заполниться автоматически — это зависит от конкретной конфигурации, и рассчитывать на это без проверки не стоит.

Ошибка записи при программном создании чаще всего связана с незаполненными обязательными реквизитами или нарушением правил проведения. Оборачивайте вызов Записать() в попытку с записью текста ошибки в журнал регистрации, особенно в регламентных заданиях, где исключение иначе пройдёт незамеченным.

Заполнение табличной части и работа с текущими данными

Табличная часть на управляемой форме заполняется через коллекцию Объект.<ИмяТабличнойЧасти>. На сервере доступны методы Добавить(), Загрузить(), Очистить(). Метод Загрузить() принимает таблицу значений и удобен при массовом заполнении из запроса.

На клиенте работа идёт с текущей строкой табличной части через Элементы.Товары.ТекущиеДанные. Типовой сценарий — пересчёт суммы при изменении цены или количества в обработчике ПриИзменении поля табличной части:

&НаКлиенте

Процедура ТоварыКоличествоПриИзменении(Элемент)

ТекущиеДанные = Элементы.Товары.ТекущиеДанные;

Если ТекущиеДанные = Неопределено Тогда

Возврат;

КонецЕсли;

ТекущиеДанные.Сумма = ТекущиеДанные.Количество * ТекущиеДанные.Цена;

КонецПроцедуры

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

Типичные ошибки
01
Заполнение реквизитов без проверки Параметры.Ключ.Пустая() — данные существующего документа затираются при каждом открытии
02
Размещение логики ввода на основании только в форме — программно созданные документы остаются пустыми
03
Обращение к элементам формы вместо реквизитов объекта — значения не сохраняются в базе
04
Серверный вызов на каждое изменение строки табличной части — форма начинает заметно тормозить

Проверка результата и типовые проблемы

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

Если реквизит не заполняется, проверьте по порядку: существует ли реквизит с таким именем у объекта, добавлен ли он в реквизиты формы, не перекрывает ли значение другой обработчик или подписка на событие, не выполняется ли код в неправильном контексте (например, обращение к серверным методам из клиентской процедуры).

Контрольные точки

Как проверить результат

Новый документ при открытии
Норма

Реквизиты заполнены значениями по умолчанию

Тревожный признак

Поля пустые или заполнены не теми значениями

Открытие существующего документа
Норма

Данные соответствуют сохранённым, ничего не меняется

Тревожный признак

Значения перезаписываются умолчаниями при открытии

Ввод на основании
Норма

Реквизиты и табличная часть перенесены из основания

Тревожный признак

Документ пустой или перенесена только часть данных

Запись и проведение
Норма

Документ записывается без ошибок

Тревожный признак

Сообщения о незаполненных обязательных реквизитах

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

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

Почему реквизит заполняется, но после записи документа значение пропадает?

Чаще всего значение присваивается элементу формы или временной переменной, а не реквизиту объекта. Проверьте, что присваивание идёт через Объект.<ИмяРеквизита>. Также возможно, что в обработчике ПередЗаписью или в подписке на событие значение очищается — стоит просмотреть все обработчики записи.

Где правильнее заполнять документ: в форме или в модуле объекта?

Логику, которая должна работать всегда (ввод на основании, значения по умолчанию, контроль данных), размещайте в модуле объекта — в ОбработкаЗаполнения и ПередЗаписью. В форме оставляйте только то, что связано с отображением и интерактивным поведением: видимость элементов, пересчёт при вводе, подсказки пользователю.

Как заполнить документ из внешней обработки, не открывая форму?

Используйте Документы.<Имя>.СоздатьДокумент(), заполните реквизиты и табличные части объекта, затем вызовите Записать(). Форма при этом не нужна. Если требуется показать созданный документ пользователю, откройте его форму через ОткрытьЗначение() или ОткрытьФорму с параметром Ключ.

Почему при копировании документа часть реквизитов не копируется?

При копировании платформа переносит данные объекта, но обработчик ОбработкаЗаполнения может сбрасывать отдельные реквизиты, а подписки на события — пересчитывать значения. Дополнительно в типовых конфигурациях некоторые поля (номер, дата, признаки проведения) намеренно очищаются при копировании.

Как передать произвольные значения в форму нового документа при её открытии?

Передайте значения через структуру параметров в ОткрытьФорму("Документ.<Имя>.ФормаОбъекта", ПараметрыФормы). В форме прочитайте их в ПриСозданииНаСервере через Параметры.<ИмяПараметра> и заполните реквизиты объекта. Параметры, не объявленные как ключевые, доступны только в ПриСозданииНаСервере — сохраните нужные значения в реквизиты формы.

Можно ли заполнить документ значениями по умолчанию без изменения кода формы?

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

Итог

Что важно запомнить

Заполняйте реквизиты объекта, а не элементы формы. Новые документы обрабатывайте в ПриСозданииНаСервере с проверкой пустого ключа, ввод на основании — в ОбработкаЗаполнения модуля объекта, программное создание — через СоздатьДокумент() без использования формы. Всегда проверяйте, что существующие документы не изменяются при открытии.