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