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