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

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

Как обратиться к реквизиту формы в 1С

Как обратиться к реквизиту формы в 1С из модуля формы, команды и другой формы: ЭтаФорма, Элементы, Объект, типовые ошибки и примеры кода для управляемых форм.

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

Основная ошибка новичков — путать реквизит формы, реквизит объекта и элемент формы. Реквизит формы хранит значение, элемент формы лишь отображает его на экране, а реквизит объекта (справочника, документа) доступен через свойство Объект. Понимание этой тройки снимает большинство вопросов вида «почему поле не находится».

Ниже разобраны рабочие способы обращения к реквизитам формы в управляемом приложении, показаны примеры кода, типичные ошибки и способы проверки результата.

Чем реквизит формы отличается от элемента формы и реквизита объекта

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

Реквизит формы — переменная формы, созданная разработчиком в дереве реквизитов. Она живёт, пока открыта форма. Реквизит объекта — поле прикладного объекта (документа, справочника), доступное через свойство Объект, если объект является основным реквизитом формы. Элемент формы — визуальный контрол (поле ввода, надпись, таблица), связанный с реквизитом через свойство ПутьКДанным.

Три вида данных на форме

Реквизит формы

Обращение: ЭтаФорма.ИмяРеквизита или просто ИмяРеквизита. Хранится только в форме, в базу не пишется.

Реквизит объекта

Обращение: Объект.ИмяРеквизита. Сохраняется в базе при записи объекта.

Элемент формы

Обращение: Элементы.ИмяЭлемента. Управляет отображением: видимость, доступность, заголовок.

Практическое следствие: чтобы изменить значение, меняют реквизит, а не элемент. Чтобы скрыть поле или поменять его заголовок, обращаются к элементу.

Обращение к реквизиту из модуля своей формы

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

&НаКлиенте

Процедура РассчитатьСумму(Команда)

// Прямое обращение по имени реквизита

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

// Эквивалент через ЭтаФорма

ЭтаФорма.СуммаДокумента = ЭтаФорма.Количество * ЭтаФорма.Цена;

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

Оба варианта равнозначны. Явное указание ЭтаФорма полезно, когда имя реквизита совпадает с именем локальной переменной или когда код читают разработчики с разным опытом — явность снижает риск ошибки.

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

&НаСервере

Процедура ДобавитьСтрокуНаСервере()

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

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

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

Обращение к реквизиту основного объекта через Объект

Когда форма принадлежит документу или справочнику, её основной реквизит доступен через свойство Объект. Через него читают и меняют реквизиты самого прикладного объекта, которые потом будут записаны в базу.

&НаКлиенте

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

Если Не ЗначениеЗаполнено(Объект.Ответственный) Тогда

Сообщить("Не заполнен ответственный");

КонецЕсли;

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

Важный нюанс клиент-серверного разделения: на клиенте Объект имеет тип ДанныеФормыСтруктура, и часть серверных методов объекта там недоступна. Для серверной логики (запросы, обращения к менеджерам объектов) объект преобразуют:

&НаСервере

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

ДокументОбъект = РеквизитФормыВЗначение("Объект");

ДокументОбъект.Заполнить(Неопределено);

ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");

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

Обращение к элементам формы и программное создание реквизитов

Иногда нужно не значение реквизита, а его визуальное представление: скрыть поле, сделать недоступным, поменять заголовок. Для этого обращаются к коллекции Элементы:

&НаКлиенте

Процедура УправлениеВидимостью()

Элементы.ПолеСкидка.Видимость = (СуммаДокумента > 100000);

Элементы.ПолеСкидка.Заголовок = "Скидка, %";

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

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

&НаСервере

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

Добавляемые = Новый Массив;

Добавляемые.Добавить(Новый РеквизитФормы("ДинамическийПризнак",

Новый ОписаниеТипов("Булево"), "", "Признак"));

ИзменитьРеквизиты(Добавляемые);

ЭтаФорма.ДинамическийПризнак = Истина;

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

Обращение к реквизиту другой формы

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

Правильные способы обмена данными между формами:

  • Передача параметров при открытии через структуру параметров и обработка их в ПриСозданииНаСервере;
  • Оповещения — Оповестить() в одной форме и ОбработкаОповещения() в другой;
  • ОписаниеОповещения при открытии формы в модальном или асинхронном режиме;
  • Через владельца формы — свойство ВладелецФормы, если форма открыта из другой формы.
&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ВыбранТовар" Тогда

ТекущийТовар = Параметр.Номенклатура;

КонецЕсли;

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

Маршрут решения

Как выбрать способ передачи данных

Нужно передать данные при открытии формыИспользуйте структуру параметров в ОткрытьФорму и читайте её в ПриСозданииНаСервере
Форма уже открыта и должна узнать о событииИспользуйте Оповестить и ОбработкаОповещения
Нужен результат после закрытия формы выбораОткрывайте форму с ОписаниеОповещения и обрабатывайте результат в callback

Контекст выполнения: клиент, сервер и директивы компиляции

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

Директива &НаСервереБезКонтекста означает, что процедура не имеет доступа к данным формы, включая реквизиты. Такие процедуры используют для вспомогательных функций, которым данные передают параметрами:

&НаСервереБезКонтекста

Функция ПолучитьЦену(Номенклатура)

// Объект и реквизиты формы здесь НЕ доступны

Возврат РегистрыСведений.Цены.ПолучитьПоследнее(ТекущаяДатаСеанса(),

Новый Структура("Номенклатура", Номенклатура)).Цена;

КонецФункции

Типичные ошибки
01
Обращение к реквизиту формы из процедуры &НаСервереБезКонтекста — ошибка компиляции или выполнения, данные формы там недоступны
02
Попытка изменить значение через элемент формы (Элементы.Поле.Значение) — значение хранится в реквизите, элемент только отображает
03
Вызов РеквизитФормыВЗначение на клиенте — метод работает только на сервере
04
Обращение к реквизиту ещё не созданной формы из другой формы — обращение к закрытой форме приводит к ошибке
05
Опечатка в имени реквизита при строковом обращении — проверяйте имена в дереве реквизитов формы в конфигураторе

Как проверить, что обращение работает

После написания кода проверьте результат до передачи изменений в рабочую базу. Базовая проверка занимает несколько минут и отлавливает большинство ошибок.

  1. Откройте модуль формы в конфигураторе и выполните проверку синтаксиса модуля (кнопка с галочкой) — она отловит обращения к несуществующим реквизитам при явном синтаксисе.
  2. Запустите базу в режиме отладки, поставьте точку останова в обработчике и посмотрите значение реквизита через табло (Shift+F9).
  3. Проверьте поведение в обоих контекстах, если процедура вызывается и с клиента, и с сервера.
  4. Убедитесь, что элемент формы связан с реквизитом: свойство ПутьКДанным элемента должно указывать на имя реквизита, иначе изменение реквизита не отобразится на экране.
Контрольные точки

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

Значение на экране
Норма

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

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

Значение в отладчике изменилось, а на форме старое — элемент не связан с реквизитом

Синтаксис модуля
Норма

Проверка модуля проходит без ошибок

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

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

Серверный вызов
Норма

Процедура &НаСервере видит реквизиты формы

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

Ошибка доступа — процедура объявлена БезКонтекста

Итог

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

Реквизит формы доступен по имени или через ЭтаФорма, данные объекта — через Объект, визуальные контролы — через Элементы. Серверные преобразования делаются через РеквизитФормыВЗначение только на сервере, а между формами данные передают параметрами и оповещениями, а не прямым обращением.

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

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

Через квадратные скобки: ЭтаФорма["ИмяРеквизита"]. Такой способ удобен, когда имя реквизита формируется динамически, например в цикле по однотипным полям. Учтите, что опечатка в строке обнаружится только в момент выполнения.

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

Реквизит и элемент формы — разные сущности. Проверьте, что на форме создан элемент (поле ввода) и в его свойстве ПутьКДанным указано имя вашего реквизита. Без привязки элемента значение существует в памяти, но пользователю не показывается.

Можно ли обратиться к реквизиту формы из общего модуля?

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

Чем отличается ЭтаФорма от ЭтотОбъект в модуле формы?

В модуле управляемой формы используется ЭтаФорма — это объект типа УправляемаяФорма с доступом к реквизитам, элементам и командам. ЭтотОбъект в модуле формы объекта (внешней обработки) ссылается на сам объект обработки, а не на форму, и реквизитов формы через него не видно.

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

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

Почему после ИзменитьРеквизиты пропали значения реквизитов формы?

Вызов ИзменитьРеквизиты перестраивает дерево реквизитов и может сбросить текущие значения изменённых реквизитов. Если нужно сохранить данные, запомните их в переменные до вызова метода и восстановите после. По возможности выполняйте изменение структуры один раз — в ПриСозданииНаСервере.