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