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