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

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

1С: как программно заполнить реквизит формы

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

Программное заполнение реквизита формы — одна из базовых задач при доработке конфигураций 1С:Предприятие 8.3. Типичные сценарии: подстановка значения по умолчанию при создании документа, заполнение поля по данным другого реквизита, установка отбора или параметра при открытии формы. В зависимости от того, где находится реквизит — в объекте (документе, справочнике) или непосредственно на форме — используются разные подходы.

Главная сложность для начинающих разработчиков — различие между реквизитом объекта и реквизитом формы, а также между управляемыми и обычными формами. В управляемой форме нельзя напрямую писать Документ.Номенклатура = Значение, как это делалось в обычных формах: нужно либо работать через Объект, либо обращаться к реквизиту формы через ЭтаФорма или коллекцию элементов.

Ниже разобраны рабочие способы для обоих типов форм, обработчики событий, в которых заполнение выполняется корректно, и типичные ошибки, из-за которых значение «не сохраняется» или форма падает с ошибкой.

Различие между реквизитом объекта и реквизитом формы

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

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

Частая ошибка — попытка заполнить реквизит объекта через элемент формы (поле ввода): Элементы.Контрагент.ТекстРедактирования = "...". Так делать не нужно: элемент формы — это только визуальное отображение. Заполнять следует данные, а элемент обновится автоматически.

Заполнение реквизита объекта в управляемой форме

Самый распространённый случай — присвоить значение полю документа или справочника. В модуле управляемой формы это делается прямым присваиванием через Объект:

&НаКлиенте

Процедура ЗаполнитьСклад(Команда)

Объект.Склад = ПредопределенноеЗначение("Справочник.Склады.Основной");

Модифицированность = Истина;

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

Если значение нужно получить с сервера (запросом к базе), присваивание выполняется в серверной процедуре. Клиентский код вызывает серверную, та меняет Объект, и форма автоматически отображает новое значение — отдельно «обновлять» поля не требуется.

&НаСервере

Процедура ЗаполнитьПоУмолчаниюНаСервере()

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

Объект.Валюта = Константы.ОсновнаяВалюта.Получить();

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

Обратите внимание: присваивать нужно значение правильного типа. Если реквизит имеет тип «СправочникСсылка.Контрагенты», нельзя присвоить строку с наименованием — сначала нужно найти ссылку через Справочники.Контрагенты.НайтиПоНаименованию(...) или получить её иным способом. Присвоение значения несовместимого типа вызовет ошибку либо молча очистит поле.

Заполнение реквизита самой формы

Дополнительные реквизиты формы, созданные в редакторе (панель «Реквизиты формы»), доступны в модуле формы напрямую по имени или через ЭтаФорма:

&НаКлиенте

Процедура УстановитьПериод(Команда)

ЭтаФорма.ДатаНачала = НачалоМесяца(ТекущаяДата());

ЭтаФорма.ДатаОкончания = КонецМесяца(ТекущаяДата());

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

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

&НаСервере

Процедура ЗаполнитьТаблицуНаСервере()

ТаблицаТоваров.Очистить();

Для Каждого Строка Из Объект.Товары Цикл

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

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

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

КонецЦикла;

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

Для динамического списка значения «заполняются» не присваиванием, а установкой параметров и отбора — через Список.Параметры.УстановитьЗначениеПараметра(...) или ЭлементыОтбора. Это отдельный механизм, и попытка присвоить списку значение напрямую — типичная ошибка новичков.

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

Место, где вы заполняете реквизит, не менее важно, чем сам код. Для заполнения при создании нового объекта правильное место — переопределение события ОбработкаЗаполнения в модуле объекта, а не код формы. Тогда значения подставятся при любом способе создания: из формы списка, копированием, программно.

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

&НаСервере

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

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

Объект.Ответственный = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;

КонецЕсли;

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

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

Порядок действий при заполнении реквизита
  1. 1
    Определите, где хранится значение: реквизит объекта или реквизит формы
  2. 2
    Выберите правильный обработчик: ПриСозданииНаСервере, ПриИзменении или команда
  3. 3
    Присвойте значение корректного типа через Объект.Имя или ЭтаФорма.Имя
  4. 4
    Если значение получается запросом — выполните заполнение на сервере
  5. 5
    Проверьте, что поле на форме отобразило значение и документ записывается без ошибок

Заполнение в обычных формах

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

Процедура ПриОткрытии()

Если ЭтоНовый() Тогда

Склад = Справочники.Склады.НайтиПоКоду("000000001");

КонецЕсли;

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

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

При переносе кода из обычных форм в управляемые учитывайте: прямое обращение к реквизитам объекта без Объект. в управляемой форме работать не будет — компилятор выдаст ошибку «Переменная не определена».

Типичные ошибки и как их избежать

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

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

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

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

Проверка результата и безопасная отладка

После внедрения кода проверьте три вещи: значение отображается в поле формы, объект записывается без ошибок, и при повторном открытии записанного документа значение на месте. Для отладки используйте конфигуратор: точку останова в обработчике и просмотр значения Объект.ИмяРеквизита в табло.

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

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

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

Отображение значения
Норма

Поле на форме показывает заполненное значение сразу после действия

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

Поле пустое или показывает старое значение — проверьте имя реквизита и контекст (клиент/сервер)

Запись объекта
Норма

Документ записывается, значение сохраняется в базе

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

Ошибка записи или значение пропадает после записи — проверьте тип присваиваемого значения

Повторное открытие
Норма

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

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

Значение перезаписывается — добавьте проверку Параметры.Ключ.Пустая()

FAQ

Как заполнить реквизит формы значением из параметра при открытии?

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

Почему поле на форме заполнено, но после записи значение пустое?

Скорее всего, вы заполнили элемент формы или реквизит формы, а не реквизит объекта. В базу сохраняются только реквизиты объекта. Проверьте, что присваивание идёт через Объект.ИмяРеквизита, и что сам реквизит существует в метаданных документа или справочника.

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

Нет, реквизиты формы существуют только в контексте открытой формы. Если нужно заполнить данные объекта программно без формы, работайте с объектом напрямую: Справочники.Имя.СоздатьЭлемент() или Документы.Имя.СоздатьДокумент(), заполните реквизиты и вызовите Записать().

Как программно заполнить табличную часть документа из формы?

Обратитесь к табличной части через Объект.ИмяТабличнойЧасти: используйте Очистить() при необходимости, затем Добавить() для каждой строки и присвойте значения колонкам. После заполнения установите Модифицированность = Истина, чтобы платформа предложила сохранить изменения.

В чём разница между ЭтаФорма.Реквизит и просто Реквизит в модуле формы?

В модуле управляемой формы оба варианта обычно равнозначны для реквизитов формы: платформа ищет имя среди реквизитов автоматически. Явное обращение через ЭтаФорма повышает читаемость и помогает отличать реквизиты формы от локальных переменных процедуры.

Итог

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

Реквизит объекта заполняйте через Объект.Имя, реквизит формы — через ЭтаФорма.Имя, всегда присваивая значение корректного типа. Заполнение при создании выполняйте в ПриСозданииНаСервере с проверкой нового объекта, связанные поля — в ПриИзменении. Не забывайте про Модифицированность = Истина и тестируйте доработки на копии базы.