Как эффективно сравнить и синхронизировать две табличные части в 1С?

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

При разработке конфигураций на платформе 1С часто возникает задача сравнения содержимого двух табличных частей (ТЧ). Например, когда нам нужно найти общие элементы, удалить дубли или выявить строки, существующие только в одной из таблиц. Рассмотрим основные подходы к реализации этого алгоритма, оценим их плюсы и минусы и разберем практические примеры кода.

Метод первый: Использование запросов и временных таблиц

Когда объем данных измеряется сотнями тысяч строк, использование механизмов СУБД становится наиболее оправданным. Запрос позволяет выполнить операцию сравнения на стороне сервера баз данных, что значительно быстрее итеративного перебора.

Пошаговый алгоритм:

  1. Помещаем содержимое обеих табличных частей во временные таблицы (ВТ1 и ВТ2), обязательно сохраняя информацию о номере строки, чтобы впоследствии точно идентифицировать записи для удаления.
  2. Выполняем левое соединение (или иное, в зависимости от бизнес-логики) между таблицами по полю Номенклатура.
  3. Отбираем записи, где результат соединения с другой таблицей дает NULL, что означает отсутствие совпадений.

Преимущество этого метода в высокой производительности при больших выборках. Мы получаем компактный список индексов строк, которые необходимо удалить из объектов ТабличнаяЧасть.

Метод второй: Алгоритмический подход в оперативной памяти

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

Разберем реализацию через массивы:

Создадим два массива, в которые будем собирать строки для последующего удаления. Это позволит избежать ошибок при изменении коллекции прямо во время обхода.


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

Для Каждого СтрокаТЧ1 Из ТЧ1 Цикл
    СтрокиТЧ2 = ТЧ2.НайтиСтроки(Новый Структура("Номенклатура", СтрокаТЧ1.Номенклатура));
    Если СтрокиТЧ2.Количество() > 0 Тогда
        МассивДляУдаления1.Добавить(СтрокаТЧ1);
        Для Каждого Стр2 Из СтрокиТЧ2 Цикл
            МассивДляУдаления2.Добавить(Стр2);
        КонецЦикла;
    КонецЕсли;
КонецЦикла;

Для Каждого Стр Из МассивДляУдаления1 Цикл
    ТЧ1.Удалить(Стр);
КонецЦикла;

Для Каждого Стр Из МассивДляУдаления2 Цикл
    ТЧ2.Удалить(Стр);
КонецЦикла;

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

Оптимизация: использование метода «Соответствие»

Если данных очень много, а использование запроса по какой-то причине нежелательно, мы можем применить Соответствие. Это позволит свести сложность поиска к линейной.

Мы предварительно выгружаем ключи поиска второй таблицы в Соответствие. Теперь вместо вызова метода НайтиСтроки(), который перебирает всю таблицу, мы мгновенно обращаемся к элементу по ключу. Это ускоряет процесс в десятки раз на массивах в сотни тысяч строк.

Важные рекомендации при работе с ТЧ

Чтобы ваша разработка была надежной и быстрой, учитывайте следующие нюансы:

Подводя итог, выбор метода зависит от контекста задачи. Для серверной обработки огромных списков — используйте запросы. Для оперативной работы с объектами в модулях форм — используйте массивы или Соответствие, стараясь минимизировать вложенные циклы.

← На главную