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