Красивый код по загрузке иерархии
Гружу номенклатуру с сайта. Иерархия там задается полями category1-category6. Вот мой код, который создает группу, если не нашел ее по ID или наименованию, помещает номенклатуру в нужную группу и даже перемещает группы если их иерархия на сайте поменялась. При всей лаконичности кода он очень функционален:
//=== ЗАГРУЗКА ИЕРАРХИИ //Идем до первого незаполненного объекта-родителя idПредРодитель = 0; СсылкаПредРодитель = Неопределено; Для Инд = 1 По 6 + 1 Цикл Если Инд = 6 + 1 Тогда idРодитель = 0; Иначе idРодитель = ЧислоИзСтроки(ЭлементДанных["category" + Инд]); КонецЕсли; Если Не ЗначениеЗаполнено(idРодитель) Тогда Если ЗначениеЗаполнено(СсылкаПредРодитель) Тогда ПрисвоитьБезопасно(НоменклатураОбъект.Родитель, СсылкаПредРодитель); КонецЕсли; Прервать; Иначе //Переносим группы из группы в группу (а не только номенклатуру) НаименованиеГруппы = EntityValueByID(ТаблицаИерархииНоменклатуры, idРодитель); СсылкаРодитель = НайтиГруппуНоменклатурыПоИДНаименованию(ТаблицаИерархииНоменклатуры, idРодитель, НаименованиеГруппы); Если НЕ ЗначениеЗаполнено(СсылкаРодитель) Тогда ГО = Справочники.Номенклатура.СоздатьГруппу(); ГО.СайтИД = idРодитель; ГО.Наименование = НаименованиеГруппы; ГО.Записать(); СсылкаРодитель = ГО.Ссылка; КонецЕсли; Если ЗначениеЗаполнено(СсылкаРодитель) И ЗначениеЗаполнено(СсылкаПредРодитель) И СсылкаРодитель.Родитель <> СсылкаПредРодитель Тогда ГО = СсылкаРодитель.ПолучитьОбъект(); ПрисвоитьБезопасно(ГО.Родитель, СсылкаПредРодитель); Если ГО.Модифицированность() Тогда ГО.ОбменДанными.Загрузка = истина; ГО.Записать(); КонецЕсли; КонецЕсли; //Переходим к следующему уровню родителя СсылкаПредРодитель = СсылкаРодитель; КонецЕсли; КонецЦикла;
Поиск по ID или наименованию с приоритетом ID сделан запросом:
Функция НайтиГруппуНоменклатурыПоИДНаименованию(ТаблицаИерархииНоменклатуры, id, НаименованиеГруппы) Экспорт З = Новый Запрос( "ВЫБРАТЬ | Номенклатура.Ссылка КАК Ссылка |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.ЭтоГруппа | И Номенклатура.СайтИД = &СайтИД | |ОБЪЕДИНИТЬ | |ВЫБРАТЬ | Номенклатура.Ссылка |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.ЭтоГруппа | И Номенклатура.Наименование = &Наименование И &ЕстьНаименование" ); З.УстановитьПараметр("СайтИД", id); З.УстановитьПараметр("Наименование", НаименованиеГруппы); З.УстановитьПараметр("ЕстьНаименование", ЗначениеЗаполнено(НаименованиеГруппы)); Выборка = З.Выполнить().Выбрать(); Если Выборка.Следующий() Тогда Возврат Выборка.Ссылка; КонецЕсли; КонецФункции
Копрокод конечно местами, но для 1С пойдет
Отож. А что тебе не понравилось? По мне так изящно.
во втором методе:
1. первый параметр не нужен
2. нет никакого приоритета поиска в запросе, найдем по id или по наименованию
в первом:
1. Если НЕ ЗначениеЗаполнено(СсылкаРодитель) Тогда
…
СсылкаРодитель = ГО.Ссылка;
КонецЕсли;
Если ЗначениеЗаполнено(СсылкаРодитель) И //условие всегда выполняется и не нужно
2. «6 + 1» вынести в переменную, чтобы не дублировать
это если не вдаваться в специфику задачи
Приоритет есть. Если есть ID, первая запись будет по ID, соответственно, будет найдено по ID.
6+1 написал специально для наглядности, 1с константы компилирует заранее и константные выражения тоже.
Первый параметр да, сохранился ошибочно, я потом стал сразу наименование туда передавать, а параметр не убрал.
Спасибо за Code Review
6+1 без проблем, но зачем два раза? Можно было вынести и готово Предел = 6+1;
Приоритета всё таки нет гарантированного во втором методе.
Можно было, но это для перфекционистов. На мой взгляд в двух местах нагляднее. О переменную глаз не споткнется.