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