При разработке функционала на управляемых формах 1С часто возникает необходимость взаимодействовать с данными, отображаемыми в таблицах. Распространенная задача — при клике по строке таблицы получить все данные этой строки для дальнейшей обработки. Однако, многие разработчики сталкиваются с тем, что стандартные параметры событий, такие как ВыбраннаяСтрока, или свойства элемента формы, например, ТекущаяСтрока, возвращают не сам объект строки с данными, а некий числовой идентификатор. Рассмотрим, почему это происходит и как правильно получить доступ ко всем данным выбранной строки.
Наш читатель столкнулся именно с такой ситуацией. Требовалось при выборе строки в одной таблице (ТоварВБраке) переместить её в другую (ТоварПодСписание) и удалить из первой. Изначально была попытка использовать параметр ВыбраннаяСтрока напрямую, но оказалось, что он содержит лишь числовой идентификатор.
Прежде чем мы перейдем к решениям, давайте проанализируем, что представляют собой ВыбраннаяСтрока и ТекущаяСтрока. В управляемых формах 1С, когда таблица формы (Элементы.ТоварВБраке в нашем случае) связана с реквизитом формы типа ТаблицаЗначений или ДанныеФормыКоллекция, эти свойства возвращают идентификатор текущей (выделенной) строки.
Элементы.ТаблицаФормы.ТекущаяСтрока: Это свойство элемента формы "Таблица" возвращает числовой идентификатор текущей строки. Платформа 1С использует этот уникальный нумератор для однозначной привязки строки таблицы формы к соответствующему элементу в связанной коллекции данных. Важно отметить, что этот идентификатор не обязательно совпадает с индексом строки в коллекции. При добавлении и удалении строк идентификаторы могут не следовать подряд.ВыбраннаяСтрока события Выбор: В контексте таблиц управляемых форм этот параметр также возвращает числовой идентификатор выбранной строки, аналогично свойству ТекущаяСтрока.Задача состоит в том, чтобы, имея этот идентификатор, получить доступ к самому объекту строки, содержащему все значения колонок.
НайтиПоИдентификатору()Это классический и рекомендуемый способ получения объекта строки по её идентификатору. Метод НайтиПоИдентификатору() применяется к самому реквизиту формы, который имеет тип ТаблицаЗначений или ДанныеФормыКоллекция.
Выбор или ПриАктивизацииСтроки, мы получаем идентификатор выбранной строки. Этот идентификатор будет передан в серверную процедуру.НайтиПоИдентификатору(), примененный к реквизиту формы, представляющему собой таблицу данных. Этот метод возвращает объект строки или Неопределено, если строка не найдена.Исходный код нашего читателя:
&НаСервере
Процедура ТоварВБракеВыборНаСервере(ВыбраннаяСтрока) // ВыбраннаяСтрока здесь - это идентификатор
Если Элементы.ТоварВБраке.ТекущаяСтрока <> Неопределено тогда
Добавление = ТоварПодСписание.Добавить();
ЗаполнитьЗначенияСвойств(Добавление, Элементы.ТоварВБраке.ТекущаяСтрока); // Здесь ошибка: ТекущаяСтрока - идентификатор
ТоварВБраке.Удалить(Элементы.ТоварВБраке.ТекущаяСтрока); // Здесь ошибка: ТекущаяСтрока - идентификатор
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ТоварВБракеВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
ТоварВБракеВыборНаСервере(ВыбраннаяСтрока); // Передаем идентификатор
КонецПроцедуры
В этом коде ошибка заключалась в том, что свойство Элементы.ТоварВБраке.ТекущаяСтрока (которое содержит идентификатор) использовалось напрямую в методах ЗаполнитьЗначенияСвойств и Удалить, ожидающих либо объект строки, либо её идентификатор для удаления.
НайтиПоИдентификатору():Изменим серверную процедуру, чтобы корректно получить объект строки по её идентификатору:
&НаСервере
Процедура ТоварВБракеВыборНаСервере(ИдентификаторВыбраннойСтроки)
// Получаем объект строки из реквизита формы 'ТоварВБраке' по идентификатору
// 'ТоварВБраке' - это сам реквизит формы типа ТаблицаЗначений или ДанныеФормыКоллекция
СтрокаДляОбработки = ТоварВБраке.НайтиПоИдентификатору(ИдентификаторВыбраннойСтроки);
Если СтрокаДляОбработки <> Неопределено Тогда
// Добавляем новую строку в другую таблицу
Добавление = ТоварПодСписание.Добавить();
// Копируем значения свойств из найденной строки в новую
ЗаполнитьЗначенияСвойств(Добавление, СтрокаДляОбработки);
// Удаляем исходную строку из первой таблицы
// Метод Удалить() для ТаблицыЗначений/ДанныеФормыКоллекция может принимать как объект строки,
// так и её идентификатор. В данном случае удобно использовать найденный идентификатор.
ТоварВБраке.Удалить(ИдентификаторВыбраннойСтроки);
// Альтернативно можно было бы: ТоварВБраке.Удалить(СтрокаДляОбработки);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ТоварВБракеВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
// Отменяем стандартную обработку события "Выбор", чтобы строка не открывалась для редактирования,
// если это не требуется.
СтандартнаяОбработка = Ложь;
// Передаем полученный идентификатор на сервер
ТоварВБракеВыборНаСервере(ВыбраннаяСтрока);
КонецПроцедуры
Важный момент: Метод ЗаполнитьЗначенияСвойств() — это очень удобный инструмент для копирования данных между объектами с похожим набором свойств (колонок), что значительно упрощает код и повышает его читаемость.
ТекущиеДанные элемента формыВ управляемых формах существует более прямой способ получить объект строки целиком, если действия выполняются на клиенте или если объект строки нужно передать на сервер. Это свойство ТекущиеДанные элемента формы "Таблица".
ТекущиеДанные?Свойство Элементы.ТаблицаФормы.ТекущиеДанные предоставляет прямой доступ к объекту данных текущей (выделенной) строки. Оно возвращает объект типа ДанныеФормыЭлементКоллекции, который уже содержит значения всех колонок строки. Это избавляет нас от необходимости сначала получать идентификатор, а затем искать по нему строку.
Выбор или ПриАктивизацииСтроки, мы обращаемся к свойству Элемент.ТекущиеДанные (где Элемент — это ссылка на сам элемент формы "Таблица"). Результатом будет уже полноценный объект строки.ДанныеФормыЭлементКоллекции на сервер. Платформа 1С корректно сериализует и десериализует его.ТекущиеДанные:
&НаСервере
Процедура ТоварВБракеВыборНаСервере(ВыбраннаяСтрокаДанные)
// ВыбраннаяСтрокаДанные уже является объектом строки (ДанныеФормыЭлементКоллекции),
// если передана из ТекущиеДанные на клиенте.
Если ВыбраннаяСтрокаДанные <> Неопределено Тогда
// Добавляем новую строку в другую таблицу
Добавление = ТоварПодСписание.Добавить();
// Копируем значения свойств из полученного объекта строки
ЗаполнитьЗначенияСвойств(Добавление, ВыбраннаяСтрокаДанные);
// Для удаления строки из ТаблицыЗначений нам нужен либо сам объект строки,
// либо её идентификатор. Объект ДанныеФормыЭлементКоллекции имеет метод ПолучитьИдентификатор().
ТоварВБраке.Удалить(ВыбраннаяСтрокаДанные.ПолучитьИдентификатор());
// Альтернативно можно было бы: ТоварВБраке.Удалить(ВыбраннаяСтрокаДанные);
// (если метод Удалить принимает объект ДанныеФормыЭлементКоллекции напрямую)
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ТоварВБракеВыбор(Элемент, ВыбраннаяСтрокаИдентификатор, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Отменяем стандартную обработку
// Получаем объект выбранной строки напрямую через свойство ТекущиеДанные элемента формы
ВыбраннаяСтрокаОбъект = Элемент.ТекущиеДанные; // Элемент - это элемент формы "Таблица"
// Передаем полученный объект строки на сервер для дальнейшей обработки
ТоварВБракеВыборНаСервере(ВыбраннаяСтрокаОбъект);
КонецПроцедуры
Использование Элементы.Таблица.ТекущиеДанные на клиенте часто более предпочтительно, поскольку сразу дает доступ к данным, упрощая код, особенно если большая часть логики может быть реализована на клиенте без лишних серверных вызовов. Однако, необходимо помнить, что при работе с несколькими выделенными строками (когда свойство таблицы формы МножественныйВыбор установлено в Истина), свойство ТекущиеДанные вернет только данные *активной* (фокусированной) строки. В этом случае для обработки всех выделенных строк потребуется итерироваться по коллекции выделенных идентификаторов и для каждого из них использовать НайтиПоИдентификатору().
Давайте проанализируем обе рассмотренные методики и определим, когда каждая из них наиболее уместна.
НайтиПоИдентификатору():
Элементы.Таблица.ВыделенныеСтроки), это единственный способ получить объекты этих строк.ТекущиеДанные:
ДанныеФормыЭлементКоллекции, который является "облегченной" версией строки данных, оптимизированной для работы на форме.ДанныеФормыЭлементКоллекции сериализуется, что может быть менее производительно по сравнению с передачей только идентификатора, если на сервере нужны лишь некоторые поля или если данные очень объемны.Элементы.Таблица.ТекущиеДанные.РеквизитФормыТипаТаблицаЗначений.НайтиПоИдентификатору(Идентификатор). Этот подход также более надежен, если логика требует строго серверного контекста для работы с данными.Мы выяснили, что параметр ВыбраннаяСтрока и свойство Элементы.Таблица.ТекущаяСтрока возвращают числовой идентификатор строки, а не сам объект данных. Для получения полных данных строки мы рассмотрели два эффективных способа:
РеквизитФормыТипаТаблицаЗначений.НайтиПоИдентификатору(ИдентификаторСтроки) на сервере.Элементы.ТаблицаФормы.ТекущиеДанные на клиенте для прямого доступа к объекту данных.Оба подхода позволяют решить задачу перемещения строки из одной таблицы в другую и удаления её из исходной, как требовалось в нашем примере. Выбор конкретного метода будет зависеть от специфики вашей задачи, контекста выполнения (клиент/сервер) и требований к производительности. Теперь вы обладаете инструментами для уверенной работы с данными таблиц на управляемых формах 1С!