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