Загрузка данных из внешних файлов — это повседневная задача для технического специалиста 1С, особенно при внедрении систем класса ERP или Управление торговлей 11. Одной из главных сложностей здесь является сохранение иерархии: как сделать так, чтобы программа не просто «вывалила» все товары в корень справочника, а аккуратно распределила их по папкам, создав недостающие группы? В этой статье мы разберем несколько проверенных способов решения этой задачи, проанализируем программную логику создания групп и выясним, какие нюансы конфигурации 1С:ERP следует учитывать.
В современных конфигурациях на базе БСП (Библиотеки стандартных подсистем), таких как 1С:ERP, встроен мощный инструмент загрузки. Найти его можно в разделе НСИ и администрирование — Сервис — Загрузка данных из файла. Рассмотрим алгоритм работы с этим инструментом для иерархических данных.
Для того чтобы система корректно определила родительскую группу, в вашем файле Excel должна быть колонка «Группа» или «Родитель». Проанализируем важный момент: стандартный механизм ищет группу по наименованию. Если в вашем справочнике Номенклатура существуют две группы с одинаковым названием в разных ветках (например, «Расходники» в разделе «Принтеры» и «Расходники» в разделе «Автосервис»), система может ошибиться.
Чтобы избежать ошибок, мы рекомендуем следующий порядок действий:
Родитель в 1С.Если стандартного функционала недостаточно (например, когда иерархия в Excel представлена не отдельной колонкой, а «ступеньками»), мы можем использовать универсальную обработку «Загрузка данных из табличного документа». Она позволяет написать алгоритм на языке 1С, который будет выполняться для каждой строки файла. Разберем, как программно реализовать поиск и создание родителя.
Посмотрим на пример кода, который проверяет наличие группы и создает её в случае отсутствия. Этот фрагмент можно вставить в поле «При записи» или в обработчик событий колонки:
// Определим переменную для хранения найденного родителя
ИмяГруппы = ТекстыЯчеек[НомерКолонкиСГруппой];
РодительОбъект = Справочники.Номенклатура.НайтиПоНаименованию(ИмяГруппы, Истина);
Если РодительОбъект.Пустая() Тогда
// Группа не найдена, создаем новую
НоваяГруппа = Справочники.Номенклатура.СоздатьГруппу();
НоваяГруппа.Наименование = ИмяГруппы;
// Для ERP критично указать вид номенклатуры, если это требуется настройками
НоваяГруппа.Записать();
РодительОбъект = НоваяГруппа.Ссылка;
КонецЕсли;
// Устанавливаем найденного родителя текущему объекту
Объект.Родитель = РодительОбъект;
Рассмотрим подробнее этот код. Функция НайтиПоНаименованию с параметром Истина ищет только среди групп (если в метаданных справочника установлено использование папок). Однако в многоуровневых структурах лучше использовать рекурсивный поиск по всей цепочке вложенности.
Часто поставщики присылают прайс-листы, где группы не указаны в каждой строке, а идут отдельными строками-заголовками выше товаров. Проанализируем, как автоматизировать загрузку такой структуры. Здесь нам понадобится алгоритм «памяти» текущей группы.
Разберем логику по шагам:
ТекущийРодитель вне цикла обхода строк.ТекущийРодитель.Родитель = ТекущийРодитель.Пример реализации логики «Запоминания» группы:
Перем ТекущийРодитель;
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
Если ЗначениеЗаполнено(СтрокаТЗ.Артикул) Тогда
// Это товар, создаем или обновляем
ЭлементНоменклатуры = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", СтрокаТЗ.Артикул);
Если ЭлементНоменклатуры.Пустая() Тогда
НовыйОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НовыйОбъект.Наименование = СтрокаТЗ.Наименование;
НовыйОбъект.Родитель = ТекущийРодитель;
НовыйОбъект.Записать();
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(СтрокаТЗ.Наименование) Тогда
// Похоже, это строка с названием группы
ТекущийРодитель = Справочники.Номенклатура.НайтиПоНаименованию(СтрокаТЗ.Наименование, Истина);
Если ТекущийРодитель.Пустая() Тогда
НоваяПапка = Справочники.Номенклатура.СоздатьГруппу();
НоваяПапка.Наименование = СтрокаТЗ.Наименование;
НоваяПапка.Записать();
ТекущийРодитель = НоваяПапка.Ссылка;
КонецЕсли;
КонецЕсли;
КонецЦикла;
При работе с 1С:ERP нельзя забывать о реквизите ВидНоменклатуры. В этой конфигурации справочник номенклатуры жестко типизирован. Выясним причину, по которой это важно для иерархии:
Во-первых, если вы создаете группу программно, желательно сразу определить, какие виды номенклатуры будут в ней находиться. В настройках справочника часто стоит ограничение на использование определенных видов в конкретных папках.
Во-вторых, если вы используете автоматическое создание групп, убедитесь, что у пользователя, под которым запускается загрузка, достаточно прав не только на создание элементов, но и на создание групп (это разные права в профилях безопасности ERP).
Проанализируем также вопрос производительности. При загрузке иерархии из Excel объемом более 10 000 строк использование НайтиПоНаименованию в каждой строке существенно замедлит процесс. В таких случаях мы рекомендуем предварительно выгрузить все существующие группы в Соответствие (кэш), где ключом будет имя группы, а значением — её ссылка. Это позволит обращаться к памяти сервера, а не к базе данных при каждой итерации.
Подведем итог: для простой загрузки достаточно штатной обработки БСП. Для сложных иерархических прайсов лучше написать небольшой скрипт с использованием Справочники.Номенклатура.СоздатьГруппу() и логикой отслеживания текущего родителя. Это гарантирует порядок в справочнике и корректную работу системы в дальнейшем.