При импорте данных из Excel или других табличных документов с помощью стандартной обработки «Загрузка данных из табличного документа» часто возникает задача: необходимо загрузить позиции в табличную часть документа, но при этом избежать создания дубликатов элементов справочников. Рассмотрим, как правильно организовать загрузку номенклатуры и характеристик, если часть элементов уже существует в информационной базе, а часть — поступает впервые.
Проанализируем механику работы стандартной обработки. В режиме загрузки в табличную часть документа установка режима сопоставления «Искать» выполняет лишь поиск уже имеющихся ссылок. Если элемент не найден в справочнике, обработка в этом режиме не создаст новый объект автоматически, а оставит поле пустым. Если же выбран режим «Загружать», то при повторном запуске обработки система создаст дублирующие записи.
Отдельное внимание стоит обратить на справочник ХарактеристикиНоменклатуры. Этот справочник является подчиненным (владельцем выступает конкретный элемент номенклатуры или вид номенклатуры). Поэтому поиск и создание характеристик должны выполняться строго с учетом ссылки на владельца.
Выясним, как настроить программное выражение в режиме загрузки «Вычислить». Данный режим позволяет написать произвольный алгоритм на языке 1С, который выполняет поиск элемента в базе и, если объект отсутствует, программно создает его и возвращает ссылку в переменную Результат.
Разберем пример кода для поиска и автоматического создания номенклатуры по артикулу:
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ Артикул = &Артикул");
Запрос.УстановитьПараметр("Артикул", ТекстыЯчеек[2]);
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
НайденнаяЕдиницаОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НайденнаяЕдиницаОбъект.Наименование = ТекстыЯчеек[1];
НайденнаяЕдиницаОбъект.Артикул = ТекстыЯчеек[2];
НайденнаяЕдиницаОбъект.СтавкаНДС = Перечисления.СтавкиНДС.НДС18;
НайденнаяЕдиницаОбъект.ЕдиницаИзмерения = Справочники.БазовыеЕдиницыИзмерения.НайтиПоНаименованию("шт");
НайденнаяЕдиницаОбъект.ВидНоменклатуры = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Ювелирное изделие");
Попытка
НайденнаяЕдиницаОбъект.Записать();
Результат = НайденнаяЕдиницаОбъект.Ссылка;
Исключение
Сообщить("Не удалось записать номенклатуру: " + ОписаниеОшибки());
КонецПопытки;
Иначе
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
Результат = Выборка.Ссылка;
КонецЕсли;
Посмотрим на аналогичный алгоритм для подчиненного справочника характеристик. Для корректной работы характеристика должна быть жестко привязана к найденной номенклатуре (владельцу):
// Сначала получаем ссылку на владельца (Номенклатуру)
СсылкаНоменклатура = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", ТекстыЯчеек[2]);
Если ЗначениеЗаполнено(СсылкаНоменклатура) Тогда
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.ХарактеристикиНоменклатуры ГДЕ Владелец = &Владелец И Наименование = &Наименование");
Запрос.УстановитьПараметр("Владелец", СсылкаНоменклатура);
Запрос.УстановитьПараметр("Наименование", ТекстыЯчеек[3]);
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
ХарактеристикаОбъект = Справочники.ХарактеристикиНоменклатуры.СоздатьЭлемент();
ХарактеристикаОбъект.Владелец = СсылкаНоменклатура;
ХарактеристикаОбъект.Наименование = ТекстыЯчеек[3];
Попытка
ХарактеристикаОбъект.Записать();
Результат = ХарактеристикаОбъект.Ссылка;
Исключение
Сообщить("Не удалось записать характеристику: " + ОписаниеОшибки());
КонецПопытки;
Иначе
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
Результат = Выборка.Ссылка;
КонецЕсли;
КонецЕсли;
Рассмотренный выше метод с выполнением запроса на каждую строку файла хорошо подходит для небольших таблиц. Однако при импорте тысяч строк выполнение запросов в цикле может существенно замедлить процесс. В таких случаях эффективнее использовать двухэтапный порядок загрузки:
Номенклатура, установив ключевым полем поиска Артикул. После этого запустим импорт для справочника ХарактеристикиНоменклатуры, выбрав поиск по наименованию и владельцу. Обработка самостоятельно сопоставит имеющиеся позиции и создаст отсутствующие.ПоступлениеТоваров). Для реквизитов Номенклатура и Характеристика установим режим сопоставления «Искать». Так как все элементы уже гарантированно созданы на первом этапе, документ заполнится быстро и без дублей.Проанализируем технические нюансы, которые следует учитывать при использовании пользовательских скриптов:
ТекстыЯчеек[2] требует строгого контроля порядка колонок в файле поставщика. При изменении структуры столбцов код запишет некорректные данные.СоздатьЭлемент() обязательно заполняйте все реквизиты, необходимые для логики вашей конфигурации (базовая единица измерения, вид номенклатуры, ставка НДС).