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

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

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

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

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

Типичные задачи, где требуется обратиться к реквизиту формы списка: хранение выбранного пользователем значения отбора, флага режима отображения, ссылки на отбор по владельцу, передача параметров между формами. Важно различать три вещи: реквизиты формы (созданные в конфигураторе), колонки динамического списка (поля запроса) и свойства объекта ЭтаФорма. Путаница между ними — главный источник ошибок «Поле объекта не обнаружено».

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

Где находятся реквизиты формы списка и как они устроены

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

Ключевое правило управляемых форм: реквизит формы — это данные, а элемент формы (поле ввода, флажок) — только их визуальное представление. Обращение к данным выполняется через реквизит, а не через элемент. Элемент нужен лишь для управления видимостью, доступностью, заголовком. Это принципиальное отличие от обычных форм, где обращение к элементу давало доступ к значению.

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

Внутри модуля формы списка реквизит доступен по имени напрямую — платформа подставляет контекст формы автоматически. Также работает явное обращение через ЭтаФорма.ИмяРеквизита. Оба варианта ниже эквивалентны:

&НаКлиенте

Процедура ПоказатьОтбор(Команда)

// Чтение реквизита формы

ТекущийКонтрагент = ОтборКонтрагент;

// Изменение реквизита формы

ЭтаФорма.ПоказыватьАрхивные = Не ПоказыватьАрхивные;

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

Если реквизит является объектом сложного типа — таблицей значений или деревом значений, — обращение идёт к его коллекции строк: ТаблицаТоваров.Добавить(), ТаблицаТоваров[0].Цена. Для реквизита-ссылки доступны свойства объекта через точку, но помните: каждое такое разыменование на тонком клиенте вызывает серверный вызов, что замедляет работу. Кэшируйте значения в локальные переменные, если обращений много.

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

Обращение к данным динамического списка: отбор и параметры

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

&НаСервере

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

// Установка параметра запроса динамического списка

Список.Параметры.УстановитьЗначениеПараметра("Организация", ТекущаяОрганизация);

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

&НаКлиенте

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

ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Проведен");

ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;

ЭлементОтбора.ПравоеЗначение = Истина;

ЭлементОтбора.Использование = Истина;

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

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

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

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

Первый — параметры при открытии. Создайте у формы списка параметры (закладка «Параметры» в редакторе формы) и передавайте значения через структуру:

ПараметрыОткрытия = Новый Структура;

ПараметрыОткрытия.Вставить("ОтборКонтрагент", КонтрагентСсылка);

ОткрытьФорму("Справочник.ДоговорыКонтрагентов.ФормаСписка", ПараметрыОткрытия);

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

Способы передать данные в форму списка

Параметры формы

Подходит для начальной настройки при открытии. Ограничение: работает только в момент открытия, изменить потом нельзя.

Структура с ключом Отбор

Платформа сама установит отбор динамического списка по полям. Ограничение: поля должны быть доступны для отбора в запросе списка.

Оповещения

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

Обычные формы: как синтаксис отличается

В обычных формах (толстый клиент, режим совместимости) обращение к реквизитам и элементам устроено иначе. Реквизит формы доступен по имени так же, но данные списка читаются через элемент формы: ЭлементыФормы.СправочникСписок.ТекущиеДанные, а отбор устанавливается через СправочникСписок.Отбор.Наименование.Установить("Значение"). Директив компиляции &НаКлиенте/&НаСервере нет — весь код выполняется на клиенте с прямым доступом к серверу.

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

Типичные ошибки
01
Обращение к элементу формы за значением: Элементы.ПолеКонтрагент — это объект поля ввода, у него нет значения данных. Читайте реквизит формы, к которому привязан элемент.
02
Попытка обратиться к реквизиту формы списка извне через ПолучитьФорму: метод возвращает форму, но обращение к её реквизитам до открытия и инициализации приводит к ошибкам и утечкам памяти. Используйте параметры открытия.
03
Установка отбора динамического списка на клиенте с вызовом серверных методов в цикле — каждый вызов идёт по сети. Собирайте настройки одним серверным вызовом.
04
Использование свойства Список.ТекущиеДанные — у динамического списка его нет, текущая строка доступна только через Элементы.Список.ТекущиеДанные.

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

Минимальная проверка выполняется в три шага. Сначала убедитесь, что реквизит существует: откройте форму в конфигураторе, найдите имя в дереве реквизитов. Затем добавьте в обработчик ПриОткрытии вывод значения через Сообщить() или запустите отладку с точкой останова. Наконец, измените значение через интерфейс (если реквизит выведен на форму) и убедитесь, что программное чтение возвращает новое значение.

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

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

Реквизит виден в дереве реквизитов формы
Норма

Имя и тип соответствуют задуманным

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

Реквизита нет или тип отличается — обращение вызовет ошибку

Чтение реквизита в отладчике
Норма

В табло ЭтаФорма.ИмяРеквизита показывает ожидаемое значение

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

Ошибка «Поле объекта не обнаружено» — проверьте имя и контекст

Отбор динамического списка
Норма

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

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

Список не меняется — проверьте Использование = Истина и доступность поля для отбора

Итог

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

В модуле формы списка реквизит доступен по имени или через ЭтаФорма.ИмяРеквизита. Данные списка — через реквизит Список (отбор, параметры), текущая строка — через Элементы.Список.ТекущиеДанные. Извне формы данные передаются параметрами при открытии и оповещениями, а не прямым обращением к реквизитам.

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

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

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

Почему возникает ошибка «Поле объекта не обнаружено» при обращении к реквизиту?

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

Как программно узнать текущую строку списка?

Используйте Элементы.Список.ТекущаяСтрока — вернётся ссылка на объект. Для доступа ко всем полям строки, включая вычисляемые колонки запроса, применяйте Элементы.Список.ТекущиеДанные. Оба свойства доступны только на клиенте.

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

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

Как сохранить значение реквизита формы списка между сеансами?

Реквизиты формы живут только пока форма открыта. Для хранения между сеансами используйте хранилище общих настроек (ХранилищеОбщихНастроек.Сохранить), константы или регистры сведений — в зависимости от того, персональная это настройка пользователя или общие данные.

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

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