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

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

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

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

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

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

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

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

Важно понимать, что на клиенте форма хранит копию данных, а не сами данные информационной базы. Реквизит формы типа «ДанныеФормыСтруктура» или «ДанныеФормыКоллекция» — это представление данных объекта, адаптированное для передачи между клиентом и сервером. Поэтому часть операций (запросы к базе, методы объектов, изменение составных типов) на клиенте недоступна в принципе.

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

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

&НаКлиенте

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

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

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

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

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

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

Оба варианта работают одинаково, но краткая форма читается легче. Запись через ЭтаФорма полезна, когда имя реквизита совпадает с именем локальной переменной или параметра процедуры — тогда явное указание контекста снимает неоднозначность. Если реквизит не существует, платформа выдаст ошибку «Поле объекта не обнаружено» в момент выполнения, а не при сохранении модуля, поэтому имена стоит проверять по дереву реквизитов в конфигураторе.

Обращение по строковому имени возможно через квадратные скобки: ЭтаФорма["СуммаДокумента"]. Это удобно, когда имя реквизита формируется динамически, например при обходе группы однотипных реквизитов Показатель1, Показатель2 и так далее.

bsl
&НаКлиенте
Процедура ЗаполнитьПоказатели()
    Для Номер = 1 По 5 Цикл
        ЭтаФорма["Показатель" + Номер] = 0;
    КонецЦикла;
КонецПроцедуры

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

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

&НаКлиенте

Процедура ПриИзмененииКонтрагента(Элемент)

Если ЗначениеЗаполнено(Объект.Контрагент) Тогда

Объект.Комментарий = "Проверен: " + Строка(Объект.Контрагент);

КонецЕсли;

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

Ограничение клиентского контекста проявляется при работе со значениями составных типов. Например, если реквизит объекта имеет составной тип и на клиенте требуется присвоить ему значение, полученное через механизмы, доступные только на сервере, платформа выдаст ошибку о недопустимом типе. В таких случаях присвоение выносят в серверную процедуру, а клиентская часть только инициирует вызов и передаёт параметры.

Работа с табличными частями на клиенте

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

&НаКлиенте

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

Итог = 0;

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

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

Итог = Итог + Строка.Сумма;

КонецЦикла;

СуммаДокумента = Итог; // реквизит формы

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

Текущую строку таблицы на форме получают через элемент формы: Элементы.Товары.ТекущиеДанные. Это удобно в обработчиках событий таблицы — ПриИзменении, ПередУдалением. Обратите внимание: ТекущиеДанные может быть Неопределено, если таблица пуста или строка не выбрана, поэтому перед обращением к реквизитам строки стоит делать проверку.

Типовая последовательность обращения к данным строки
  1. 1
    Получите текущие данные: СтрокаТаблицы = Элементы.Товары.ТекущиеДанные
  2. 2
    Проверьте, что СтрокаТаблицы <> Неопределено
  3. 3
    Обратитесь к реквизиту строки: СтрокаТаблицы.Цена
  4. 4
    При необходимости запишите результат в реквизит формы или объекта

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

Иногда обратиться к реквизиту формы нужно не из её модуля, а из другой формы или общего модуля — например, после открытия формы через ОткрытьФорму() или при получении формы через ПолучитьФорму(). В этом случае переменная типа УправляемаяФорма даёт доступ к реквизитам точечной записью.

&НаКлиенте

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

ФормаОтбора = ПолучитьФорму("Обработка.Подбор.Форма.ФормаПодбора");

ФормаОтбора.СкладОтбора = СкладПоУмолчанию; // реквизит чужой формы

ФормаОтбора.Открыть();

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

Здесь действует важное ограничение: доступны только реквизиты верхнего уровня, объявленные в дереве реквизитов той формы. Обратиться к локальным переменным модуля чужой формы нельзя. Если требуется передать данные в открываемую форму, предпочтительнее использовать параметры формы — ПараметрыФормы = Новый Структура("Склад", СкладПоУмолчанию) и обработку их в обработчике ПриСозданииНаСервере целевой формы. Это надёжнее, потому что параметры применяются до отображения формы.

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

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

Подходит для начального заполнения при открытии; обрабатываются в ПриСозданииНаСервере, недоступны для изменения после открытия.

Прямая запись в реквизит формы

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

Оповещение через Оповестить()

Подходит для передачи данных в уже открытые формы; требует обработчика ОбработкаОповещения в целевой форме.

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

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

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

Типичные ошибки
01
Обращение к реквизиту объекта как к реквизиту формы: пишут СуммаДокумента вместо Объект.СуммаДокумента — получают ошибку или читают пустой реквизит формы с таким же именем
02
Чтение Элементы.Товары.ТекущиеДанные без проверки на Неопределено — падение при пустой таблице
03
Попытка записать объект на клиенте — операция доступна только на сервере
04
Опечатка в строковом обращении ЭтаФорма["Имя"] — ошибка возникает только в момент выполнения и не ловится при проверке модуля

Проверка результата и отладка

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

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

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

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

Значение реквизита после присвоения
Норма

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

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

Значение пустое или ошибка «Поле объекта не обнаружено»

Связь реквизита с элементом формы
Норма

Изменение реквизита в коде сразу отображается в поле ввода

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

Код меняет значение, но на форме ничего не происходит — элемент не связан с реквизитом

Контекст выполнения
Норма

Клиентская процедура не содержит запросов и методов объекта

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

Ошибка о недопустимости операции на клиенте

FAQ

Чем отличается обращение ЭтаФорма.Реквизит от просто Реквизит в модуле формы?

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

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

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

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

Используйте квадратные скобки: ЭтаФорма["ИмяРеквизита"]. Строку можно собирать динамически, например "Поле" + Номер. Учтите, что опечатка в таком имени обнаружится только при выполнении, поэтому полезна проверка через Попытка...Исключение.

Можно ли из одной формы изменить реквизит другой уже открытой формы?

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

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

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

Как получить текущую строку табличной части в клиентской процедуре?

Через элемент формы, связанный с таблицей: Элементы.Товары.ТекущиеДанные. Перед обращением к реквизитам строки обязательно проверьте, что результат не равен Неопределено — иначе при пустой таблице код завершится ошибкой.

Итог

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

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