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

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

В процессе разработки на платформе 1С:Предприятие 8.3 (особенно в режиме управляемого приложения) часто возникает задача: предоставить пользователю возможность выбрать несколько строк в одной форме и передать их для обработки или отображения в другую форму той же обработки. На первый взгляд задача кажется простой, но она таит в себе важные архитектурные нюансы, связанные с разделением контекста клиента и сервера.

В этой статье мы подробно разберем, как правильно извлечь данные выделенных строк, в каком виде их лучше передавать и как принять эти данные на стороне вызываемой формы.

Понимание механизма выделенных строк

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

Рассмотрим по шагам правильный алгоритм действий:

  1. Получение массива идентификаторов выделенных строк.
  2. Обход этого массива и получение реальных данных (значений реквизитов) из таблицы.
  3. Упаковка данных в универсальную коллекцию (Массив или Структура).
  4. Передача данных через параметры метода ОткрытьФорму.

Способ 1. Передача через массив структур (рекомендуемый)

Этот способ идеально подходит для небольшого и среднего объема данных. Мы формируем массив, элементами которого являются структуры с нужными нам полями. Это позволяет передать только те данные, которые действительно необходимы в другой форме.

Давайте посмотрим на пример кода, который выполняется в исходной форме:


&НаКлиенте
Процедура ВыгрузитьВыделенные(Команда)
    
    // Получаем массив идентификаторов выделенных строк
    ВыделенныеСтроки = Элементы.Товары.ВыделенныеСтроки;
    
    // Создаем массив для хранения данных
    МассивДанных = Новый Массив;
    
    Для Каждого Идентификатор Из ВыделенныеСтроки Цикл
        
        // Получаем данные конкретной строки по идентификатору
        ДанныеСтроки = Объект.Товары.НайтиПоИдентификатору(Идентификатор);
        
        // Формируем структуру только с необходимыми полями
        СтруктураСтроки = Новый Структура;
        СтруктураСтроки.Вставить("Номенклатура", ДанныеСтроки.Номенклатура);
        СтруктураСтроки.Вставить("Количество", ДанныеСтроки.Количество);
        СтруктураСтроки.Вставить("Цена", ДанныеСтроки.Цена);
        
        МассивДанных.Добавить(СтруктураСтроки);
        
    КонецЦикла;
    
    // Формируем параметры для открытия новой формы
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("ВыбранныеТовары", МассивДанных);
    
    // Открываем форму и передаем данные
    ОткрытьФорму("Обработка.МояОбработка.Форма.ВспомогательнаяФорма", ПараметрыФормы);
    
КонецПроцедуры

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

Способ 2. Использование временного хранилища

Если объем передаваемых данных велик (например, сотни или тысячи строк с большим количеством колонок), передача через параметры формы может вызвать "зависание" интерфейса из-за длительной сериализации. В этом случае рассмотрим вариант с использованием временного хранилища.

Суть метода заключается в том, чтобы поместить данные в хранилище на сервере и передать во вторую форму только уникальный адрес (строку).

Пример реализации на сервере исходной формы:


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

&НаКлиенте
Процедура ПередатьЧерезХранилище(Команда)
    
    Адрес = ПоместитьДанныеВоХранилище(Элементы.Товары.ВыделенныеСтроки);
    
    ПараметрыФормы = Новый Структура("АдресДанных", Адрес);
    ОткрытьФорму("Обработка.МояОбработка.Форма.ВспомогательнаяФорма", ПараметрыФормы);
    
КонецПроцедуры

Прием данных в вызываемой форме

Теперь выясним, как правильно обработать полученные данные во второй форме. Весь процесс происходит в обработчике события ПриСозданииНаСервере.

Если мы передавали массив структур (Способ 1):


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

Если мы использовали временное хранилище (Способ 2):


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Параметры.Свойство("АдресДанных") Тогда
        
        ДанныеИзХранилища = ПолучитьИзВременногоХранилища(Параметры.АдресДанных);
        
        Если ТипЗнч(ДанныеИзХранилища) = Тип("ТаблицаЗначений") Тогда
            Объект.ТаблицаПриемник.Загрузить(ДанныеИзХранилища);
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Дополнительные настройки интерфейса

Часто при открытии вспомогательной формы требуется, чтобы она не перекрывала весь экран, а выглядела как небольшое диалоговое окно, блокирующее владельца. Для этого при вызове ОткрытьФорму можно использовать дополнительные параметры:


ОткрытьФорму("Обработка.МояОбработка.Форма.ВспомогательнаяФорма", 
             ПараметрыФормы, 
             ЭтаФорма, // Владелец
             Истина,   // Уникальность
             , 
             , 
             , 
             РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

Проанализировав вышеизложенное, можно сделать вывод: выбор способа передачи зависит от объема данных. Для большинства повседневных задач программиста 1С достаточно передачи массива структур через параметры. Это обеспечивает простоту кода и легкость отладки.

Главное — помнить, что в управляемом приложении мы всегда передаем копии данных, а не ссылки на объекты таблиц или сами строки. Используя метод ЗаполнитьЗначенияСвойств, вы можете значительно упростить процесс копирования полей из переданных структур в новую таблицу.

← На главную