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

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

Как получить значение элемента формы в 1С

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

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

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

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

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

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

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

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

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

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

&НаКлиенте

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

Количество = ЭтаФорма.Количество;

Цена = ЭтаФорма.Цена;

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

Сообщить("Итого: " + Сумма);

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

Если код находится в модуле формы, имя реквизита доступно напрямую без префикса: Количество = Цена * 2;. Платформа сначала ищет имя среди реквизитов формы, затем среди её свойств и методов. Тем не менее явное обращение через ЭтаФорма делает код понятнее и защищает от неоднозначности.

Учтите контекст выполнения. В клиентских процедурах (&НаКлиенте) доступны реквизиты формы любых типов, но нельзя вызывать серверные методы объектов. В серверных процедурах (&НаСервере) обращение к реквизитам формы работает так же, однако данные передаются между клиентом и сервером — поэтому не стоит гонять на сервер вызов ради простого чтения значения поля.

Получение значения реквизита объекта (документа, справочника)

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

&НаКлиенте

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

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

НомерДокумента = Объект.Номер;

Если Не ЗначениеЗаполнено(ТекущийКонтрагент) Тогда

Сообщить("Контрагент не выбран");

КонецЕсли;

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

Табличные части объекта читаются аналогично — как коллекции строк. Например, перебор товаров документа:

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

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

КонецЦикла;

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

&НаКлиенте

Процедура ТоварыПриИзменении(Элемент)

ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;

Если ТекущаяСтрока <> Неопределено Тогда

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

КонецЕсли;

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

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

Получение самого элемента формы через коллекцию Элементы

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

&НаКлиенте

Процедура НастроитьВидимость()

ПолеСкидка = ЭтаФорма.Элементы.Скидка;

ПолеСкидка.Видимость = Истина;

ПолеСкидка.Доступность = Ложь;

ПолеСкидка.Заголовок = "Скидка, %";

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

Обращение по имени работает только если элемент с таким именем существует на форме. Иначе возникнет ошибка «Поле объекта не обнаружено». Безопасный вариант — поиск методом Найти:

ПолеСкидка = ЭтаФорма.Элементы.Найти("Скидка");

Если ПолеСкидка <> Неопределено Тогда

ПолеСкидка.Видимость = Ложь;

КонецЕсли;

У некоторых элементов есть свойства, похожие на значение, но не заменяющие реквизит. Например, у поля надписи можно прочитать Заголовок, у декорации — текст. Но у поля ввода в управляемой форме нет свойства «Текст» с редактируемым значением — данные только в реквизите.

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

Особенности обычных форм

В обычных формах (режим обычного приложения, устаревший подход) модель другая: элементы управления могут хранить значение непосредственно. Поле ввода без связи с данными имеет свойство Значение:

// Обычная форма

ЗначениеПоля = ЭлементыФормы.ПолеВвода1.Значение;

ЭлементыФормы.ПолеВвода1.Значение = "Новый текст";

Если же поле связано с данными через «Данные» или «ИсточникДанных», значение читается из связанного реквизита — как и в управляемой форме. Смешение двух подходов в одном коде — частый источник путаницы при сопровождении старых конфигураций.

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

Управляемые и обычные формы

Управляемая форма

Значение только в реквизите формы или объекта; элементы через ЭтаФорма.Элементы; контексты &НаКлиенте и &НаСервере

Обычная форма

Элемент может хранить Значение сам; элементы через ЭлементыФормы; весь код выполняется на клиенте без разделения контекстов

Получение значения из формы другого объекта

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

Для форм, открываемых методом ОткрытьФорму или ОткрытьФормуМодально, результат возвращается через обработчик оповещения:

&НаКлиенте

Процедура ВыбратьПериод(Команда)

Оповещение = Новый ОписаниеОповещения("ПослеВыбораПериода", ЭтаФорма);

ОткрытьФорму("Обработка.Настройки.Форма.ВыборПериода", , ЭтаФорма, , , , Оповещение);

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

&НаКлиенте

Процедура ПослеВыбораПериода(Результат, ДопПараметры) Экспорт

Если Результат <> Неопределено Тогда

ЭтаФорма.НачалоПериода = Результат.ДатаНачала;

КонецЕсли;

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

В открываемой форме результат передаётся методом Закрыть(ЗначениеРезультата). Прямое обращение к реквизитам чужой формы технически возможно, если у вас есть ссылка на объект формы, но это хрупкое решение: любое переименование реквизита в чужой форме сломает ваш код.

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

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

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

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

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

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

Содержит введённые пользователем данные нужного типа

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

Неопределено, пустая строка или значение другого типа — проверьте ПутьКДанным элемента

Обращение к Элементы.Имя
Норма

Возвращается объект элемента формы

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

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

ТекущиеДанные таблицы
Норма

Строка с заполненными полями

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

Неопределено — таблица пуста или нет активной строки

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

Итог

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

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

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

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

Имя, указанное в коде, не совпадает с именем элемента или реквизита на форме. Проверьте точное имя в конфигураторе (учитывается регистр букв в некоторых случаях и кириллица/латиница — частая ловушка с буквами «а» и «с»). Либо используйте Элементы.Найти("Имя") с проверкой на Неопределено.

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

В управляемой форме поле ввода без заполненного свойства ПутьКДанным работать с данными не будет — добавьте реквизит формы и свяжите элемент с ним. В обычной форме такое поле хранит значение в собственном свойстве Значение.

Можно ли получить значение элемента формы из внешней обработки?

Если внешняя обработка открыла форму и сохранила на неё ссылку, технически можно обратиться к её реквизитам через объект формы. Но надёжнее передавать данные через параметры открытия и возвращать результат через Закрыть(Результат) с описанием оповещения.

Как прочитать значение ячейки табличного поля, а не всей строки?

Получите текущую строку через Элементы.ИмяТаблицы.ТекущиеДанные, затем обратитесь к нужной колонке по имени: ТекущиеДанные.Цена. Если нужна не текущая, а конкретная строка, найдите её в коллекции Объект.ИмяТабличнойЧасти по индексу или методом Найти.

Чем отличается ЭтаФорма.Имя от Элементы.Имя?

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

Как получить значение поля на сервере, если оно введено на клиенте?

Реквизиты формы автоматически синхронизируются между клиентом и сервером при вызове серверной процедуры. Просто вызовите процедуру &НаСервере из клиентской — внутри неё ЭтаФорма.ИмяРеквизита уже содержит актуальное введённое значение.