В процессе работы с базами данных 1С часто возникает задача дублирования структуры справочников. Особенно это актуально для справочника Контрагенты, где структура может включать сотни папок и тысячи элементов. Стандартная кнопка «Копировать» в интерфейсе 1С копирует только текущий объект (либо только саму папку, либо только один элемент), не затрагивая вложенную иерархию. Разберем подробно, как решить эту задачу программно и с помощью стандартных инструментов.
При копировании ветки справочника с вложенными элементами мы сталкиваемся с несколькими техническими сложностями:
Родитель не перенесет эти данные автоматически.Рассмотрим два основных пути решения: использование внешней обработки с программным кодом и применение средств конвертации данных.
Для корректного переноса иерархии лучше всего использовать рекурсивную функцию. Она будет заходить в каждую папку, создавать её копию и вызывать саму себя для всех элементов внутри этой папки. Разберем пример реализации, который можно разместить во внешней обработке.
Сначала рассмотрим основной метод, который инициирует процесс:
Процедура ВыполнитьКопированиеГруппы(ИсходнаяГруппаСсылка, НовыйРодитель)
// 1. Создаем копию текущей группы
НоваяГруппаОбъект = ИсходнаяГруппаСсылка.Скопировать();
НоваяГруппаОбъект.Родитель = НовыйРодитель;
// Можно очистить код, чтобы он сгенерировался автоматически при записи
НоваяГруппаОбъект.Код = "";
НоваяГруппаОбъект.Записать();
НоваяГруппаСсылка = НоваяГруппаОбъект.Ссылка;
// 2. Выбираем все элементы и группы, входящие в исходную группу
Выборка = Справочники.Контрагенты.Выбрать(ИсходнаяГруппаСсылка, , , "Наименование Возр");
Пока Выборка.Следующий() Цикл
Если Выборка.ЭтоГруппа Тогда
// Если это вложенная папка - вызываем эту же процедуру (рекурсия)
ВыполнитьКопированиеГруппы(Выборка.Ссылка, НоваяГруппаСсылка);
Иначе
// Если это элемент - просто копируем его
НовыйЭлементОбъект = Выборка.Ссылка.Скопировать();
НовыйЭлементОбъект.Родитель = НоваяГруппаСсылка;
НовыйЭлементОбъект.Код = "";
НовыйЭлементОбъект.Записать();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Проанализируем этот код. Мы используем метод Скопировать(), который позволяет сохранить все заполненные реквизиты (ИНН, КПП, основной менеджер и т.д.), кроме уникального идентификатора. Важным моментом является передача НоваяГруппаСсылка в качестве родителя для всех вложенных объектов. Это гарантирует, что структура будет в точности дублировать оригинал.
Если элементов много, как указано в обсуждении (более 5000), необходимо оптимизировать процесс записи, чтобы избежать проблем с производительностью. Выясним, как ускорить работу:
ОбменДанными.Загрузка = Истина позволяет проигнорировать прикладные проверки в модуле объекта, что значительно ускоряет запись.Посмотрим на модифицированный фрагмент кода для записи элемента:
НовыйЭлементОбъект = Выборка.Ссылка.Скопировать();
НовыйЭлементОбъект.Родитель = НоваяГруппаСсылка;
// Отключаем проверки для ускорения
НовыйЭлементОбъект.ОбменДанными.Загрузка = Истина;
НовыйЭлементОбъект.Записать();
Проблема простого копирования справочника Контрагенты заключается в том, что его договоры и банковские счета хранятся в других справочниках, где поле Владелец ссылается на контрагента. При программном копировании самого контрагента эти записи не дублируются автоматически.
Рассмотрим, как можно доработать код для копирования договоров:
Процедура СкопироватьДоговоры(СтарыйВладелец, НовыйВладелец)
ВыборкаДоговоров = Справочники.ДоговорыКонтрагентов.Выбрать(, СтарыйВладелец);
Пока ВыборкаДоговоров.Следующий() Цикл
НовыйДоговор = ВыборкаДоговоров.Ссылка.Скопировать();
НовыйДоговор.Владелец = НовыйВладелец;
НовыйДоговор.Записать();
КонецЦикла;
КонецПроцедуры
Эту процедуру необходимо вызывать сразу после записи нового элемента контрагента. Аналогичную логику следует реализовать для справочника БанковскиеСчета и контактной информации (если она хранится не в табличной части, а в регистре сведений).
Если задача разовая и программирование кажется сложным, можно воспользоваться стандартной обработкой "Универсальный обмен данными в формате XML". Рассмотрим этот сценарий подробнее:
Конвертация данных 2.1.Контрагенты с фильтром по конкретной группе.Однако, как справедливо заметили участники форума, для новичка этот путь может оказаться сложнее, чем написание небольшого скрипта, так как требует понимания логики работы GUID в 1С.
Выясним итоговый алгоритм действий для успешного копирования иерархии:
ГруппаИсточник (СправочникСсылка.Контрагенты) и ГруппаПриемник (СправочникСсылка.Контрагенты).Записать() для групп, иначе иерархия не будет создана (сообщение №27 на форуме).При правильном подходе программное создание дубля ветки справочника занимает не более 30 минут разработки и гарантирует чистоту данных в системе.