Как перенести номенклатуру в другую группу с сохранением иерархии папок

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

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

Понимание иерархии в 1С: Реквизит Родитель

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

Следовательно, задача «перенести в другую группу» технически сводится к изменению значения реквизита Родитель. Однако сложность заключается в том, что при простом перемещении элементов в одну общую папку иерархия «рассыплется». Чтобы ее сохранить, нам нужно либо перемещать саму «головную» группу, либо воссоздавать структуру папок в целевом месте.

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

Проанализируем самый простой вариант, доступный пользователю. Если вам нужно переместить целые группы вместе со всем содержимым, платформа позволяет сделать это без программирования.

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

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

Способ 2. Стандартная обработка «Универсальный подбор и обработка объектов»

Если задача сложнее (например, нужно перенести не всю папку, а только определенные товары, но раскидать их по таким же папкам в новом месте), рассмотрим использование мощного инструмента с диска ИТС — обработки Универсальный подбор и обработка объектов.

Разберем по шагам, как работать с этим инструментом:

  1. Запустим обработку и выберем объект поиска — справочник Номенклатура.
  2. Настроим отбор. Выясним критерии: это могут быть товары из определенного списка, документы или товары с конкретными свойствами.
  3. На вкладке «Обработки» выберем пункт Установка реквизитов.
  4. Найдем реквизит Родитель и укажем новую группу.

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

Способ 3. Программный перенос с автоматическим созданием структуры групп

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

Проанализируем пример кода, который копирует структуру папок. Это полезно, если вы хотите сначала создать «скелет» в новом месте, а затем перенести туда товары.


Процедура КопироватьИерархиюГрупп(ИсходнаяГруппа, НоваяГруппаРодитель)
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Номенклатура.Ссылка КАК Ссылка,
        |   Номенклатура.Наименование КАК Наименование,
        |   Номенклатура.Родитель КАК Родитель
        |ИЗ
        |   Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |   Номенклатура.Ссылка В ИЕРАРХИИ(&Ссылка)
        |   И Номенклатура.ЭтоГруппа = ИСТИНА";
    
    Запрос.УстановитьПараметр("Ссылка", ИсходнаяГруппа);
    РезультатЗапроса = Запрос.Выполнить().Выгрузить();
    
    // Сначала создаем копии групп
    Для Каждого Строка Из РезультатЗапроса Цикл
        НоваяПапка = Справочники.Номенклатура.СоздатьГруппу();
        НоваяПапка.Наименование = Строка.Наименование;
        // Здесь логика определения родителя для новой папки
        // ...
        НоваяПапка.Записать();
    КонецЦикла;
КонецПроцедуры

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


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

// 1 этап: Создаем структуру папок
Для Каждого Стр Из ТЗ Цикл
    Если Стр.ЭтоГруппа Тогда
        НоваяГруппа = Справочники.Номенклатура.СоздатьГруппу();
        НоваяГруппа.Наименование = Стр.СтараяСсылка.Наименование;
        // Логика установки родителя...
        НоваяГруппа.Записать();
        Стр.НоваяСсылка = НоваяГруппа.Ссылка;
    КонецЕсли;
КонецЦикла;

Способ 4. Современный инструмент «Групповое изменение реквизитов»

В конфигурациях на управляемых формах (УТ 11, БП 3.0, ERP) встроен мощный механизм Групповое изменение реквизитов. Выясним, как им воспользоваться для нашей задачи:

  1. Перейдем в раздел «Администрирование» — «Обслуживание» — «Корректировка данных».
  2. Выберем справочник Номенклатура.
  3. Нажмем «Добавить условие отбора». Здесь мы можем выбрать товары, например, входящие в определенный документ (как спрашивал автор темы про документ установки ассортимента).
  4. В списке реквизитов найдем Родитель и в колонке «Новое значение» выберем целевую папку.

Важно: этот метод идеален, если вы переносите товары из разных папок в ОДНУ общую. Но если нужно сохранить вложенность, этот инструмент придется запускать итерационно для каждой подпапки, что может быть неудобно для 6500 позиций.

Критически важные рекомендации при массовом переносе

Разберем основные риски, которые возникают при работе с таким объемом данных (6500 позиций):

1. Счета учета номенклатуры. В программах типа «1С:Бухгалтерия» счета учета (41.01, 10.01 и др.) часто привязаны не к конкретным товарам, а к папкам (группам). Если вы переносите товары из папки «Материалы» в папку «Товары», их бухгалтерское поведение в новых документах может измениться. Проанализируйте регистр сведений Счета учета номенклатуры перед переносом.

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


НачатьТранзакцию();
Попытка
    Для Каждого Элемент Из СписокПереноса Цикл
        ОбъектНом = Элемент.ПолучитьОбъект();
        ОбъектНом.Родитель = НоваяГруппа;
        ОбъектНом.Записать();
    КонецЦикла;
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    Сообщить("Ошибка при переносе: " + ОписаниеОшибки());
КонецПопытки;

3. Обмены данными. Если ваша база синхронизируется с сайтом или другой программой, массовое изменение родителя у 6500 товаров пометит их все как «измененные». Это вызовет огромную очередь выгрузки. Чтобы этого избежать, используйте свойство ОбменДанными.Загрузка = Истина при записи объекта в коде.

Резюме

Для решения задачи автора темы наиболее эффективным будет сочетание методов. Если новые папки еще не созданы, используйте программный скрипт для копирования иерархии (аналогичный коду из Сообщения 13). Если же задача разово переместить отобранные товары в существующую структуру, воспользуйтесь стандартной обработкой Универсальный подбор и обработка объектов. Всегда выполняйте такие операции сначала на копии базы, чтобы убедиться в сохранении ссылочной целостности и корректности отчетов после перемещения.

← На главную