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

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

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

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

Выясним причину ошибки

Проанализируем типичный ошибочный код, который часто пишут на начальном этапе:


Для Каждого тек Из Элементы.ВсеТовары.ВыделенныеСтроки Цикл
    СтрВТ = ТоварыДляПечати.Добавить();
    ЗаполнитьЗначенияСвойств(СтрВТ, ВсеТовары[тек]);
    ВсеТовары.Удалить(ВсеТовары.Индекс(ВсеТовары.НайтиПоИдентификатору(тек)));
КонецЦикла;

Здесь кроются сразу две существенные проблемы:

  1. Идентификатор строки — это не индекс. Свойство ВыделенныеСтроки элемента таблицы возвращает массив уникальных идентификаторов строк (числовые значения), а не их порядковые индексы в коллекции. Обращение к таблице через квадратные скобки ВсеТовары[тек] пытается получить строку по индексу, что приводит к некорректным данным или выходу за границы массива.
  2. Модификация коллекции во время обхода. При удалении строки из исходной таблицы данных платформа автоматически корректирует состав выделенных строк и их индексы. В результате цикл пропускает элементы или сбивается.

Алгоритм правильного переноса строк

Чтобы избежать ошибок, разберем решение по шагам:

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

Правильная реализация на клиенте

Рассмотрим рабочий пример кода для переноса строк между таблицами формы:


МассивДляУдаления = Новый Массив;

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

КонецЦикла;

// 2. Удаляем перенесенные строки из исходной таблицы
Для Каждого ИДДляУдаления Из МассивДляУдаления Цикл
    СтрокаДляУдаления = ВсеТовары.НайтиПоИдентификатору(ИДДляУдаления);
    Если СтрокаДляУдаления <> Неопределено Тогда
        ВсеТовары.Удалить(СтрокаДляУдаления);
    КонецЕсли;
КонецЦикла;

Альтернативный вариант через цикл «Пока»

Существует еще один компактный способ удаления выделенных строк, когда удаление выполняется с первой выделенной строки до тех пор, пока массив выделенных строк не станет пустым:


Пока Элементы.ВсеТовары.ВыделенныеСтроки.Количество() > 0 Цикл
    ИДПервойСтроки = Элементы.ВсеТовары.ВыделенныеСтроки[0];
    СтрокаИсточника = ВсеТовары.НайтиПоИдентификатору(ИДПервойСтроки);
    
    Если СтрокаИсточника <> Неопределено Тогда
        НоваяСтрока = ТоварыДляПечати.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника);
        ВсеТовары.Удалить(СтрокаИсточника);
    КонецЕсли;
КонецЦикла;

Важно учитывать, что метод НайтиПоИдентификатору() доступен для коллекций данных формы (ДанныеФормыКоллекция). При работе с объектами таблиц всегда проверяйте, что поиск вернул значение, отличное от Неопределено.

← На главную