Как реализовать вывод выбранных данных из одной таблицы во вторую в 1С

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

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

Метод 1: Копирование строк через перебор коллекции

Самый простой и понятный способ — это использование цикла. Мы пройдем по всем строкам исходной таблицы (источника) и, если условие выбора (например, флажок Выбран) истинно, добавим новую строку в таблицу-приемник. Разберем по шагам, как это выглядит в коде.

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


// Предположим, ТаблицаИсточник и ТаблицаПриемник - это данные формы
// Очищаем таблицу-приемник перед заполнением, чтобы не было дублей
Объект.ТаблицаПриемник.Очистить();

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

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

Метод 2: Использование методов поиска для Таблицы Значений

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

Рассмотрим пример кода, который позволяет быстро получить массив выбранных строк и загрузить их в другую таблицу:


// Создаем структуру отбора
ПараметрыОтбора = Новый Структура("Выбор", Истина);

// Получаем массив строк, соответствующих условию
МассивВыбранныхСтрок = ТаблицаИсточник.НайтиСтроки(ПараметрыОтбора);

// Очищаем таблицу-приемник
ТаблицаПриемник.Очистить();

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

Метод 3: Динамическая фильтрация (Отбор строк)

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

В Обычных формах для этого используется свойство элемента управления ОтборСтрок. В Управляемых формах, если данные связаны с динамическим списком, мы работаем через КомпоновщикНастроек. Однако для обычных табличных частей на управляемой форме чаще всего применяется именно программное копирование, описанное в методе №1.

Анализ типичной ошибки: Удаление строк в цикле

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


// ОШИБОЧНЫЙ ПОДХОД
Для Каждого Строка Из ТЧ Цикл
    Если Строка.Выбор = Ложь Тогда
        ТЧ.Удалить(Строка); // ОШИБКА: коллекция меняется во время обхода!
    КонецЕсли;
КонецЦикла;

Когда мы вызываем метод Удалить(), индексы всех последующих строк в коллекции смещаются. В результате цикл "перепрыгивает" через одну строку, и некоторые невыбранные строки останутся в таблице. Чтобы правильно удалить строки, нужно использовать цикл "с конца" или сначала собрать строки в массив.

Правильный способ удаления:


КолличествоСтрок = Объект.ТЧ.Количество();
// Обходим таблицу с последней строки к первой
Для Индекс = 1 По КолличествоСтрок Цикл
    ОбратныйИндекс = КолличествоСтрок - Индекс;
    ТекущаяСтрока = Объект.ТЧ[ОбратныйИндекс];
    
    Если НЕ ТекущаяСтрока.Выбор Тогда
        Объект.ТЧ.Удалить(ОбратныйИндекс);
    КонецЕсли;
КонецЦикла;

Рекомендации по улучшению взаимодействия (UX)

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

  1. Мгновенное обновление: Установите у колонки с флажком свойство АвтоОтработкаИзменения в значение Истина, чтобы событие ПриИзменении срабатывало сразу при клике мышкой, а не после потери фокуса строкой.
  2. Служебные колонки: Если вы копируете данные, добавьте во вторую таблицу скрытую колонку КлючСвязи, где будет храниться индекс или уникальный идентификатор строки из первой таблицы. Это позволит вам легко найти и удалить конкретную строку во второй таблице, если пользователь снимет флажок в первой.
  3. Условное оформление: Используйте условное оформление, чтобы визуально выделить выбранные строки в первой таблице (например, изменить цвет фона), чтобы пользователь видел, какие данные уже перенесены.

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

← На главную