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

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

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

Способы получить текущие данные формы в 1С: Элементы.Список.ТекущиеДанные, ЭтаФорма, Объект, работа в клиентских и серверных процедурах, типовые ошибки и примеры кода.

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

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

Ниже разобраны основные приёмы: получение текущей строки динамического списка, обращение к реквизитам объекта через Объект, работа с табличными частями, передача данных между клиентскими и серверными процедурами, а также типовые ошибки, из-за которых код «не видит» значения.

Что такое текущие данные формы и где они хранятся

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

Понятие «текущие данные» обычно означает одно из двух: либо данные активной строки таблицы (списка документов, табличной части товаров), либо текущие значения реквизитов редактируемого объекта. В первом случае используется свойство ТекущиеДанные таблицы формы, во втором — прямое обращение к реквизитам формы.

Важно помнить про контекст выполнения. В клиентской процедуре доступны данные формы в структурном виде, но недоступны методы прикладного объекта (например, проведение). На сервере данные формы нужно преобразовать в прикладной объект через РеквизитФормыВЗначение, а после изменений вернуть обратно через ЗначениеВРеквизитФормы.

Как получить текущую строку динамического списка

На форме списка документов, справочников или регистров текущая строка читается через таблицу формы, отображающую список. Типовой код в клиентской процедуре выглядит так:

&НаКлиенте

Процедура ПоказатьТекущийДокумент(Команда)

ТекущиеДанные = Элементы.Список.ТекущиеДанные;

Если ТекущиеДанные = Неопределено Тогда

ПоказатьПредупреждение(, "Строка не выбрана");

Возврат;

КонецЕсли;

Сообщить("Выбран документ: " + ТекущиеДанные.Ссылка);

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

Обязательна проверка на Неопределено: если список пуст или ни одна строка не активна, свойство вернёт именно это значение, и обращение к полям вызовет ошибку. Для получения только ссылки без остальных полей можно использовать Элементы.Список.ТекущаяСтрока — оно возвращает ссылку на текущий объект напрямую.

Если список отображает несколько выделенных строк (при включённом множественном выборе), перебирайте коллекцию Элементы.Список.ВыделенныеСтроки — она содержит идентификаторы строк, по которым можно получить данные через Элементы.Список.ДанныеСтроки(Идентификатор).

Порядок действий для формы списка
  1. 1
    Определите имя элемента формы, отображающего список (обычно «Список»)
  2. 2
    В клиентской процедуре получите Элементы.ИмяСписка.ТекущиеДанные
  3. 3
    Проверьте результат на Неопределено
  4. 4
    Обратитесь к нужным полям по имени: ТекущиеДанные.Номер, ТекущиеДанные.Ссылка
  5. 5
    Для нескольких строк используйте ВыделенныеСтроки и ДанныеСтроки

Как обратиться к реквизитам объекта на форме документа

На форме документа, справочника или другого объекта текущие значения реквизитов доступны через главный реквизит формы — по умолчанию он называется Объект. В клиентской процедуре обращение прямое: Объект.Контрагент, Объект.Дата, Объект.Товары. Это структура данных формы, а не прикладной объект, поэтому методы вроде Записать() у неё отсутствуют.

Табличные части читаются перебором строк: Для Каждого Строка Из Объект.Товары Цикл ... КонецЦикла. Текущая строка табличной части получается так же, как в списке: Элементы.Товары.ТекущиеДанные. Это удобно в обработчиках событий таблицы — «ПриИзменении», «ПередУдалением», где нужно знать, какую именно строку редактирует пользователь.

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

Получение данных формы на сервере

Серверные процедуры формы не имеют прямого доступа к элементам управления, но работают с реквизитами формы так же по имени. Чтобы получить полноценный прикладной объект со всеми методами, используется преобразование:

&НаСервере

Процедура ЗаполнитьПоДаннымОбъекта()

ДокументОбъект = РеквизитФормыВЗначение("Объект");

ДокументОбъект.Заполнить(Неопределено);

ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");

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

Обратное преобразование ЗначениеВРеквизитФормы обязательно, иначе изменения останутся в локальной переменной и не попадут на форму — пользователь увидит старые значения. Это одна из самых частых причин «неработающего» серверного кода.

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

Чтение данных чужой формы и передача между формами

Иногда нужно получить данные формы, открытой из другой формы — например, при выборе значения в поле ввода. Стандартный механизм — обработка оповещения: открывающая форма подписывается на закрытие через ОписаниеОповещения, а закрываемая форма возвращает результат через Закрыть(Результат).

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

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

Способы получить данные формы

Элементы.ИмяТаблицы.ТекущиеДанные

Текущая строка списка или табличной части на клиенте. Не работает на сервере и требует проверки на Неопределено

Объект.ИмяРеквизита

Реквизиты редактируемого объекта на клиенте и сервере. Не даёт доступа к методам прикладного объекта

РеквизитФормыВЗначение

Полный прикладной объект на сервере с методами. Требует обратного преобразования и ресурсоёмок

ЭтаФорма.ИмяРеквизита

Дополнительные реквизиты формы. Работает только в модуле самой формы

Типичные ошибки при работе с текущими данными

Самая распространённая ошибка — обращение к ТекущиеДанные без проверки на Неопределено. В пустом списке или после удаления строки свойство возвращает Неопределено, и попытка прочитать поле приводит к падению кода. Проверка должна стоять всегда, даже если «строка точно есть».

Вторая группа ошибок связана с контекстом: попытка вызвать Элементы на сервере, использование РеквизитФормыВЗначение на клиенте или вызов методов объекта у структуры данных формы. Директивы компиляции &НаКлиенте и &НаСервере нужно расставлять осознанно, а не копировать из примера.

Третья типичная проблема — чтение значения из элемента управления вместо данных. Конструкции вроде поиска по представлению поля ввода ненадёжны: представление может отличаться от реального значения (форматирование, маска, быстрый выбор). Всегда читайте реквизит, к которому привязан элемент.

Типичные ошибки
01
Обращение к ТекущиеДанные без проверки на Неопределено — падение кода на пустом списке
02
Изменение объекта после РеквизитФормыВЗначение без ЗначениеВРеквизитФормы — изменения теряются
03
Чтение значения из элемента формы вместо реквизита — неверные данные при форматировании
04
Вызов методов прикладного объекта (Записать, Провести) у структуры Объект на клиенте — ошибка выполнения
05
Использование Элементы в серверной процедуре — элементы управления недоступны на сервере

Как проверить, что данные получены правильно

Быстрый способ отладки — вывести полученное значение через Сообщить() или остановиться точкой останова в конфигураторе и посмотреть переменную в табло. Для структур данных формы в табло видны все поля и их текущие значения.

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

Также полезно убедиться, что данные на форме актуальны: если объект модифицирован, но не записан, в базе хранится старая версия. Чтение данных формы даёт именно экранные значения, а запрос к базе — сохранённые. Путать эти два источника нельзя.

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

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

Значение ТекущиеДанные
Норма

Возвращает коллекцию с полями строки

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

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

Тип переменной через ТипЗнч()
Норма

Совпадает с ожидаемым (ссылка, строка данных формы)

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

Строка или Неопределено там, где ожидалась ссылка

Изменения после серверной процедуры
Норма

Новые значения видны на форме

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

Форма показывает старые данные — пропущено ЗначениеВРеквизитФормы

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

Чем ТекущиеДанные отличается от ТекущаяСтрока?

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

Почему ТекущиеДанные возвращает Неопределено?

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

Можно ли получить ТекущиеДанные на сервере?

Нет, элементы формы и их свойства доступны только на клиенте. На сервере работайте с реквизитами формы напрямую или передавайте нужные значения из клиентской процедуры параметрами.

Как получить данные строки табличной части по её номеру?

Через коллекцию: Объект.Товары[Индекс], где индекс начинается с нуля. Также можно найти строку по идентификатору: Объект.Товары.НайтиПоИдентификатору(ИдентификаторСтроки).

Как прочитать данные формы, открытой другой обработкой?

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

Почему изменения на сервере не видны на форме?

После РеквизитФормыВЗначение вы работаете с отдельной копией объекта. Чтобы изменения попали на форму, нужно вернуть объект вызовом ЗначениеВРеквизитФормы(Объект, "Объект").

Итог

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

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