Как удалить более 100 000 дублей контрагентов в 1С:УНФ на управляемых формах

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет
← На главную

Проблема избыточного количества дублей в информационной базе — одна из самых сложных задач для администратора и программиста 1С. Когда счет идет на сотни тысяч записей, типовая обработка «Поиск и удаление дублей» перестает справляться. В этой статье мы подробно разберем, почему стандартные механизмы дают сбой, как оптимизировать процесс удаления огромных объемов данных и какие риски необходимо учитывать, чтобы не разрушить учет.

Почему типовая обработка не справляется с большими объемами?

Разберем основную причину низкой производительности стандартного механизма. В конфигурациях на управляемых формах, таких как 1С:УНФ, типовое решение использует специализированную библиотеку (DLL) для реализации так называемого «размытого» поиска (fuzzy search). Этот алгоритм пытается сопоставить схожесть строк, учитывая опечатки, перестановки слов и лишние символы.

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

Стратегия 1: Использование «Инструментов разработчика» (ИР)

Одним из самых эффективных альтернативных способов является использование портативного набора обработок «Инструменты разработчика». Рассмотрим, за счет чего этот инструмент выигрывает в скорости:

  1. Выборочный поиск ссылок: В отличие от типовой обработки, в ИР мы можем вручную ограничить область поиска ссылок. Если мы знаем, что контрагенты используются только в документах закупок и продаж, мы можем исключить из поиска производственные блоки, кадровые документы и неиспользуемые регистры сведения. Это сокращает время поиска в десятки раз.
  2. Прямое управление объектами: Инструмент позволяет производить замену ссылок и удаление объектов без лишних транзакционных издержек.
  3. Управление блокировками: Возможность более тонкой настройки блокировок позволяет избежать конфликтов при работе других пользователей.

Стратегия 2: Порционная обработка и маркировка

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

Посмотрим на алгоритм действий:

  1. Создадим произвольную обработку или воспользуемся групповым изменением реквизитов.
  2. Напишем простой запрос для поиска полных дублей по строгому соответствию (например, по ИНН или КПП).
  3. Для найденных дублей (кроме «эталонного» объекта) установим специальный признак. Это может быть префикс в наименовании или пометка в поле Комментарий. Например, добавим текст «ДУБЛЬ_ГРУППА_1».
  4. Запустим типовую обработку, установив фильтр по этому комментарию.

Рассмотрим пример разделения по алфавиту, как наиболее простой и эффективный метод группировки:


// Пример логики разделения объектов для обработки
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Контрагенты.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    |	Контрагенты.Наименование ПОДОБНО &Буква";

Запрос.УстановитьПараметр("Буква", "А%");
Результат = Запрос.Выполнить().Выгрузить();
// Далее помечаем найденные объекты для порционной обработки

Технические хитрости для ускорения процесса замены ссылок

Когда мы приступаем к непосредственной замене дублей на «правильный» объект, система начинает переписывать ссылки во всех найденных документах и регистрах. Выясним, как ускорить этот процесс программно.

Использование флага ОбменДанными.Загрузка: Это критически важный момент. При программной записи объектов (документов, справочников) необходимо устанавливать свойство ОбменДанными.Загрузка = Истина. Это отключает все проверки в модулях объектов, такие как проверка остатков, пересчет сумм и контроль прав доступа. Без этого флага обработка 100 000 ссылок может затянуться на недели.

Порционная фиксация транзакций: Не пытайтесь заменить все ссылки в рамках одной транзакции. Это приведет к катастрофическому росту файла лога транзакций (LDF в SQL) и может остановить работу всей системы. Рекомендуется фиксировать транзакцию каждые 1000–5000 итераций.


// Пример правильной организации транзакций
Для Каждого Строка ИЗ МассивОбъектов Цикл
    НачатьТранзакцию();
    Попытка
        ОбъектДляЗаписи = Строка.Ссылка.ПолучитьОбъект();
        ОбъектДляЗаписи.ОбменДанными.Загрузка = Истина;
        // Логика замены ссылки...
        ОбъектДляЗаписи.Записать();
        ЗафиксироватьТранзакцию();
    Исключение
        ОтменитьТранзакцию();
        ЗаписатьЛогОшибки(ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;

Поиск дублей через SQL: экстремальная скорость

Проанализируем ситуацию, когда база данных находится на SQL-сервере. Самый быстрый способ найти идентификаторы (GUID) дублей — выполнить прямой запрос к таблице справочника. Например, по полю _Description (Наименование) или _FldXXXX (ИНН).

Результаты запроса можно выгрузить в таблицу 1С и передать в стандартные методы поиска ссылок. Это полностью исключает стадию медленного поиска средствами платформы и дает мгновенный результат по выявлению «кандидатов на удаление».

Бизнес-риски и последствия «склейки»

Важно понимать, что массовое удаление дублей — это не только техническая, но и методологическая задача. Рассмотрим основные риски, о которых часто забывают:

Рекомендация: Перед слиянием контрагентов обязательно проведите процедуру слияния их договоров и контактной информации. Только после того, как все подчиненные объекты будут перенесены на «мастер-объект», можно приступать к удалению самого контрагента.

Безопасное удаление объектов

Многие разработчики предлагают «экстремальный» вариант: удалить записи напрямую из базы данных или использовать метод Удалить() без контроля целостности, а затем запустить «Тестирование и исправление» (ТИИ). Мы категорически не рекомендуем этот метод. ТИИ создаст тысячи записей «Объект не найден», что окончательно превратит базу в «мусор».

Вместо этого разберем метод УдалитьОбъекты() с параметром проверки ссылочной целостности. Он работает быстрее интерактивного удаления, так как выполняет проверки на уровне платформы более эффективно:


// Безопасное программное удаление
МассивДляУдаления = Новый Массив;
// Заполняем массив ссылками, помеченными на удаление
УдаляемыеОбъекты = Справочники.Контрагенты.Выбрать();
Пока УдаляемыеОбъекты.Следующий() Цикл
    Если УдаляемыеОбъекты.ПометкаУдаления Тогда
        МассивДляУдаления.Добавить(УдаляемыеОбъекты.Ссылка);
    КонецЕсли;
КонецЦикла;

// МассивНеудаленныхОбъектов вернет ссылки, которые нельзя удалить из-за наличия связей
МассивНеудаленныхОбъектов = Новый Массив;
УдалитьОбъекты(МассивДляУдаления, Истина, МассивНеудаленныхОбъектов);

Подведем итог: работа с большими объемами дублей требует комбинированного подхода. Сначала мы группируем данные (по алфавиту или меткам), затем используем оптимизированный поиск ссылок (через ИР или SQL), и в финале производим аккуратную замену с отключением проверок. Только такая последовательность действий гарантирует сохранность данных и приемлемую скорость работы системы.

← На главную