При разработке интерактивных форм часто возникает задача перемещения строк из одной таблицы в другую. На первый взгляд алгоритм кажется простым: обойти выделенные строки, добавить их в таблицу-приемник и удалить из исходной таблицы. Однако при попытке реализовать этот механизм разработчики регулярно сталкиваются с ошибками вроде «Индекс находится за границами массива» или пропуском части выделенных строк.
В этой статье мы разберем причину возникновения таких ошибок и рассмотрим правильный способ переноса данных на управляемых формах.
Проанализируем типичный ошибочный код, который часто пишут на начальном этапе:
Для Каждого тек Из Элементы.ВсеТовары.ВыделенныеСтроки Цикл
СтрВТ = ТоварыДляПечати.Добавить();
ЗаполнитьЗначенияСвойств(СтрВТ, ВсеТовары[тек]);
ВсеТовары.Удалить(ВсеТовары.Индекс(ВсеТовары.НайтиПоИдентификатору(тек)));
КонецЦикла;
Здесь кроются сразу две существенные проблемы:
ВыделенныеСтроки элемента таблицы возвращает массив уникальных идентификаторов строк (числовые значения), а не их порядковые индексы в коллекции. Обращение к таблице через квадратные скобки ВсеТовары[тек] пытается получить строку по индексу, что приводит к некорректным данным или выходу за границы массива.Чтобы избежать ошибок, разберем решение по шагам:
НайтиПоИдентификатору(), копируем их данные в новую таблицу и сохраняем идентификатор в промежуточный массив.Рассмотрим рабочий пример кода для переноса строк между таблицами формы:
МассивДляУдаления = Новый Массив;
// 1. Переносим данные и запоминаем идентификаторы
Для Каждого ИДИзВыделенных Из Элементы.ВсеТовары.ВыделенныеСтроки Цикл
// Получаем текущую строку таблицы-источника по ее идентификатору
СтрокаИсточника = ВсеТовары.НайтиПоИдентификатору(ИДИзВыделенных);
Если СтрокаИсточника <> Неопределено Тогда
// Создаем новую строку в таблице-приемнике
НоваяСтрока = ТоварыДляПечати.Добавить();
// Копируем значения совпадающих реквизитов
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника);
// Сохраняем идентификатор для последующего удаления
МассивДляУдаления.Добавить(ИДИзВыделенных);
КонецЕсли;
КонецЦикла;
// 2. Удаляем перенесенные строки из исходной таблицы
Для Каждого ИДДляУдаления Из МассивДляУдаления Цикл
СтрокаДляУдаления = ВсеТовары.НайтиПоИдентификатору(ИДДляУдаления);
Если СтрокаДляУдаления <> Неопределено Тогда
ВсеТовары.Удалить(СтрокаДляУдаления);
КонецЕсли;
КонецЦикла;
Существует еще один компактный способ удаления выделенных строк, когда удаление выполняется с первой выделенной строки до тех пор, пока массив выделенных строк не станет пустым:
Пока Элементы.ВсеТовары.ВыделенныеСтроки.Количество() > 0 Цикл
ИДПервойСтроки = Элементы.ВсеТовары.ВыделенныеСтроки[0];
СтрокаИсточника = ВсеТовары.НайтиПоИдентификатору(ИДПервойСтроки);
Если СтрокаИсточника <> Неопределено Тогда
НоваяСтрока = ТоварыДляПечати.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника);
ВсеТовары.Удалить(СтрокаИсточника);
КонецЕсли;
КонецЦикла;
Важно учитывать, что метод НайтиПоИдентификатору() доступен для коллекций данных формы (ДанныеФормыКоллекция). При работе с объектами таблиц всегда проверяйте, что поиск вернул значение, отличное от Неопределено.