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

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

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

Наш читатель столкнулся именно с такой ситуацией. Требовалось при выборе строки в одной таблице (ТоварВБраке) переместить её в другую (ТоварПодСписание) и удалить из первой. Изначально была попытка использовать параметр ВыбраннаяСтрока напрямую, но оказалось, что он содержит лишь числовой идентификатор.

Понимание идентификаторов строк в управляемых формах 1С

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

  1. Элементы.ТаблицаФормы.ТекущаяСтрока: Это свойство элемента формы "Таблица" возвращает числовой идентификатор текущей строки. Платформа 1С использует этот уникальный нумератор для однозначной привязки строки таблицы формы к соответствующему элементу в связанной коллекции данных. Важно отметить, что этот идентификатор не обязательно совпадает с индексом строки в коллекции. При добавлении и удалении строк идентификаторы могут не следовать подряд.
  2. Параметр ВыбраннаяСтрока события Выбор: В контексте таблиц управляемых форм этот параметр также возвращает числовой идентификатор выбранной строки, аналогично свойству ТекущаяСтрока.

Задача состоит в том, чтобы, имея этот идентификатор, получить доступ к самому объекту строки, содержащему все значения колонок.

Решение 1: Использование метода НайтиПоИдентификатору()

Это классический и рекомендуемый способ получения объекта строки по её идентификатору. Метод НайтиПоИдентификатору() применяется к самому реквизиту формы, который имеет тип ТаблицаЗначений или ДанныеФормыКоллекция.

Разберем по шагам, как это работает:

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

Посмотрим на пример кода, предложенный в обсуждении, и его доработку:

Исходный код нашего читателя:


&НаСервере
Процедура ТоварВБракеВыборНаСервере(ВыбраннаяСтрока) // ВыбраннаяСтрока здесь - это идентификатор
    
    Если Элементы.ТоварВБраке.ТекущаяСтрока <> Неопределено тогда
        Добавление = ТоварПодСписание.Добавить();
        ЗаполнитьЗначенияСвойств(Добавление, Элементы.ТоварВБраке.ТекущаяСтрока); // Здесь ошибка: ТекущаяСтрока - идентификатор
        ТоварВБраке.Удалить(Элементы.ТоварВБраке.ТекущаяСтрока); // Здесь ошибка: ТекущаяСтрока - идентификатор
    КонецЕсли;
    
КонецПроцедуры
 &НаКлиенте
Процедура ТоварВБракеВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    ТоварВБракеВыборНаСервере(ВыбраннаяСтрока); // Передаем идентификатор
КонецПроцедуры

В этом коде ошибка заключалась в том, что свойство Элементы.ТоварВБраке.ТекущаяСтрока (которое содержит идентификатор) использовалось напрямую в методах ЗаполнитьЗначенияСвойств и Удалить, ожидающих либо объект строки, либо её идентификатор для удаления.

Правильная реализация с использованием НайтиПоИдентификатору():

Изменим серверную процедуру, чтобы корректно получить объект строки по её идентификатору:


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

&НаКлиенте
Процедура ТоварВБракеВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    // Отменяем стандартную обработку события "Выбор", чтобы строка не открывалась для редактирования,
    // если это не требуется.
    СтандартнаяОбработка = Ложь;
    
    // Передаем полученный идентификатор на сервер
    ТоварВБракеВыборНаСервере(ВыбраннаяСтрока);
КонецПроцедуры

Важный момент: Метод ЗаполнитьЗначенияСвойств() — это очень удобный инструмент для копирования данных между объектами с похожим набором свойств (колонок), что значительно упрощает код и повышает его читаемость.

Решение 2: Использование свойства ТекущиеДанные элемента формы

В управляемых формах существует более прямой способ получить объект строки целиком, если действия выполняются на клиенте или если объект строки нужно передать на сервер. Это свойство ТекущиеДанные элемента формы "Таблица".

В чем преимущество ТекущиеДанные?

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

Разберем по шагам, как это работает:

  1. Получение объекта строки на клиенте: В обработчике события, например, Выбор или ПриАктивизацииСтроки, мы обращаемся к свойству Элемент.ТекущиеДанные (где Элемент — это ссылка на сам элемент формы "Таблица"). Результатом будет уже полноценный объект строки.
  2. Передача объекта строки на сервер (опционально): Если дальнейшая обработка требует серверного вызова, мы можем передать этот объект ДанныеФормыЭлементКоллекции на сервер. Платформа 1С корректно сериализует и десериализует его.
  3. Дальнейшая обработка: На сервере или клиенте мы можем напрямую работать со свойствами полученного объекта строки.

Пример кода с использованием ТекущиеДанные:


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

&НаКлиенте
Процедура ТоварВБракеВыбор(Элемент, ВыбраннаяСтрокаИдентификатор, Поле, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь; // Отменяем стандартную обработку
    
    // Получаем объект выбранной строки напрямую через свойство ТекущиеДанные элемента формы
    ВыбраннаяСтрокаОбъект = Элемент.ТекущиеДанные; // Элемент - это элемент формы "Таблица"
    
    // Передаем полученный объект строки на сервер для дальнейшей обработки
    ТоварВБракеВыборНаСервере(ВыбраннаяСтрокаОбъект);
КонецПроцедуры

Использование Элементы.Таблица.ТекущиеДанные на клиенте часто более предпочтительно, поскольку сразу дает доступ к данным, упрощая код, особенно если большая часть логики может быть реализована на клиенте без лишних серверных вызовов. Однако, необходимо помнить, что при работе с несколькими выделенными строками (когда свойство таблицы формы МножественныйВыбор установлено в Истина), свойство ТекущиеДанные вернет только данные *активной* (фокусированной) строки. В этом случае для обработки всех выделенных строк потребуется итерироваться по коллекции выделенных идентификаторов и для каждого из них использовать НайтиПоИдентификатору().

Сравнение подходов и рекомендации

Давайте проанализируем обе рассмотренные методики и определим, когда каждая из них наиболее уместна.

  1. Метод НайтиПоИдентификатору():
    • Плюсы:
      • Универсален: работает как для текущей строки, так и для любой строки, чей идентификатор известен.
      • Необходим при работе с множественным выбором: когда у нас есть список идентификаторов выбранных строк (например, из Элементы.Таблица.ВыделенныеСтроки), это единственный способ получить объекты этих строк.
      • Подходит для сценариев, где идентификатор строки сохраняется и используется позже (например, в фоновом задании).
    • Минусы:
      • Требует отдельного вызова метода после получения идентификатора.
      • Часто требует серверного вызова, если сам реквизит формы является коллекцией данных, доступной только на сервере.
  2. Свойство ТекущиеДанные:
    • Плюсы:
      • Прямой доступ к объекту данных строки без дополнительного поиска.
      • Упрощает клиентский код, если вся необходимая логика выполняется на клиенте.
      • Возвращает объект типа ДанныеФормыЭлементКоллекции, который является "облегченной" версией строки данных, оптимизированной для работы на форме.
    • Минусы:
      • Работает только для одной активной (фокусированной) строки. Не подходит для обработки множественно выбранных строк.
      • При передаче на сервер, объект ДанныеФормыЭлементКоллекции сериализуется, что может быть менее производительно по сравнению с передачей только идентификатора, если на сервере нужны лишь некоторые поля или если данные очень объемны.

Когда использовать какой метод?

Заключение

Мы выяснили, что параметр ВыбраннаяСтрока и свойство Элементы.Таблица.ТекущаяСтрока возвращают числовой идентификатор строки, а не сам объект данных. Для получения полных данных строки мы рассмотрели два эффективных способа:

  1. Использование метода РеквизитФормыТипаТаблицаЗначений.НайтиПоИдентификатору(ИдентификаторСтроки) на сервере.
  2. Использование свойства Элементы.ТаблицаФормы.ТекущиеДанные на клиенте для прямого доступа к объекту данных.

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

← На главную