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

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

В процессе эксплуатации крупных информационных систем на базе 1С программисты часто сталкиваются с проблемой возникновения большого количества дублирующихся элементов справочников. Особенно остро этот вопрос встает после некорректного переноса данных через «Конвертацию данных» или при интеграции с внешними системами. Когда количество дублей исчисляется тысячами (например, более 1500 групп), стандартная обработка «Поиск и удаление дублей» может потреблять слишком много ресурсов, вызывать переполнение лога транзакций или просто «умирать» по таймауту. Рассмотрим, как решить эту задачу различными методами: от оптимизации штатных средств до низкоуровневых манипуляций в MS SQL Server.

Причина проблемы: почему стандартные средства дают сбой

Разберем ситуацию: типовая обработка в конфигурациях на БСП пытается выполнить поиск и замену ссылок в рамках одной или нескольких крупных транзакций. Когда система находит сотни мест использования для каждой из 1500 ссылок-дублей, объем изменяемых данных становится критическим. Процессорное время тратится на анализ метаданных, поиск по всем таблицам базы данных и проверку бизнес-логики в модулях объектов. Если база работает в режиме 24/7, длительная блокировка таблиц недопустима.

Решение 1. Оптимизация работы типовой обработки

Проанализируем самый безопасный путь — разделение задачи на части. Вместо того чтобы пытаться обработать все 1500 дублей сразу, выполним следующие шаги:

  1. Откроем обработку «Поиск и удаление дублей».
  2. В настройках отбора установим дополнительные фильтры. Например, можно обрабатывать контрагентов по алфавиту (наименование начинается на «А», затем на «Б») или по диапазонам ИНН.
  3. Выполним поиск и замену для каждой группы отдельно. Это позволит транзакциям завершаться быстрее и не перегружать сервер приложений.

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

Решение 2. Программный поиск и замена ссылок (Batch-обработка)

Если ручное разделение на части занимает слишком много времени, напишем собственную обработку. Рассмотрим алгоритм, который будет программно находить дубли по ключевым полям ИНН и КПП, а затем заменять ссылки порциями.

Сначала выполним запрос для поиска групп дублей:


ВЫБРАТЬ
    Контрагент.ИНН КАК ИНН,
    Контрагент.КПП КАК КПП,
    КОЛИЧЕСТВО(Контрагент.Ссылка) КАК КоличествоДублей
ПОМЕСТИТЬ ВТ_Дубли
ИЗ
    Справочник.Контрагенты КАК Контрагент
ГДЕ
    Контрагент.ЭтоГруппа = ЛОЖЬ
СГРУППИРОВАТЬ ПО
    Контрагент.ИНН,
    Контрагент.КПП
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(Контрагент.Ссылка) > 1
;

ВЫБРАТЬ
    Контрагент.Ссылка КАК Ссылка,
    ВТ_Дубли.ИНН,
    ВТ_Дубли.КПП
ИЗ
    Справочник.Контрагенты КАК Контрагент
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Дубли КАК ВТ_Дубли
    ПО Контрагент.ИНН = ВТ_Дубли.ИНН
    И Контрагент.КПП = ВТ_Дубли.КПП
УПОРЯДОЧИТЬ ПО
    ВТ_Дубли.ИНН

После получения списка дублей нам необходимо выбрать один «эталонный» элемент (например, самый ранний по дате создания или имеющий заполненные реквизиты) и заменить все остальные ссылки на него. Для этого воспользуемся методом ЗаменитьСсылки(), но будем вызывать его в цикле для небольших пакетов данных.

Важный момент: при программной замене обязательно устанавливайте свойство ОбменДанными.Загрузка = Истина. Это позволит избежать выполнения тяжелых проверок в модулях объектов, которые при массовой замене могут затормозить процесс в десятки раз.

Решение 3. Использование инструментов разработчика (ИР)

Рассмотрим использование профессионального инструментария, такого как «Инструменты разработчика» (авторства Сергея Старых). В этом расширении или обработке есть продвинутые механизмы поиска и замены значений. Проанализируем их преимущества:

Решение 4. Низкоуровневая замена через MS SQL Server

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

Для глобального поиска и замены в SQL можно использовать динамический скрипт. Однако, в контексте 1С, замена дублей контрагентов — это чаще всего замена Binary(16) (UUID ссылки), а не текста. Если же вам нужно заменить именно текст (например, ошибочно записанный «абв» на «агд» во всех текстовых полях), можно использовать следующий подход:


-- ПРИМЕР: Поиск и замена текста в конкретной таблице
UPDATE _Reference15 -- Имя таблицы справочника контрагентов в SQL
SET _Fld1234 = REPLACE(_Fld1234, 'абв', 'агд')
WHERE _Fld1234 LIKE '%абв%';

Выясним, почему этот метод опасен для 1С:

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

Специфика дублей в регистрах сведений

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

При замене ссылок на контрагента 1С автоматически обновит записи в регистрах, где Контрагент является измерением или ресурсом. Однако, если ИНН записан как независимый строковый реквизит (собственный реквизит регистра), типовая замена ссылок его не тронет. В этом случае придется дополнительно пройтись по таким регистрам программным перебором.

Итоговые рекомендации

Рассмотрев все варианты, мы рекомендуем придерживаться следующего плана действий:

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

2. Попробуйте выполнить замену штатными средствами, но малыми порциями (через фильтры в обработке).

3. Если штатные средства не подходят, используйте программный цикл с использованием метода ЗаменитьСсылки() и обязательным флагом ОбменДанными.Загрузка = Истина. Это обеспечит максимальную производительность при сохранении ссылочной целостности.

4. К прямому SQL-запросу UPDATE прибегайте только в самом крайнем случае, если нужно исправить тысячи строк в текстовых полях, которые не связаны с бизнес-логикой и итогами регистров, и только после полной остановки сервера приложений 1С для очистки кэша.

Помните, что 1500 дублей — это значительный объем, требующий аккуратности. Правильный подход — это всегда сочетание автоматизации и контроля за целостностью данных.

← На главную