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