Красивый код по загрузке иерархии

Гружу номенклатуру с сайта. Иерархия там задается полями category1-category6. Вот мой код, который создает группу, если не нашел ее по ID или наименованию, помещает номенклатуру в нужную группу и даже перемещает группы если их иерархия на сайте поменялась. При всей лаконичности кода он очень функционален:

//=== ЗАГРУЗКА ИЕРАРХИИ

//Идем до первого незаполненного объекта-родителя
idПредРодитель = 0;
СсылкаПредРодитель = Неопределено;
Для Инд = 1 По 6 + 1 Цикл
	Если Инд = 6 + 1 Тогда
		idРодитель = 0;
	Иначе
		idРодитель = ЧислоИзСтроки(ЭлементДанных["category" + Инд]); 
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(idРодитель) Тогда
		Если ЗначениеЗаполнено(СсылкаПредРодитель) Тогда
			ПрисвоитьБезопасно(НоменклатураОбъект.Родитель, СсылкаПредРодитель); 
		КонецЕсли;
		Прервать;
	Иначе
		//Переносим группы из группы в группу  (а не только номенклатуру)
		НаименованиеГруппы = EntityValueByID(ТаблицаИерархииНоменклатуры, idРодитель);
		СсылкаРодитель = НайтиГруппуНоменклатурыПоИДНаименованию(ТаблицаИерархииНоменклатуры, idРодитель, НаименованиеГруппы);
		Если НЕ ЗначениеЗаполнено(СсылкаРодитель) Тогда
			ГО = Справочники.Номенклатура.СоздатьГруппу();
			ГО.СайтИД = idРодитель;
			ГО.Наименование = НаименованиеГруппы;
			ГО.Записать();
			СсылкаРодитель = ГО.Ссылка;
		КонецЕсли;
		
		Если ЗначениеЗаполнено(СсылкаРодитель) И 
			ЗначениеЗаполнено(СсылкаПредРодитель) И
			СсылкаРодитель.Родитель <> СсылкаПредРодитель
			Тогда
			ГО = СсылкаРодитель.ПолучитьОбъект();
			ПрисвоитьБезопасно(ГО.Родитель, СсылкаПредРодитель);
			Если ГО.Модифицированность() Тогда
				ГО.ОбменДанными.Загрузка = истина;
				ГО.Записать();
			КонецЕсли;
		КонецЕсли;
		
		//Переходим к следующему уровню родителя
		СсылкаПредРодитель = СсылкаРодитель; 
	КонецЕсли;
	
КонецЦикла;

Поиск по ID или наименованию с приоритетом ID сделан запросом:

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

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

комментариев 6

  1. rzd:

    Копрокод конечно местами, но для 1С пойдет

    • Отож. А что тебе не понравилось? По мне так изящно.

      • rzd:

        во втором методе:
        1. первый параметр не нужен
        2. нет никакого приоритета поиска в запросе, найдем по id или по наименованию

        в первом:
        1. Если НЕ ЗначениеЗаполнено(СсылкаРодитель) Тогда

        СсылкаРодитель = ГО.Ссылка;
        КонецЕсли;

        Если ЗначениеЗаполнено(СсылкаРодитель) И //условие всегда выполняется и не нужно

        2. «6 + 1» вынести в переменную, чтобы не дублировать

        это если не вдаваться в специфику задачи

        • Приоритет есть. Если есть ID, первая запись будет по ID, соответственно, будет найдено по ID.
          6+1 написал специально для наглядности, 1с константы компилирует заранее и константные выражения тоже.
          Первый параметр да, сохранился ошибочно, я потом стал сразу наименование туда передавать, а параметр не убрал.
          Спасибо за Code Review

  2. rzd:

    6+1 без проблем, но зачем два раза? Можно было вынести и готово Предел = 6+1;

    Приоритета всё таки нет гарантированного во втором методе.

    • Можно было, но это для перфекционистов. На мой взгляд в двух местах нагляднее. О переменную глаз не споткнется.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *