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