Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Получить список групп номенклатуры всех уровней (число прочтений - 2529 )
es3000
God Member
*****
Отсутствует



Сообщений: 536
Зарегистрирован: 10. Июля 2006
Получить список групп номенклатуры всех уровней
22. Октября 2019 :: 13:39
Печать  
В результате нескольких запросов получили временную таблицу #Tovar, в которой содержатся товары, которые надо вывести в отчет.
Но их надо вывести с учетом иерархии групп, как в типовых отчетах.
Количество уровней в справочнике товаров - 5.

Как наиболее быстро и удобно получить группы с подгруппами для этих товаров и вывести в отчет?
  
Наверх
ICQ  
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Получить список групп номенклатуры всех уровней
Ответ #1 - 22. Октября 2019 :: 13:54
Печать  
я обычно использую ИТ
  

1&&2&&3
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Получить список групп номенклатуры всех уровней
Ответ #2 - 22. Октября 2019 :: 13:56
Печать  
есть вот такой шаблон кода:
Код
Выбрать все
Перем мВсегоПозиций, мТекСтрока;

//*******************************************
Процедура ВывестиИерархию(Таб, ИТ, Отступ = "")

	ИТ.ВыбратьСтроки("индПорядок");
	Пока ИТ.ПолучитьСтроку("индПорядок") = 1 Цикл
		Если ИТ.__ЭтоГруппа__ = 1 Тогда
			ПечНаименование = Отступ + ИТ.Наименование;
			Если ИТ.__Уровень__ = 1 Тогда
				ИмяСекции = "Группа1уровня";
			Иначе
				ИмяСекции = "Группа";
			КонецЕсли;
			Таб.ВывестиСекцию(ИмяСекции);
			ВывестиИерархию(Таб, ИТ.тзПотомки, Отступ + " ");
		Иначе
			мТекСтрока = мТекСтрока + 1;
			Если мТекСтрока % 10 = 0 Тогда
				Состояние("Вывод... " + Цел(мТекСтрока / мВсегоПозиций * 100) + "%");
			КонецЕсли;
			ПечНаименование = ИТ.Наименование;
			Таб.ВывестиСекцию("Строка");
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры


//*******************************************
Процедура ОбработатьИерархию(ИТ)

	ИТ.ВыбратьСтроки();
	Пока ИТ.ПолучитьСтроку() = 1 Цикл
		Если ИТ.__ЭтоГруппа__ = 1 Тогда
			ИТ.Наименование = ИТ.Ссылка.Наименование;
			ОбработатьИерархию(ИТ.тзПотомки);
		КонецЕсли;
	КонецЦикла;
	ИТ.ДобавитьИндекс("индПорядок", "Наименование");

КонецПроцедуры


//*******************************************
Процедура Сформировать()

	РезИТ = СоздатьОбъект("ИндексированнаяТаблица");

	// тут получение данных в ИТ
	//в данных должно быть поле Ссылка
	//желательно наличие поля Ссылка_Родитель

	мВсегоПозиций = РезИТ.КоличествоСтрок();
	Если мВсегоПозиций = 0 Тогда
		Возврат;
	КонецЕсли;

	РезИТ.Группировать("Ссылка:Ссылка*&", , 0);
	ОбработатьИерархию(РезИТ);

	Таб = СоздатьОбъект("Таблица");
	//Таб.ИсходнаяТаблица();
	Таб.ВывестиСекцию("Шапка");
	Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0, "Печать", "Окно");
	Таб.ПовторятьПриПечатиСтроки(Таб.ВысотаТаблицы(), Таб.ВысотаТаблицы());

	мТекСтрока=0;
	ВывестиИерархию(Таб, РезИТ);

	Таб.ВывестиСекцию("Подвал");
	Таб.ТолькоПросмотр(1);
	//Таб.ПараметрыСтраницы();
	Таб.Показать();

КонецПроцедуры
 

  

1&&2&&3
Наверх
 
IP записан
 
es3000
God Member
*****
Отсутствует



Сообщений: 536
Зарегистрирован: 10. Июля 2006
Re: Получить список групп номенклатуры всех уровней
Ответ #3 - 22. Октября 2019 :: 14:44
Печать  
Понял, спасибо!

А как теперь добавить группы?
В моей временной таблице есть только товары с нужными данными без групп.
Имеется ввиду, что это временная SQL-таблица.

Получается, сначала в нее надо как-то группы добавить.

Можно ли написать такой SQL-запрос, чтобы он за один раз выбрал все группы с учетом иерархии?
Или придется в цикле по каждому уровню группы делать отдельные запросы?

  
Наверх
ICQ  
IP записан
 
es3000
God Member
*****
Отсутствует



Сообщений: 536
Зарегистрирован: 10. Июля 2006
Re: Получить список групп номенклатуры всех уровней
Ответ #4 - 22. Октября 2019 :: 14:49
Печать  
А что делает модификатор '&'?
  
Наверх
ICQ  
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Получить список групп номенклатуры всех уровней
Ответ #5 - 23. Октября 2019 :: 07:18
Печать  
модификатор '&' - как раз создает иерархию в ИТ из плоской таблицы без групп
  

1&&2&&3
Наверх
 
IP записан
 
es3000
God Member
*****
Отсутствует



Сообщений: 536
Зарегистрирован: 10. Июля 2006
Re: Получить список групп номенклатуры всех уровней
Ответ #6 - 23. Октября 2019 :: 09:58
Печать  
trad писал(а) 23. Октября 2019 :: 07:18:
модификатор '&' - как раз создает иерархию в ИТ из плоской таблицы без групп


Он обращается к базе и "вытягивает" оттуда группы?
Если да, то интересно как он это делает, насколько эффективно и быстро?
Если одним запросом все группы читает - то хорошо.

А если по одной (типа через реквизит Номенклатура.Родитель) - то это долго будет.



  
Наверх
ICQ  
IP записан
 
es3000
God Member
*****
Отсутствует



Сообщений: 536
Зарегистрирован: 10. Июля 2006
Re: Получить список групп номенклатуры всех уровней
Ответ #7 - 23. Октября 2019 :: 10:02
Печать  
В примере есть комментарий:
//желательно наличие поля Ссылка_Родитель

Это поле нужно для метода "Группировать"?
  
Наверх
ICQ  
IP записан
 
Djelf
God Member
*****
Отсутствует


Ubuntu + wine@etersoft
+ 1C 7.7

Сообщений: 631
Местоположение: Питер
Зарегистрирован: 02. Ноября 2007
Пол: Мужской
Re: Получить список групп номенклатуры всех уровней
Ответ #8 - 23. Октября 2019 :: 15:43
Печать  
Группы вытягиваются одним запросом:
Код (C++)
Выбрать все
	// Соорудим временную таблицу для групп
	CValue vVTGroups;
	vVTGroups.CreateObject("IndexedTable");
	CVTExtended* pVTGroups = CValue2VTExt(vVTGroups);
	pVTGroups->LoadStructure(this);

	// Проиндексируем по колонке группы
	CString sIndexExpr(ColumnName(nRefCol));
	sIndexExpr += "*"; //сортировать будем по внутреннему представлению
	CVTExtIndex* pGrpIndex = pVTGroups->DefaultIndex;
	pGrpIndex->Reindex( sIndexExpr );
 



"Ссылка_Родитель" нужна для избежания лишних телодвижений, т.е. если Справочник.ЧтоТоТам в запросе есть, то извлечение PARENTID из него это быстро, а вот получить из каждой строки PARENTID, чуток медленнее, но при условии его типизации это почти нивелируется.

Насколько эффективно проверь сам.
  
Наверх
www  
IP записан
 
es3000
God Member
*****
Отсутствует



Сообщений: 536
Зарегистрирован: 10. Июля 2006
Re: Получить список групп номенклатуры всех уровней
Ответ #9 - 24. Октября 2019 :: 08:15
Печать  
Djelf писал(а) 23. Октября 2019 :: 15:43:
... а вот получить из каждой строки PARENTID, чуток медленнее, но при условии его типизации это почти нивелируется.


Где должна быть задана эта типизация?
И кто ее должен задать?
  
Наверх
ICQ  
IP записан
 
Djelf
God Member
*****
Отсутствует


Ubuntu + wine@etersoft
+ 1C 7.7

Сообщений: 631
Местоположение: Питер
Зарегистрирован: 02. Ноября 2007
Пол: Мужской
Re: Получить список групп номенклатуры всех уровней
Ответ #10 - 24. Октября 2019 :: 09:27
Печать  
Да не задумывайся ты, не так уж и важно как оно внутри работает.
Просто вытаскивай в запросе Ссылка_Родитель для группировки по группам, вот и все что требуется для ускорения.

Про типизацию я что-то загнул, вечер все таки...
  
Наверх
www  
IP записан
 
es3000
God Member
*****
Отсутствует



Сообщений: 536
Зарегистрирован: 10. Июля 2006
Re: Получить список групп номенклатуры всех уровней
Ответ #11 - 25. Октября 2019 :: 07:40
Печать  
Djelf писал(а) 24. Октября 2019 :: 09:27:
Просто вытаскивай в запросе Ссылка_Родитель для группировки по группам, вот и все что требуется для ускорения.


Даже если для каждой строки ИТ (для каждого элемента справочника в колонке Ссылка) будет иметься Ссылка_Родитель, то этого все равно будет недостаточно.
Так как у каждой группы (Ссылка_Родитель) есть свой "Родитель", то есть своя родительская группа.
А этих данных (родительских групп для Ссылка_Родитель) в ИТ уже не будет, потому что каждая строка ИТ содержит только элементы справочника.

То есть по любому при группировке ИТ по группам, метод "Группировать" должен обратиться к базе данных, чтобы вытащить оттуда полную иерархию групп.
Правильно я понимаю?


  
Наверх
ICQ  
IP записан
 
Djelf
God Member
*****
Отсутствует


Ubuntu + wine@etersoft
+ 1C 7.7

Сообщений: 631
Местоположение: Питер
Зарегистрирован: 02. Ноября 2007
Пол: Мужской
Re: Получить список групп номенклатуры всех уровней
Ответ #12 - 25. Октября 2019 :: 08:10
Печать  
Иерархия вытягивается отдельно.
Там вообще все довольно хитро сделано.
Посмотри лучше сам: https://github.com/trdm/alterplast/blob/ae63cff603051d50461995152af2e6d7940a3d7d...
Только сохрани в файл, там ascii, поэтому комментарии и не видать.
  
Наверх
www  
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Получить список групп номенклатуры всех уровней
Ответ #13 - 25. Октября 2019 :: 08:35
Печать  
Тебе нужно получить плоскую таблицу
в которой есть поля Ссылка (тут элементы) и Ссылка_Родитель (где родитель элемента)
Далее вызвать метод Группировать с модификатором & на колонке Ссылка
Этот метод построит всю иерархию, до самого верха. Все родители будут получены дополнительным запросом.
Наличие поля Ссылка_Родитель (если его можно получить в первичной выборке, то это нужно сделать) сократит время на получение родителей при построении иерархии
  

1&&2&&3
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Получить список групп номенклатуры всех уровней
Ответ #14 - 25. Октября 2019 :: 08:37
Печать  
  

1&&2&&3
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать