Генератор текста запроса для получения родителей верхнего уровня

29.11.24

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

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Обработка для интерактивной генерации текста на УФ
.epf 8,62Kb
2
2 Скачать (1 SM) Купить за 1 850 руб.

После столкновения с проблемой получения родителей верхнего уровня, я решил, что писать запрос каждый раз я не выдержу, поэтому решил написать функцию, которая сгенерирует текст запроса для получения родителей верхнего уровня. Далее этот текст можно передавать в конструкцию "Новый Запрос()" , или копировать и подставлять в запрос самостоятельно.

 

Функция принимает следующие параметры:

ИмяСправочника - имя справочника, по которому необходимо получить родителей верхнего уровня.

ИмяВременнойТаблицы - имя таблицы, куда следует поместить результат, если это необходимо.

ВключитьГруппыВРезультат - если Истина, то в таблицу попадут группы, если Ложь, то только элементы.

ИмяРеквизитаРодитель - имя реквизита, по которому строится иерархия. На случай, если добавлен отдельный реквизит (например, если справочник не иерархический).

МаксимальноеКоличествоУровнейИерархии - на сколько глубоко будет построен запрос. Укажите параметр явно, если хотите получить родителя "не выше n-го уровня".

 

// Текст запроса для получения родителей верхнего уровня для иерархического справочника.
//
// Параметры:
//  ИмяСправочника                             - Строка - Имя справочника, по которому необходимо получить родителей.
//  ИмяВременнойТаблицы                         - Строка - Имя временной таблицы для помещения в нее результата.
//                                                      Если не задана, то будет сформирована выборка данных.
//  ВключитьГруппыВРезультат                 - Булево - Истина - в результат попадут группы / Ложь - только элементы.
//  ИмяРеквизитаРодитель                     - Строка - Имя реквизита, по которому необходимо получить верхний уровень иерархии.
//  МаксимальноеКоличествоУровнейИерархии     - Число  - Количество возможных уровней иерархии (не менее 2). Если не задано, то определяется автоматически:
//                                                        по настройкам справочника (если установлено ограничение), иначе 10, как значение по умолчанию.
// 
// Возвращаемое значение:
//  Строка - Текст запроса для получения родителей верхнего уровня. 
//
&НаСервереБезКонтекста
Функция ТекстЗапросаРодителиВерхнегоУровня(ИмяСправочника, ИмяВременнойТаблицы = "", ВключитьГруппыВРезультат = Ложь,
                                           ИмяРеквизитаРодитель = "Родитель",
                                           МаксимальноеКоличествоУровнейИерархии = Неопределено) Экспорт
                                           
    // Если количество уровней иерархии не задано, то определяем автоматически
    Если МаксимальноеКоличествоУровнейИерархии = Неопределено Тогда
        Попытка
            МетаданныеСправочника = Метаданные.Справочники[ИмяСправочника]; 
            Если МетаданныеСправочника.ОграничиватьКоличествоУровней Тогда
                МаксимальноеКоличествоУровнейИерархииВрем = МетаданныеСправочника.КоличествоУровней;
            Иначе // Значение по умолчанию
                МаксимальноеКоличествоУровнейИерархииВрем = 10;
            КонецЕсли;
        Исключение // Справочник не найден
            МаксимальноеКоличествоУровнейИерархииВрем = 10;    
        КонецПопытки;
    Иначе // Получаем родителей не выше указанного уровня и не менее 2
        МаксимальноеКоличествоУровнейИерархииВрем = Макс(МаксимальноеКоличествоУровнейИерархии, 2);    
    КонецЕсли;
    
    // Выделяем часть для первого уровня, в качестве родителя указываем сам элемент
    ТекстЗапроса = СтрШаблон("
    |ВЫБРАТЬ
    |    ИсточникДанных.Ссылка КАК Ссылка,
    |    ИсточникДанных.Ссылка КАК Родитель
    |ИЗ
    |    Справочник.%1 КАК ИсточникДанных", ИмяСправочника);
    
    // Добавляем цикличную часть (начинаем с второго уровня, т.к первый уровень иерархии уже определен выше)
    Для УровеньИерархии = 2 По МаксимальноеКоличествоУровнейИерархииВрем Цикл
        
        // Проверка на последний уровень
        Если УровеньИерархии = МаксимальноеКоличествоУровнейИерархииВрем Тогда
            // Исключаем ситуацию, когда элемент является своим родителем
            ИмяРеквизитаСсылка = ИмяРеквизитаРодитель;
            ТекстВременнойТаблицы = ?(ПустаяСтрока(ИмяВременнойТаблицы), "", "
            |ПОМЕСТИТЬ " + ИмяВременнойТаблицы);    
        Иначе
            ТекстВременнойТаблицы = "";
            ИмяРеквизитаСсылка = "Ссылка";    
        КонецЕсли;
        
        ТекстЗапроса = СтрШаблон("
        |ВЫБРАТЬ
        |    ИсточникДанных.Ссылка КАК Ссылка,
        |    ВЫБОР
        |        КОГДА ИсточникДанных.%2 = ЗНАЧЕНИЕ(Справочник.%1.ПустаяСсылка)
        |            ТОГДА ИсточникДанных.%4
        |        ИНАЧЕ ВложенныйЗапрос.Родитель
        |    КОНЕЦ КАК Родитель %5
        |ИЗ
        |    Справочник.%1 КАК ИсточникДанных
        |        ЛЕВОЕ СОЕДИНЕНИЕ (%3) КАК ВложенныйЗапрос
        | 
        |ПО ИсточникДанных.%2 = ВложенныйЗапрос.Ссылка", ИмяСправочника, ИмяРеквизитаРодитель, ТекстЗапроса, ИмяРеквизитаСсылка, ТекстВременнойТаблицы);
        
    КонецЦикла;
    
    // Исключаем группы из результата по параметру
    Если Не ВключитьГруппыВРезультат Тогда
        ТекстЗапроса = ТекстЗапроса + "
        |ГДЕ НЕ ИсточникДанных.ЭтоГруппа";
    КонецЕсли;
    
    Возврат ТекстЗапроса;
    
КонецФункции

 

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

Проверено на следующих конфигурациях и релизах:

  • 1С:ERP Управление предприятием 2, релизы 2.5.19.60

Запрос родитель транзитивное замыкание верхний уровень обработка генератор текст запроса иерархия уровень группы элементы

См. также

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

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

12000 руб.

02.09.2020    168192    929    403    

900

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    11252    sergey279    18    

65

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

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

11.10.2024    6218    XilDen    36    

83

Запросы Программист Запросы Бесплатно (free)

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

16.08.2024    8940    user1840182    5    

28

Математика и алгоритмы Запросы Программист Платформа 1С v8.3 Запросы Бесплатно (free)

Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.

08.07.2024    2695    ivanov660    9    

22

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

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

15.05.2024    10076    implecs_team    6    

48

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

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

11.04.2024    3602    andrey_sag    10    

38
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. scarl1n 12 19.09.24 07:09 Сейчас в теме
(1) Не натыкался на это, видел лишь https://infostart.ru/1c/articles/158512/. Изобрел велосипед, получается) Ну ладно, пусть будет еще способ через вложенные запросы вместо временных таблиц) Мне кажется такое удобнее в свой запрос подставлять (будет 1 набор данных, а не 10 временных таблиц и еще 10 их уничтожений).
3. vkovall 17 19.09.24 23:21 Сейчас в теме
Для такой штуки изобрели дискретрую математику и транзиктивные замыкания насколько я помню.
Ох и весело это все будет тормозить на большом объёме данных, которые с каждым годом все более в базах встречаются.
4. scarl1n 12 20.09.24 07:41 Сейчас в теме
(3) Ну, у меня нет большой базы для проверки, взял 30гб базу с 50к элементами справочника, длину пути указал 10 (для способа из транзитивного замыкания указал длину дуги 4):
Вложенные запросы: 0.4 - 0.55с
Транзитивное замыкание: 1.3-1.5с
По итогу данный способ выигрывает в плане удобства работы в конструкторе и по скорости выполнения в небольшой базе. Но зачем разбираться, когда можно просто ткнуть минус)
5. vkovall 17 20.09.24 11:15 Сейчас в теме
(4) минус это тоже оценка.
Оставьте свое сообщение