Соединение в запросе, сравнение (В ИЕРАРХИИ)

18.12.11

Разработка - Запросы

Иногда требуется, в запросе, в соединении, найти какую то общую иерархию... например, есть два списка элементов номенклатуры, эти два списка надо объеденить по общему родителю, если он есть, причем этот неизвестно как высоко стоит этот родитель.

Как вариант можно перебрать родителей через ИЛИ, например так


Номенклатура.Родитель = Номенклатура1.Ссылка
    ИЛИ Номенклатура.Родитель.Родитель = Номенклатура1.Ссылка
    ИЛИ Номенклатура.Родитель.Родитель.Родитель = Номенклатура1.Ссылка
    ИЛИ Номенклатура.Родитель.Родитель.Родитель.Родитель = Номенклатура1.Ссылка


Только здесь глубина родителей конечна, если же непонятно какую глубину имеет справочник, то можно это решить так
выгрузить родителей вообще в таблицу значений в две колонки,
в одной родитель, а во второй все возможные его родители (по количеству родителей количество строк в таблице значений
полученную таблицу использовать для соедениения

Скачать исходный код

Наименование Файл Версия Размер
Пример группировки
.epf 8,85Kb
33
.epf 8,85Kb 33 Скачать

Это мое первое сочинение для Инфостарта

В запросе, в соединении нельзя указать например:  ЛЕВОЕ СОЕДИНЕНИЕ ....... Ссылка В ИЕРАРХИИ(ТЗ.Ссылка)

Внизу приведены процедуры, которые позволяют все же сравниться с иерархией

идея в том что бы подготовить такую таблицу значений, где была бы информация



Первая колонка      Вторая колонка

Родитель                 Родитель.Родитель

Родитель                 Родитель.Родитель.Родитель

и так далее для каждой группы в первой колонке, всег вышестоящие группы во второй

и использовать это для этой задачи

Где можно будет указать .... СОединение Номенклатура.Родитель = ТЗ.Родитель и далее обрабатывается

условие с Вышестоящими родителями

итак процедуры

/// это основная процедура где и нужно произвести соединение по иерархии

Процедура КнопкаВыполнитьНажатие(Кнопка)

 
М = Новый МенеджерВременныхТаблиц;

 
Запрос = Новый Запрос;
 
Запрос.УстановитьПараметр("Номенклатура",Номенклатура);

 
ПолучитьНаборРодителей(М);
 
Запрос.МенеджерВременныхТаблиц = М;

 
// это конечно можно сразу в условии ГДЕ в ИЕРАРХИИ решить
 // это просто пример
 
Запрос.Текст =

 
"ВЫБРАТЬ
 | ВремТаб.ПервыйРодитель,
 | ВремТаб.РодительГдеТоНадНоменклатурой
 |ПОМЕСТИТЬ ТЗ
 |ИЗ
 | ВремТаб КАК ВремТаб
 |;
 |
 |////////////////////////////////////////////////////////////////////////////////
 |ВЫБРАТЬ
 | Номенклатура.Ссылка КАК Номенклатура,
 | ТЗ.ПервыйРодитель,
 | ТЗ.РодительГдеТоНадНоменклатурой
// ну и ради чего все затевалось, сравнение с группами в иерархии
 
|ИЗ
 | ТЗ КАК ТЗ
 |  ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
 |  ПО ТЗ.ПервыйРодитель = Номенклатура.Родитель
 |ГДЕ
 | ТЗ.РодительГдеТоНадНоменклатурой = &Номенклатура"
 
;

 
РЕзультат = Запрос.Выполнить().Выгрузить();
 
ЭлементыФормы.ТЗ_1.Значение = Результат.Скопировать();

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


// Эти две процедуры создают ТЗ с группами

// первая процедура выбирает все группы

// вторая заполняет ТЗ вышестоящими родителями для родителя первой колонки

Процедура ПолучитьНаборРодителей(МенВремТаблиц)


 
НовТЗСоВсемиРодителями = Новый ТаблицаЗначений;
 
ТипНоменклатура = Новый ОписаниеТипов("СправочникСсылка.Номенклатура");
 
НовТЗСоВсемиРодителями.Колонки.Добавить("ПервыйРодитель",ТипНоменклатура);
 
НовТЗСоВсемиРодителями.Колонки.Добавить("РодительГдеТоНадНоменклатурой",ТипНоменклатура);

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

 
НовТЗСоВсемиРодителями.Сортировать("ПервыйРодитель");

 
////////////////////////////////////////////////////////////////////////
 ///// для наглядоности, выгружаем в Таблицу значений на форме //////////
 ////////////////////////////////////////////////////////////////////////
 
ЭлементыФормы.ТЗ_.Значение = НовТЗСоВсемиРодителями.Скопировать();
 
ЭлементыФормы.ТЗ_.ОбновитьСтроки();

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

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

Процедура
ПолучитьВсехРодителей(ТЗ,Родитель,РодительНадРодителем)

 Если
РодительНадРодителем.Пустая() Тогда
  Возврат;
 КонецЕсли;

 
стрТЗ = ТЗ.Добавить();
 
стрТЗ.ПервыйРодитель     = Родитель;
 
стрТЗ.РодительГдеТоНадНоменклатурой = РодительНадРодителем;

 
ПолучитьВсехРодителей(ТЗ,Родитель,РодительНадРодителем.Родитель);

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

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    134703    740    391    

775

Как посмотреть итоговый запрос в отчете СКД

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    4393    implecs_team    6    

40

Пропорциональное распределение в запросе с использованием АвтоНомерЗаписи()

Запросы Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Часто поступают задачи по произвольному распределению общих сумм. После распределения иногда пропадают копейки. Суть решения добавить АвтоНомерЗаписи() в ВТ распределения, и далее используя функции МАКСИМУМ или МИНИМУМ можем положить разницу копеек в первую или последнюю строку знаменателя распределения.

11.04.2024    2764    andrey_sag    10    

32

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Программист Стажер Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    6503    KawaNoNeko    23    

26

Набор-объект для СКД по тексту или запросу

Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2412    2    Yashazz    0    

33

Запрос 1С copilot

Инструментарий разработчика Запросы Программист Стажер Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Бесплатно (free)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

15.01.2024    7744    65    mkalimulin    32    

58

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Одной из интересных задач, стоящих в процессе разработки, была поддержка механизма представлений в ЗУП. Но не просто возможность исполнения запросов с ними. Основная проблема была в том, чтобы с ними было удобно работать, а именно: создавать, модифицировать и отлаживать. Кратко о том, что в итоге получилось...

14.12.2023    2143    vandalsvq    7    

29

Консоль запросов УФ 8.3.2.24.12 (мод от Dr.Zombi)

Инструментарий разработчика Запросы Программист Платформа 1С v8.3 Управляемые формы Запросы Россия Абонемент ($m)

Работа с запросом и СКД, Полная поддержка пакетных запросов, временных таблиц. Главное скорость отладки запроса и данных, а красота вторична.

1 стартмани

07.12.2023    3619    52    DrZombi    54    

21
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. mr zafod 23 18.12.11 14:47 Сейчас в теме
? А вроде в СКД такое соединение делается на ура с помощью разных наборов данных
17. Hobbit_Jedi 12.03.15 12:05 Сейчас в теме
(1) А можно пример того, как это легко на СКД сделать?
2. YODDHA 50 19.12.11 00:16 Сейчас в теме
бесспорно))) решается, но иногда надо влезть в существующий запрос, например типовой, и строить скд, для общего модуля, или еще по каким причинам может быть неудобно.
3. Модератор раздела 23.12.11 16:37 Сейчас в теме
Что-то как-то наворочено и запутано все :(
Да еще и неоптимально :(
стр.ПервыйРодитель.Родитель - объектный/тормозной подход
еще РодительНадРодителем.Родитель и т.п.
Временная таблица ВремТаб нафига нужна? Она создается, из нее создается еще одна временная таблица, с которой уже идет основная работа. неоптимально.
ЗЫ код путаный совсем, тяжело разгребать.
4. YODDHA 50 24.12.11 23:43 Сейчас в теме
тут две задачи даже показаны,
одна из них понятно, это использование менеджера таблиц и использовании в запросе таблицы значения, тут все понятно и про нее расписывать ничего не стал
и вторая как узнать общего родителя через соединение в запросе

каждая процедурка, решает очень узкую задачу

КнопкаВыполнитьНажатие(Кнопка) основная процедура, в которой и лежит запрос в котором нужно получить соединение

ПолучитьНаборРодителей(М) процедура которая получает список родителей, организуя выборку родителей вообще
и подбор всех родителей через
рекурсивную процедуру ПолучитьВсехРодителей(ТЗ,Родитель,РодительНадРодителем)

что беру всего родителя, ну может и тяжело, только зачем в примере путать людей оптимизацией, чем нагляднее тем лучше

да еще, у меня приложена там обработка, которая и демонстрирует работу этой задачи
ну и я не убрал отсюда из кода строк которые управляют таблицей на форме

//ЭлементыФормы.ТЗ_1.Значение = Результат.Скопировать();

//ЭлементыФормы.ТЗ_.Значение = НовТЗСоВсемиРодителями.Скопировать();
//ЭлементыФормы.ТЗ_.ОбновитьСтроки();

если есть пожелания конкретного характера))) в частности как сделать код нагляднее, с удовольствием выслушаю
спасибо за критику
5. Модератор раздела 26.12.11 16:47 Сейчас в теме
(4) В (3) я тебе указал конкретные недостатки твоего кода.
что еще? для столь универсального кода нужна оптимизация/оптимальность.
Данные ХХХ.Родитель неужели трудно из запроса достать?
зачем промежуточная ненужная таблица вообще нужна?
6. YODDHA 50 26.12.11 17:17 Сейчас в теме
понятно))) если вы не увидели зачем она нужна, то и статья то в общем вам должна быть не интересна
7. Модератор раздела 27.12.11 07:46 Сейчас в теме
(6) Ты пойми, что одна из двух твоих временных таблиц вообще не нужна :(
Если уж выкладываешь универсальный код, либо сразу напиши, что он далеко не оптимален, либо сделай пооптимальнее.
8. YODDHA 50 27.12.11 13:03 Сейчас в теме
спасибо за комментарии
9. shomo 05.01.12 12:23 Сейчас в теме
Спасибо. Натолкнуло на решение собственной проблемы.
10. YODDHA 50 05.01.12 18:58 Сейчас в теме
11. пользователь 01.03.12 20:38
Сообщение было скрыто модератором.
...
12. KliMich 01.03.12 22:24 Сейчас в теме
13. mkostya 30 01.03.12 22:49 Сейчас в теме
14. ulili 04.05.12 12:59 Сейчас в теме
дело нужное и хорошее
15. s1sting 19.06.12 17:10 Сейчас в теме
16. YODDHA 50 19.06.12 17:30 Сейчас в теме
18. eugeniezheludkov 45 02.06.17 04:28 Сейчас в теме
Сорри за некропостинг ))) но наткнулся тут у вас на запрос в рекурсии и все это цикле это прям идеальный антипаттерн.
имхо наилучшая оптимизация подобной задачи это просто один цикл по каждому элементу правой таблицы соединения (В ИЕРАРХИИ)
19. YODDHA 50 07.08.17 10:35 Сейчас в теме
20. leonidt84 475 27.06.19 14:00 Сейчас в теме
ВЫБРАТЬ
	ВложенныйЗапрос.Ссылка,
	ВложенныйЗапрос.Родитель
ИЗ
	(ВЫБРАТЬ
		Товар.Ссылка КАК Ссылка,
		Товар.Родитель КАК Родитель
	ИЗ
		Справочник.Товар КАК Товар
	ГДЕ
		НЕ Товар.ЭтоГруппа
	
	ОБЪЕДИНИТЬ ВСЕ
	
	ВЫБРАТЬ
		Товар.Ссылка,
		Товар.Родитель.Родитель
	ИЗ
		Справочник.Товар КАК Товар
	ГДЕ
		НЕ Товар.ЭтоГруппа
	
	ОБЪЕДИНИТЬ ВСЕ
	
	ВЫБРАТЬ
		Товар.Ссылка,
		Товар.Родитель.Родитель.Родитель
	ИЗ
		Справочник.Товар КАК Товар
	ГДЕ
		НЕ Товар.ЭтоГруппа
	
	ОБЪЕДИНИТЬ ВСЕ
	
	ВЫБРАТЬ
		Товар.Ссылка,
		Товар.Родитель.Родитель.Родитель.Родитель
	ИЗ
		Справочник.Товар КАК Товар
	ГДЕ
		НЕ Товар.ЭтоГруппа
	
	ОБЪЕДИНИТЬ ВСЕ
	
	ВЫБРАТЬ
		Товар.Ссылка,
		Товар.Родитель.Родитель.Родитель.Родитель.Родитель
	ИЗ
		Справочник.Товар КАК Товар
	ГДЕ
		НЕ Товар.ЭтоГруппа) КАК ВложенныйЗапрос
ГДЕ
	ВложенныйЗапрос.Родитель <> ЗНАЧЕНИЕ(Справочник.Товар.ПустаяСсылка)
Показать

такой запрос в таблицу и спрягаете с ним ваш набор данных как хотите
21. YODDHA 50 27.06.19 18:17 Сейчас в теме
(20) Вложенность родителей не известна, в этом фокус, а такой перебор конечно очевиден
22. Рощупкин 11.04.23 16:16 Сейчас в теме
Хорошая статья, жизненно!)
Оставьте свое сообщение