В процессе разработки интерфейсов на платформе 1С часто возникает задача: предоставить пользователю список элементов в одной таблице, чтобы он мог отметить нужные позиции флажками, а выбранные строки отобразились в другой таблице для дальнейшей обработки. Рассмотрим подробнее, как это реализовать, разберем типичные ошибки новичков и проанализируем наиболее эффективные методы программирования в этой ситуации.
Самый простой и понятный способ — это использование цикла. Мы пройдем по всем строкам исходной таблицы (источника) и, если условие выбора (например, флажок Выбран) истинно, добавим новую строку в таблицу-приемник. Разберем по шагам, как это выглядит в коде.
Важно помнить, что если в обеих таблицах имена колонок совпадают, мы можем использовать встроенную функцию ЗаполнитьЗначенияСвойств(), что значительно сократит код и уменьшит вероятность ошибок.
// Предположим, ТаблицаИсточник и ТаблицаПриемник - это данные формы
// Очищаем таблицу-приемник перед заполнением, чтобы не было дублей
Объект.ТаблицаПриемник.Очистить();
Для Каждого СтрокаИсточника Из Объект.ТаблицаИсточник Цикл
// Проверяем, установлен ли флажок в колонке "Выбор"
Если СтрокаИсточника.Выбор = Истина Тогда
// Добавляем новую строку во вторую таблицу
НоваяСтрока = Объект.ТаблицаПриемник.Добавить();
// Копируем данные всех колонок с одинаковыми именами
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника);
КонецЕсли;
КонецЦикла;
Важный нюанс: этот код лучше всего размещать в обработчике события ПриИзменении флажка в первой таблице или вешать на отдельную кнопку "Обновить" или "Применить".
Если ваша таблица является не просто элементом формы, а объектом типа ТаблицаЗначений, мы можем применить более производительный метод НайтиСтроки(). Проанализируем ситуацию: когда строк тысячи, обычный цикл может работать медленнее, чем встроенные методы платформы.
Рассмотрим пример кода, который позволяет быстро получить массив выбранных строк и загрузить их в другую таблицу:
// Создаем структуру отбора
ПараметрыОтбора = Новый Структура("Выбор", Истина);
// Получаем массив строк, соответствующих условию
МассивВыбранныхСтрок = ТаблицаИсточник.НайтиСтроки(ПараметрыОтбора);
// Очищаем таблицу-приемник
ТаблицаПриемник.Очистить();
// Заполняем таблицу-приемник из массива
Для Каждого СтрокаМассива Из МассивВыбранныхСтрок Цикл
ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаМассива);
КонецЦикла;
Иногда нет необходимости физически копировать данные из одной таблицы в другую. Если обе таблицы должны отображать одни и те же данные, но в разном составе, можно использовать механизм отборов. Выясним причину, почему это удобно: изменения в одной таблице (например, редактирование количества) сразу будут отражаться во второй, так как источник данных у них общий.
В Обычных формах для этого используется свойство элемента управления ОтборСтрок. В Управляемых формах, если данные связаны с динамическим списком, мы работаем через КомпоновщикНастроек. Однако для обычных табличных частей на управляемой форме чаще всего применяется именно программное копирование, описанное в методе №1.
Проанализируем фрагмент кода, который часто пытаются написать новички: удаление строк, которые не были выбраны. Рассмотрим, почему этот код может работать некорректно:
// ОШИБОЧНЫЙ ПОДХОД
Для Каждого Строка Из ТЧ Цикл
Если Строка.Выбор = Ложь Тогда
ТЧ.Удалить(Строка); // ОШИБКА: коллекция меняется во время обхода!
КонецЕсли;
КонецЦикла;
Когда мы вызываем метод Удалить(), индексы всех последующих строк в коллекции смещаются. В результате цикл "перепрыгивает" через одну строку, и некоторые невыбранные строки останутся в таблице. Чтобы правильно удалить строки, нужно использовать цикл "с конца" или сначала собрать строки в массив.
Правильный способ удаления:
КолличествоСтрок = Объект.ТЧ.Количество();
// Обходим таблицу с последней строки к первой
Для Индекс = 1 По КолличествоСтрок Цикл
ОбратныйИндекс = КолличествоСтрок - Индекс;
ТекущаяСтрока = Объект.ТЧ[ОбратныйИндекс];
Если НЕ ТекущаяСтрока.Выбор Тогда
Объект.ТЧ.Удалить(ОбратныйИндекс);
КонецЕсли;
КонецЦикла;
Для того чтобы работа с таблицами была комфортной для пользователя, рекомендуем внедрить следующие доработки:
АвтоОтработкаИзменения в значение Истина, чтобы событие ПриИзменении срабатывало сразу при клике мышкой, а не после потери фокуса строкой.КлючСвязи, где будет храниться индекс или уникальный идентификатор строки из первой таблицы. Это позволит вам легко найти и удалить конкретную строку во второй таблице, если пользователь снимет флажок в первой.Таким образом, выбор метода зависит от архитектуры вашего решения. Для простых задач идеально подходит цикл с ЗаполнитьЗначенияСвойств(), а для сложных интерфейсов с большими объемами данных стоит рассмотреть варианты с Ключами связи или использованием временных таблиц значений на сервере.