Примеры запросов для работы с иерархическими справочниками
В данном разделе показаны примеры решения типовых задач при работе с иерархическими справочниками.
Получение элементов иерархического справочника, находящихся в подчинении заданной группы
Для получения подчиненных элементов иерархического справочника в языке запросов предусмотрена конструкция В ИЕРАРХИИ. Пример использования В ИЕРАРХИИ:
ВЫБРАТЬ
Номенклатура.Код,
Номенклатура.Наименование КАК Наименование,
Номенклатура.ЗакупочнаяЦена
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)
В данном примере будут получены все записи справочника Номенклатура, находящиеся в группе &Группа, включая ее саму, ее подчиненные группы и элементы, принадлежащие подчиненным группам.
Если же нас интересуют только элементы и группы, находящиеся непосредственно в заданной группе, то такие элементы мы можем получить установив условие на поле Родитель. Пример:
ВЫБРАТЬ
Номенклатура.Код,
Номенклатура.Наименование КАК Наименование,
Номенклатура.ЗакупочнаяЦена
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Родитель = &Группа
Такой запрос выберет группы и элементы, находящиеся в подчинении группы со ссылкой &Группа.
Проверка наличия подчиненных элементов у элемента справочника
Для проверки наличия подчиненных записей элемента справочника можно пользоваться запросом, аналогичным представленному:
ВЫБРАТЬ ПЕРВЫЕ 1
Номенклатура.Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Родитель = &Родитель
Если Запрос.Выполнить().Пустой() Тогда
Сообщить(«Зписей нет»);
Иначе
Сообщить(«Записи есть»);
КонецЕсли;
Получение всех родителей элемента
В языке запросов не предусмотрено специальных средств для получения всех родителей элемента. Для выполнения задачи можно воспользоваться иерархическими итогами, однако получение иерархических итогов оптимизировано для построения итогов большого количества записей, и не вполне эффективно для получения родителей одного элемента. Для более эффективного получения всех родительских записей элемента, рекомендуется перебирать в цикле его родителей небольшими порциями. Пример:
Запрос = Новый Запрос(«ВЫБРАТЬ
| Номенклатура.Родитель,
| Номенклатура.Родитель.Родитель,
| Номенклатура.Родитель.Родитель.Родитель,
| Номенклатура.Родитель.Родитель.Родитель.Родитель,
| Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|
|ГДЕ
| Номенклатура.Ссылка = &ТекущийЭлементНоменклатуры»;
Если ТекущийЭлементНоменклатуры = Справочники.Номенклатура.ПустаяСсылка() Тогда
Прервать;
КонецЕсли;
КонецЦикла;
В данном примере в окно служебных сообщений выводятся все родители для ссылки, записанной в переменную ЭлементНоменклатура. В цикле выбирается по 5 родителей ссылки.
Если число уровней в справочнике ограничено и невелико, то возможно получение всех родителей одним запросом без цикла.
Вывод иерархического справочника в отчет
Для вывода иерархического справочника в отчет с сохранением иерархии необходимо пользоваться запросом аналогичным следующему:
ВЫБРАТЬ
Номенклатура.Код,
Номенклатура.Наименование КАК Наименование,
Номенклатура.ЗакупочнаяЦена
ИЗ
Справочник.Номенклатура КАК Номенклатура
УПОРЯДОЧИТЬ ПО
Наименование ИЕРАРХИЯ
Данный запрос выбирает все записи из справочника и производит упорядочивание по иерархии. Результат будет упорядочен по наименованию, с учетом иерархии.
Для того чтобы группы справочника размещались выше элементов необходимо в данном запросе заменить предложение УПОРЯДОЧИТЬ ПО на следующее:
УПОРЯДОЧИТЬ ПО
Номенклатура.ЭтоГруппа ИЕРАРХИЯ,
Наименование
Результат по-прежнему будет упорядочен по иерархии, однако группы будут располагаться выше элементов.
Возможна также замена предложения УПОРЯДОЧИТЬ ПО на предложение АВТОУПОРЯДОЧИВАНИЕ. В этом случае результат будет упорядочен в соответствии с настройками справочника, т.е. если в справочнике указано, что группы должны располагаться выше элементов, то они будут расположены выше.
Получить иерархическую структуру справочника также возможно и при помощи итогов.
ВЫБРАТЬ
Номенклатура.Код,
Номенклатура.Наименование КАК Наименование,
Номенклатура.ЗакупочнаяЦена
ИЗ Справочник.Номенклатура КАК Номенклатура
ГДЕ
(Номенклатура.ЭтоГруппа = ЛОЖЬ)
УПОРЯДОЧИТЬ ПО Наименование
ИТОГИ ПО Номенклатура.Ссылка ТОЛЬКО ИЕРАРХИЯ
Получение итогов по иерархии
Для получения итогов по иерархии в запросе необходимо в предложении ИТОГИ ПО указать ключевое слово ИЕРАРХИЯ после указания поля, по которому будет рассчитываться итоги. Пример отчета «Обороты номенклатуры» с получением итогов по иерархии:
ВЫБРАТЬ
УчетНоменклатурыОбороты.Номенклатура КАК Номенклатура,
УчетНоменклатурыОбороты.Номенклатура.Представление,
УчетНоменклатурыОбороты.КоличествоОборот КАК КоличествоОборот
ИЗ
РегистрНакопления.УчетНоменклатуры.Обороты КАК УчетНоменклатурыОбороты
ИТОГИ СУММА(КоличествоОборот) ПО
Номенклатура ИЕРАРХИЯ
В результате данного запроса будут рассчитаны итоги не только для каждой номенклатуры, но и для групп, к которым принадлежит та или иная номенклатура.
В случае, когда не нужны итоги по элементам, а нужны итоги только по группам, нам необходимо использовать в итогах конструкцию ТОЛЬКО ИЕРАРХИЯ. Пример:
ВЫБРАТЬ
УчетНоменклатурыОбороты.Номенклатура КАК Номенклатура,
УчетНоменклатурыОбороты.Номенклатура.Представление,
УчетНоменклатурыОбороты.КоличествоОборот КАК КоличествоОборот
ИЗ
РегистрНакопления.УчетНоменклатуры.Обороты КАК УчетНоменклатурыОбороты
ИТОГИ СУММА(КоличествоОборот) ПО
Номенклатура ТОЛЬКО ИЕРАРХИЯ
В результате данного запроса будут итоговые записи только для групп номенклатуры.
Запрос В ИЕРАРХИИ
Запрос В ИЕРАРХИИ
Данный условный оператор запросов 1С рассмотрен отдельно, так как за видимой простотой скрываются некоторые особенности его использования.
Предназначение
В системе объектов 1С:Предприятия ключевое место занимают справочники, бухгалтерские счета (в меньшей степени с планы видов характеристик), главной особенностью которых является иерархическая структура.
Она может быть включена, ограничена на этапе создания. Данный функционал позволяет удобно устроить справочные данные, карточки товаров.
Стоит заметить, что это не новый функционал — появился он еще до 7.7. Например в 6.0 максимум могло быть 3 уровней иерархии.
В 8.0 появилась не только иерархия групп, но и иерархия элементов.
Данный функционал не является, чем то сложным — просто у каждого такого элемента, группы появляется свойство «Родитель», т.е. таблицы имеет ту же двумерную структуру:
Использование
Получим подчиненные счета из плана счетов для предопределенного элемента
Что происходит в реальности
Система преобразует такую команду в цепочку запросов, что негативно сказывается на производительности.
Использование данной команды для больших справочников не рекомендуется, особенно в явных условиях виртуальных таблиц (вложенные более оптимальные).
Если справочник имеет заранее известную вложенность, то использование цепочки соединений, может быть более оправдано для таких запросов, но является не универсальным и «некрасивым».
Следует организовывать алгоритм так, чтобы подобные запросы запросы производились редко, не циклично, по возможности «кешировались».
Дополнительная информация
В конструкторе запроса задается на вкладке условия:
В отчетах СКД и в механизмах отбора системы/отчетов существует аналог:
Если в качестве параметра передать пустую ссылку, то данный запрос выдаст все элементы (истина), это следует иметь ввиду
Эту особенность можно использовать в фильтрах, т.е. если значение не выбрано считается, что фильтр не действует.
Вот такой полезный, удобный, но особенный условный оператор «В ИЕРАРХИИ()».
Реклама — самый дешевый способ продажи товара, особенно если товар не имеет никакой ценности.
Вложенные запросы в 1С 8.3. Оператор В
Вложенные запросы
Язык запросов 1С поддерживает вложенные запросы. Вложенный запрос — это когда выборка выполняется не из таблицы, а из результата другого запроса, например:
Сначала во вложенном запросе свернули таблицу по цвету, а потом из результата выбрали все поля.
Во вложенном запросе нельзя использовать итоги, потому что итоги рассчитываются сервером 1С, а не СУБД. Также во вложенном запросе нельзя использовать предложение УПОРЯДОЧИТЬ ПО, кроме случаев когда используется ключевое слово ПЕРВЫЕ:
Количество вложенности запросов не ограничено.
Оператор В
Допустим, нам нужно выбрать все камеры хранения, где площадь равна 100 или 200. Для этого можно использовать следующий запрос:
Оператор В позволяет сократить текст запроса и сделать его более понятным для чтения:
После оператора В в скобках перечисляются все возможные значения. Это может быть одно значение, десять или любое другое количество.
Также параметром можно передать массив или список значений:
Можно указать вложенный запрос:
Данный запрос выберет те камеры хранения, где площадь равна максимальной среди всех камер.
Можно использовать несколько полей:
Количество полей слева от оператора В и в результате вложенного запроса должно совпадать, иначе будет ошибка «В запросах операции «В» должно выбираться столько полей, сколько операндов имеет левая часть операции.».
Также важна последовательность. В запросе выше поле Спр.Площадь сравнивается с первым полем вложенного запроса, а Спр.Цвет со вторым.
Из вложенного запроса можно обращаться к полям внешнего запроса:
Оператор «В ИЕРАРХИИ» в запросе
Начало
Конструкция «В ИЕРАРХИИ» в запросах 1С:Предприятия 8.x позволяет получить подчиненные элементы иерархического объекта конфигурации по заданному отбору. Сегодня в статье рассмотрим пример ее использования, а также действия платформы на стороне СУБД и ее влияние на производительность.
Использование
Рассмотрим простой пример использования конструкции «В ИЕРАРХИИ». При выполнении следующего запроса будут получены подчиненные элементы иерархического справочника «Товары» для переданного значения переменной «Ссылка».
В качестве параметра «&Ссылка» передается ссылка на группу справочника. Пример выполняем на тестовой базе, ссылка для загрузки на которую доступна в конце статьи.
В тестовой базе справочник «Товары» имеет следующие тестовые данные:
Конечно, на изображении показаны не все записи справочника. Скриншот показывает лишь структуру хранения данных в иерархическом справочнике. В таблице справочника хранятся 10 групп верхнего уровня, в каждой из них содержится 5 вложенных групп с 200 элементами в каждой.
Как мы видим, запрос вернул ссылку на саму верхнюю группу (переданную параметром), а также вложенные группы с находящимися в них элементами. Таким образом, использование конструкции «В ИЕРАРХИИ» позволяет удобным образом получать иерархически подчиненные данные.
Синтаксис языка запросов 1C:Предприятия и классического SQL очень похожи в некоторых моментах. Но для выражения «В ИЕРАРХИИ» нет аналога в языке запросов SQL как, например, для выражения языка запросов платформы «В» есть аналогичный SQL-оператор «IN». Поэтому интересной является работа платформы с СУБД при использовании данного оператора.
За кулисами
Итак, приступим. Для примера будем использовать написанный ранее запрос к справочнику «Товары». Анализировать действия платформы будем для двух ситуация:
1. Сначала выполняется SQL-запрос на получение ссылки на группу справочника, переданную в качестве параметра, и всех подчиненных ей групп. Результат помещается во временную таблицу ‘#tt1’.
2. На втором этапе дважды выполняется одинаковый запрос:
Влияние на производительность
Неправильное использование любого оператора в запросе может привести к неоптимальной работе системы. Рассматриваемый оператор «В ИЕРАРХИИ» не исключение. Его нужно применять с осторожностью, поскольку он намного усложняет алгоритм выполнения SQL-запросов к базе и тем самым увеличивает нагрузку на сервер СУБД.
Приведу пример неоптимального запроса, который может привести к названным выше печальным последствиям:
Как можно догадаться, запрос приведет к формированию множества SQL-запросов, что повлечет за собой снижение производительности информационной системы.
Делайте выводы!
Выводы делать Вам. Скажу лишь, что оператор «В ИЕРАРХИИ» используется платформой для системы компоновки данных, когда в условиях отбора присутствуют «В ГРУППЕ», «В ГРУППЕ ИЗ СПИСКА» и прочие. Думаю не стоит объяснять, что при неправильных манипуляциях пользователи могу поставить очень сложный отбор и повысить нагрузку на сервер 1С и СУБД в несколько раз. Давайте изменять настройки только опытным пользователям.
Ну и разумеется, при написании собственных механизмов обращайте внимание на оператор «В ИЕРАРХИИ». Очень удобный с одной стороны, и опасный с другой.
Примеры запросов для работы с иерархическими справочниками
Получение элементов иерархического справочника, находящихся в подчинении заданной группы
Для получения подчиненных элементов иерархического справочника в языке запросов предусмотрена конструкция В ИЕРАРХИИ :
Если же нас интересуют только элементы и группы, находящиеся непосредственно в заданной группе, то такие элементы мы можем получить, установив условие на поле Родитель :
Проверка наличия подчиненных элементов у элемента справочника
Для проверки наличия подчиненных записей элемента справочника можно пользоваться запросом, аналогичным представленному:
Получение всех родителей элемента
В языке запросов не предусмотрено специальных средств для получения всех родителей элемента. Для выполнения задачи можно воспользоваться иерархическими итогами, однако получение иерархических итогов оптимизировано для построения итогов большого количества записей, и не вполне эффективно для получения родителей одного элемента. Для более эффективного получения всех родительских записей элемента, рекомендуется перебирать в цикле его родителей небольшими порциями.
Если число уровней в справочнике ограничено и невелико, то возможно получение всех родителей одним запросом без цикла.
Вывод иерархического справочника в отчет
Для вывода иерархического справочника в отчет с сохранением иерархии необходимо пользоваться запросом аналогичным следующему:
Данный запрос выбирает все записи из справочника и производит упорядочивание по иерархии. Результат будет упорядочен по наименованию, с учетом иерархии.
Для того, чтобы группы справочника размещались выше элементов необходимо в данном запросе заменить предложение УПОРЯДОЧИТЬ ПО на следующее:
Результат по-прежнему будет упорядочен по иерархии, однако группы будут располагаться выше элементов.
Получить иерархическую структуру справочника также возможно и при помощи итогов:
Получение итогов по иерархии
Для получения итогов по иерархии в запросе необходимо в предложении ИТОГИ ПО указать ключевое слово ИЕРАРХИЯ после указания поля, по которому будет рассчитываться итоги. Пример отчета «Обороты номенклатуры» с получением итогов по иерархии:
В результате данного запроса будут рассчитаны итоги не только для каждой номенклатуры, но и для групп, к которым принадлежит та или иная номенклатура.
В случае, когда не нужны итоги по элементам, а нужны итоги только по группам, необходимо использовать в итогах конструкцию ТОЛЬКО ИЕРАРХИЯ :
В результате данного запроса будут итоговые записи только для групп номенклатуры.