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