Как правильно получать и обрабатывать актуальные данные формы и табличных частей в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Понятие данных формы и элементов интерфейса

Прежде всего, проанализируем, что происходит, когда мы открываем форму документа или справочника. В контексте управляемого приложения важно разделять две сущности:

  1. Данные формы (Реквизиты) — это структура, которая хранит значения. Главным реквизитом обычно является Объект. Это «легкая» копия данных прикладного объекта, предназначенная для отображения на клиенте.
  2. Элементы формы — это визуальные контролы (поля ввода, кнопки, таблицы), которые мы видим на экране.

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

Почему ТекущиеДанные работают только для таблиц?

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

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

Если бы мы хотели получить данные строки через Объект, нам пришлось бы знать индекс строки:


// Так можно обратиться, если мы знаем номер строки (индекс)
ТекущаяСтрока = Объект.Товары[0]; 
Номенклатура = ТекущаяСтрока.Номенклатура;

Но поскольку пользователь может сортировать таблицу, удалять строки или перемещать их, индекс — вещь ненадежная. Поэтому разработчики платформы создали удобный «мостик» в виде свойства ТекущиеДанные, который по сути делает следующее: Объект.Товары[ИндексАктивнойСтроки].

Когда данные на форме становятся актуальными?

Рассмотрим механизм синхронизации. Проанализируем типичный сценарий: пользователь вводит новое значение в поле на форме. В какой момент Объект.Контрагент получит это значение?

Синхронизация происходит в момент завершения редактирования. Обычно это случается, когда поле теряет фокус (пользователь нажал Tab, Enter или кликнул мышкой в другое место). Именно в этот момент срабатывает событие ПриИзменении, и данные из визуального элемента переносятся в реквизит Объект. До этого момента в памяти Объект может храниться старое значение.

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

Особенности работы с табличными частями

При работе с таблицами важно учитывать состояние фокуса. Рассмотрим пример безопасного получения данных текущей строки:


&НаКлиенте
Процедура ОбработатьСтроку()
    
    ДанныеСтроки = Элементы.Товары.ТекущиеДанные;
    
    // Обязательно проверяем на Неопределено, если таблица может быть пустой
    Если ДанныеСтроки <> Неопределено Тогда
        Сообщить("Выбрана номенклатура: " + ДанныеСтроки.Номенклатура);
        // Мы можем менять данные прямо здесь
        ДанныеСтроки.Количество = 10; 
        // Это изменение сразу отразится в Объект.Товары
    КонецЕсли;
    
КонецПроцедуры

Обратите внимание: ТекущиеДанные возвращают не копию, а ссылку на строку данных формы. Изменяя ДанныеСтроки.Количество, вы напрямую меняете данные в Объект.Товары.

Разница между идентификатором строки и индексом

Многие путают свойство Элементы.Таблица.ТекущаяСтрока и ТекущиеДанные. Посмотрим на различия:

Если вам нужно программно найти строку в данных формы по её идентификатору, используйте специальный метод:


Идентификатор = Элементы.Товары.ТекущаяСтрока;
СтрокаДанных = Объект.Товары.НайтиПоИдентификатору(Идентификатор);

Работа во внешних обработках

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

Взаимодействие с сервером и «актуальность»

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

Чтобы минимизировать объем передаваемых данных, следуйте правилам:

  1. Для получения данных текущей строки используйте ТекущиеДанные на клиенте и передавайте на сервер только необходимые значения (например, ссылку на товар), а не всю строку целиком.
  2. Если нужно изменить один реквизит объекта на сервере, не всегда обязательно гонять весь Объект. Иногда эффективнее использовать внеконтекстные серверные вызовы &НаСервереБезКонтекста.

Итоги и рекомендации

Для правильного получения актуальных данных следуйте этим правилам:

Помните, что Объект на форме — это не данные в базе данных. Пока вы не вызвали метод Записать(), все ваши изменения в Объект.Реквизит или ТекущиеДанные существуют только в оперативной памяти формы. Если закрыть форму без сохранения, все эти «актуальные» данные будут потеряны.

← На главную