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