В процессе разработки часто возникает задача массового обновления данных, например, актуализация кодов КодТНВЭД для номенклатуры. Начинающие разработчики часто сталкиваются с проблемой производительности, когда поиск нужных элементов справочника выполняется непосредственно внутри цикла Для каждого. Давайте разберем, как перенести логику поиска в запрос и сделать код эффективным.
Использование метода НайтиПоНаименованию() или аналогичных функций внутри цикла приводит к выполнению отдельного запроса к базе данных на каждой итерации. Если у вас в таблице тысячи записей, выполнение такой процедуры может растянуться на минуты или даже часы. Это создает лишнюю нагрузку на сервер 1С и SQL-сервер, а также блокирует работу пользователей.
Самым правильным подходом является перенос всей логики сопоставления данных в текст запроса. Благодаря механизму ЛЕВОЕ СОЕДИНЕНИЕ, мы можем получить все необходимые ссылки на объекты за один проход, что значительно ускоряет выполнение задачи.
Рассмотрим, как это реализовать:
времтаб, содержащую штрихкоды и коды ТНВЭД из вашего источника данных.КлассификаторТНВЭД по полю Наименование. Это позволит получить не просто строку, а готовую ссылку на элемент справочника.ШтрихкодыНоменклатуры, чтобы найти нужную Номенклатура.Давайте посмотрим, как может выглядеть оптимизированный запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| времтаб.ШтрихКод КАК ШтрихКод,
| КлассификаторТНВЭД.Ссылка КАК КодТНВЭДСсылка,
| ШтрихкодыНоменклатуры.Номенклатура КАК Номенклатура
|ПОМЕСТИТЬ ВТ
|ИЗ
| времтаб КАК времтаб
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.КлассификаторТНВЭД КАК КлассификаторТНВЭД
| ПО времтаб.КодТНВЭД = КлассификаторТНВЭД.Наименование
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры
| ПО времтаб.ШтрихКод = ШтрихкодыНоменклатуры.Штрихкод
|;
|ВЫБРАТЬ
| ВТ.Номенклатура,
| ВТ.КодТНВЭДСсылка
|ИЗ
| ВТ КАК ВТ
|ГДЕ
| ВТ.Номенклатура ЕСТЬ НЕ NULL";
Запрос.УстановитьПараметр("Таб", Таб);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
После получения результата в таблице значений, мы обходим её циклом и выполняем запись только тех объектов, у которых код ТНВЭД действительно требует изменения.
Обратите внимание на использование свойства ОбменДанными.Загрузка. Оно позволяет избежать срабатывания лишних проверок и бизнес-логики, что критически важно при массовом обновлении номенклатуры.
Для Каждого СтрокаТЗ Из РезультатЗапроса Цикл
ОбъектНоменклатура = СтрокаТЗ.Номенклатура.ПолучитьОбъект();
Если ОбъектНоменклатура.КодТНВЭД <> СтрокаТЗ.КодТНВЭДСсылка Тогда
ОбъектНоменклатура.КодТНВЭД = СтрокаТЗ.КодТНВЭДСсылка;
ОбъектНоменклатура.ОбменДанными.Загрузка = Истина;
ОбъектНоменклатура.Записать();
КонецЕсли;
КонецЦикла;
ГДЕ КодТНВЭД = ПустаяСсылка. В реальности вам может потребоваться обновить даже те элементы, у которых код уже заполнен, если он не совпадает с данными из вашей таблицы.НачатьТранзакцию() и ЗафиксироватьТранзакцию().Применяя данные методы, вы не только решите проблему с поиском КодТНВЭД, но и значительно повысите общую производительность вашей обработки.