Как сделать иерархию в запросе 1с

Добавил пользователь Alex
Обновлено: 04.10.2024

Программное создание дерева значений

Как уже упоминалось выше, каждая строка имеет свойство Строки , которое содержит коллекцию дочерних строк. И сам объект ДеревоЗначений имеет свойство Строки , которое содержит коллекцию строк верхнего уровня.

  • Добавляет колонку в конец коллекции колонок дерева значений.
  • Возвращаемое значение: КолонкаДереваЗначений .
  • Добавляет строку в конец коллекции строк данного уровня дерева значений.
  • Возвращаемое значение: СтрокаДереваЗначений .

Заполнить табличное поле на форме

Визуальное представление дерева значений на форме обеспечивает элемент Таблица .



Пример программного заполнения дерева значений для управляемых форм:



Результат выполнения запроса очень легко преобразовать в дерево значений, для этого нужно воспользоваться методом Выгрузить() и указать параметр ТипОбхода отличным от того, что стоит по умолчанию, т.е. ПоГруппировкам или ПоГруппировкамСИерархией .


Свернуть и развернуть строки дерева значений

Свернуть и развернуть дочерние строки элемента дерева значений можно с помощью методов Свернуть() и Развернуть() .

  • Сворачивает узел в указанной строке дерева.
  • ИдектификаторСтроки — идентификатор строки таблицы.
  • Разворачивает узел в указанной строке дерева.
  • ИдектификаторСтроки — идентификатор строки таблицы.
  • СПодчиненными — определяет необходимость раскрытия подчиненных узлов.
  • Получает коллекцию элементов дерева верхнего уровня.
  • Возвращаемое значение: ДанныеФормыКоллекцияЭлементовДерева .
  • Получает коллекцию дочерних элементов.
  • Возвращаемое значение: ДанныеФормыКоллекцияЭлементовДерева .

Для представления в форме объектов конфигурации (справочники, документы и т.п.) существуют специальные типы данных:

  • ДанныеФормыСтруктура — содержит набор свойств произвольного типа. Свойствами могут быть другие структуры, коллекции или структуры с коллекциями. Таким типом представляется, например, в форме СправочникОбъект .
  • ДанныеФормыКоллекция — это список типизированных значений, похожий на массив. Доступ к элементу коллекции осуществляется по индексу или по идентификатору. Доступ по идентификатору может отсутствовать в некоторых случаях. Это обусловлено типом прикладного объекта, который представлен этой коллекцией. Идентификатором может быть любое целое число. Таким типом представляется, например, в форме табличная часть.
  • ДанныеФормыСтруктураСКоллекцией — это объект, который представлен в виде структуры и коллекции одновременно. С ним можно обращаться как с любой из этих сущностей. Таким типом представляется, например, в форме набор записей.
  • ДанныеФормыДерево — объект предназначен для хранения иерархических данных.

Прикладной объект представлен либо одним, либо несколькими элементами данных формы. Например, документ, содержащий табличную часть, будет представлен объектом типа ДанныеФормыСтруктура (собственно документ), которому подчинен объект типа ДанныеФормыКоллекция (табличная часть документа).

Удалить строку и очистить дерево значений

Поиск в дереве значений

Среди наиболее часто используемых методов стоит отметить метод Найти() коллекции строк дерева значений.

  • Значение (обязательный, тип Произвольный ). Искомое значение.
  • Колонки (необязательный, тип Строка ). Список имен колонок, в которых будет осуществляться поиск, разделенных запятыми. Если параметр не указан, поиск осуществляется по всем колонкам дерева. Значение по умолчанию — Пустая строка.
  • ВключатьПодчиненные (необязательный, тип Булево ). Определяет, будут ли участвовать в поиске строки подчиненных коллекций (если таковые имеются). Если Истина — строки подчиненных коллекций участвуют в поиске. Значение по умолчанию — Ложь .

Метод осуществляет поиск значения в дереве в указанных колонках коллекции строк дерева значений. Возвращает строку (тип СтрокаДереваЗначений ), которая содержит искомое значение. Если значение не найдено, то возвращается значение Неопределено . Предназначен для поиска уникальных значений.

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

Размещение на форме и заполнение дерева значений

Чтобы на управляемой форме вывести дерево значений, необходимо добавить новый реквизит, выбрать нужный тип, добавить колонки и перетащить влево. На вопрос о добавлении колонок ответьте утвердительно, и перед вами предстанет общий вид дерева значений. Чтобы увидеть какие-либо записи, необходимо добавить строки дерева значений 1С с нужными данными.


Существует несколько способов заполнения дерева значений нужными нам свойствами с определенной иерархией. Самый простой вариант – заполнить вручную, последовательно добавляя элементы и внимательно самостоятельно соблюдая иерархию. Естественно, при большом количестве элементов данный вариант не должен рассматриваться разработчиками 1С. Данный способ вывода информации состоит из следующих операторов:

На стороне сервера:

  1. Получение значения реквизита;
  2. Добавление элементов с учетом иерархии;
  3. Возврат значения в элемент формы на клиенте для вывода пользователю.

На стороне клиента:

  1. Получение элементов дерева;
  2. Добавление новых.


Таким способом можно оформить на управляемой форме 1С небольшое дерево значений или простую иерархию, используя цикл. Однако часто возникает задача представить на форме сложный иерархический справочник из базы данных. И здесь на помощь придет помещение результата запроса в дерево на форме. Алгоритм достаточно прост и логичен:

  • Создаем запрос и указываем нужные нам условия. Важно, чтобы псевдонимы совпадали с наименованием колонок дерева значений на форме;
  • Получаем данные с нужным видом обхода. Если не указывать, то получится не иерархическая таблица значений.


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

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

Работа с заполненным деревом значений

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

На клиентской стороне:

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

На серверной стороне:

  • Получаем объект с формы;
  • Вызываем процедуру с объектом в качестве параметра;
  • В цикле по каждой строке дерева проверяем количество вложенных элементов и при их наличии снова вызываем процедуру.

Также достаточно распространенной задачей является преобразование дерева значений в таблицу значений. Так как нам нельзя терять иерархию, в таблице будет на 2 поля больше, чем в дереве – добавятся идентификатор и родитель. Заполнить таблицу с сохранением структуры мы сможем с помощью рекурсивной процедуры.

Целиком алгоритм состоит из:

  1. Вызов процедуры с указанием начального идентификатора;
  2. Цикл с добавлением данных в таблицу значений и проверкой на наличие вложенных элементов в дереве в каждой итерации. При их наличии снова начинается вызов рекурсивной процедуры.

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



1) Идея проста – выбираем запросом элементы, не являющиеся папками, а всю иерархию нам построит запрос. Тут сразу начинаются неожиданности. Какую конструкцию использовать: ИЕРАРХИЯ или ТОЛЬКО ИЕРАРХИЯ? Вроде логично было бы ТОЛЬКО ИЕРАРХИЯ, т.к. итоги на уровне элементов нам не нужны (будут дубли). Заглядываем в справку: "ИЕРАРХИЯ. В результате будут рассчитаны итоги по контрольным точкам и итоги по иерархии для контрольных точек . При необходимости можно рассчитать итоги только значений по иерархии, без расчета итогов в контрольных точках. Для этого перед ключевым словом ИЕРАРХИЯ нужно указать ключевое слово ТОЛЬКО."

Для однозначного понимания моих объяснений введу несколько "терминов", которыми буду пользоваться. Все листья дерева буду называть элементами. Узлы дерева, которые содержат только элементы – нижние папки, Остальные узлы, которые содержат хотя бы одну нижнюю папку – верхние папки.

Для ИЕРАРХИЯ – все логично: разбираем дерево итогов по иерархии для папок. У всех папок тип – ТипЗаписиЗапроса.ИтогПоИерархии. У элементов тип – ТипЗаписиЗапроса.ИтогПоГруппировке. Внутри группировки одна запись того же элемента но уже с типом ТипЗаписиЗапроса.ДетальнаяЗапись. Все как заявлено. Но если выгрузить в дерево, дубль пропадает!

Либо сформировать вручную

Для ТОЛЬКО ИЕРАРХИЯ все немного не так, как ожидалось. Верхние папки – ТипЗаписиЗапроса.ИтогПоИерархии, нижние – ТипЗаписиЗапроса.ИтогПоГруппировке. Внутри элементы с типом – ТипЗаписиЗапроса.ДетальнаяЗапись. НО, если верхняя папка содержит элементы, все они будут помещены в еще в одну вложенную группу с типом ТипЗаписиЗапроса.ИтогПоГруппировке. Поэтому выгрузить() приводит к дублированию! Цель такого дублирования думаю в том, чтобы все элементы обязательно содержались в папке с ТипЗаписиЗапроса.ИтогПоГруппировке, чтобы мы могли обходить выборку ОбходРезультатаЗапроса.ПоГруппировкам. Поэтому, если использовать ТОЛЬКО ИЕРАРХИЯ, лучше обойти выборку и сформировать ручками дерево, устраняя дублирование. При обходе нужно обязательно указывать второй параметр "Группировки". Привожу обход для ТОЛЬКО ИЕРАРХИЯ

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

2) Для решения этой проблемы необходимо выбрать папки в запросе. Такой запрос не получиться выгрузить в дерево, но, если мы будем использовать в запросе УПОРЯДОЧИТЬ ПО . ИЕРАРХИЯ, а также выберем в запросе родителя, то обход дерева станет простым, мы будем обходить выборку в цикле и прицеплять следующий элемент к текущему или одному из его родителей. К кому цеплять покажет выбранное поле родитель.

Рассмотрим задачу получения только иерархии по набору элементов. Для решения задачи выберем для элементов все папки, в которых они содержатся, затем замыканием вычислим всех родителей этих папок, ну и далее выборка с обходом по 2 методу.

Batchir --> Batchir


В данном разделе показаны примеры решения типовых задач при работе с иерархическими справочниками.

Получение элементов иерархического справочника, находящихся в подчинении заданной группы

Для получения подчиненных элементов иерархического справочника в языке запросов предусмотрена конструкция В ИЕРАРХИИ. Пример использования В ИЕРАРХИИ:

В данном примере будут получены все записи справочника Номенклатура, находящиеся в группе &Группа, включая ее саму, ее подчиненные группы и элементы, принадлежащие подчиненным группам.

Если же нас интересуют только элементы и группы, находящиеся непосредственно в заданной группе, то такие элементы мы можем получить установив условие на поле Родитель. Пример:

Такой запрос выберет группы и элементы, находящиеся в подчинении группы со ссылкой &Группа.

Проверка наличия подчиненных элементов у элемента справочника

Для проверки наличия подчиненных записей элемента справочника можно пользоваться запросом, аналогичным представленному:

В данном примере ссылка элемента, для которого необходимо проверить наличие дочерних элементов, записывается в параметр запроса "Родитель". После выполнения такого запроса необходимо проверить результат на пустоту. Если результат не пустой, то подчиненные записи есть. Иначе - нет. Пример:

Получение всех родителей элемента

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

Если число уровней в справочнике ограничено и невелико, то возможно получение всех родителей одним запросом без цикла.

Вывод иерархического справочника в отчет

Для вывода иерархического справочника в отчет с сохранением иерархии необходимо пользоваться запросом аналогичным следующему:

Данный запрос выбирает все записи из справочника и производит упорядочивание по иерархии. Результат будет упорядочен по наименованию, с учетом иерархии.

Для того чтобы группы справочника размещались выше элементов необходимо в данном запросе заменить предложение УПОРЯДОЧИТЬ ПО на следующее:

Результат по-прежнему будет упорядочен по иерархии, однако группы будут располагаться выше элементов.

Возможна также замена предложения УПОРЯДОЧИТЬ ПО на предложение АВТОУПОРЯДОЧИВАНИЕ. В этом случае результат будет упорядочен в соответствии с настройками справочника, т.е. если в справочнике указано, что группы должны располагаться выше элементов, то они будут расположены выше.

Получить иерархическую структуру справочника также возможно и при помощи итогов.

Получение итогов по иерархии

Для получения итогов по иерархии в запросе необходимо в предложении ИТОГИ ПО указать ключевое слово ИЕРАРХИЯ после указания поля, по которому будет рассчитываться итоги. Пример отчета "Обороты номенклатуры" с получением итогов по иерархии:

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

В случае, когда не нужны итоги по элементам, а нужны итоги только по группам, нам необходимо использовать в итогах конструкцию ТОЛЬКО ИЕРАРХИЯ. Пример:

В результате данного запроса будут итоговые записи только для групп номенклатуры.

Работа с иерархией в системе компоновки данных

Система компоновки данных позволяет выводить в результат иерархические данные. В данной статье описываются некоторые особенности работы с иерархией в системе компоновки данных.

Иерархические группировки

Для того чтобы вывести в отчет группировку с иерархией следует у поля группировки, указать тип иерархии.

Создаем схему с набором данных - запрос. В качестве текста запроса используем следующий запрос:

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


Результатом отчета будет простой список номенклатуры:

Изменим тип иерархии на "Иерархия". Для этого, в настройках отчета дважды щелкнем на группировке и изменим тип иерархии:


Теперь результат отчета будет дополнен иерархическими записями - родительскими записями для выводимой в отчет номенклатуры:

Если же изменить тип иерархии на "Только иерархия", то в группировке будут выводиться только иерархические записи:

Отбор "В группе"

Система компоновки данных позволяет отбирать записи, которые находятся в иерархии некоторого элемента. Для этого в системе предусмотрен вид сравнения "В группе" (во встроенном языке данный вид сравнения называется ВИерархии).

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

Если в отчет из первой части статьи добавить отбор "Номенклатура В группе "Программное обеспечение", то результат отчета будет выглядеть так

Описание иерархических наборов данных

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

Допустим, у нас есть справочник Сотрудники, в котором есть реквизит Руководитель, содержащий ссылку на сотрудника, являющегося непосредственным руководителем сотрудника. В документе РасходнаяНакладная имеется реквизит Ответственный, в котором указывается сотрудник, ответственный за документ.

Требуется выдать отчет, в котором документы будут сгруппированы по ответственным за документы сотрудникам, с выводом иерархии по сотрудникам.

Для создания такого отчета:

Создадим набор данных "Документы", получающий список документов при помощи запроса:

Данный запрос выдаст нам документы с сотрудниками за них ответственных.

Для построения иерархии создадим набор данных "ИерархияСотрудников". Его запрос будет выглядеть так:

Как видно, данный запрос будет возвращать сотрудников, перечисленных в параметре запроса Сотрудник.

Для того чтобы данный набор данных получал по иерархии всех руководителей, опишем связь. В конструкторе схемы компоновки данных это делается на закладке "Связи".

В связи укажем, что связываем набор данных ИерархияСотрудников сам с собой. В качестве выражения источника будет выступать выражение "Руководитель", а в качестве выражения - приемника "Сотрудник". Таким образом, из каждой записи набора данных будет получено значение поля Руководитель и будет осуществлен поиск полученного значения в поле Сотрудник в этом же наборе данных и система рекурсивно получит все записи по иерархии. Т.к. в запросе записи получаются только для сотрудников, переданных в параметре Сотрудник, то в связи укажем, что следует использовать этот параметр, и т.к. параметр может принимать список значений, обозначаем это в связи, установив соответствующий флажок.


Теперь в схеме следует создать еще одну связь, которая будет указывать, что поле Сотрудник набора данных Документы следует связать с полем иерархического набора данных.


ВАЖНО!
При выводе иерархических записей система компоновки данных выводит в результат поля с теми же именами, какие были у полей, для которых достраивалась иерархия. Поэтому, в иерархическом наборе данных поле, с которым осуществляется связь основного набора должно называться так же, как и в основном наборе. Так, в приведенном выше примере, в иерархическом наборе данных связуемое поле должно иметь имя Сотрудник.

После описания связей, результат отчета с иерархической группировкой будет выглядеть приблизительно так:

СОВЕТ
Для того чтобы поля иерархического набора данных не отображались пользователю, следует отключить у этих полей доступность настройки. Делается это на закладке "Наборы данных" конструктора схемы компоновки данных.


Набор данных для проверки иерархии

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

Для того чтобы этого достичь создадим в схеме компоновки новый набор данных ПроверкаИерархии, с текстом запроса:

Для набора данных определим связь самого к себе. Выражение источник "ПроверкаИерархииСотрудника", приемник "РодительИерархииСотрудника". Параметр связи ПроверкаИерархииСотрудника, с возможностью использования списка.

Теперь следует указать данный набор как набор данных проверки иерархии поля Сотрудник набора данных Документы. Это делается на закладке "Наборы данных" в таблице полей набора данных.


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

Так, выше описанный отчет, с отбором "Сотрудник В группе "Тарасов" будет выглядеть так:

Примеры

Приведенные в данной статье примеры можно найти в отчете "ДокументыПоОтветственным" в информационной базе "Примеры 8.1", расположенной на диске ИТС.

Параметры запроса и работа с ними. Типы равенствнеравенств равно, В, В ИЕРАРХИИ и др.

Для построения грамотного и эффективного запроса, нужно разбираться в его параметрах. Запрос 1С к базе данных – это конструкция, позволяющая извлечь актуальную информацию из набора таблиц и предоставить её пользователю для принятия обоснованного управленческого решения в наиболее оптимальной форме. Поскольку Запрос 1С является объектом с набором параметров, то определённые приёмы языка запросов позволяют повысить его читабельность, увеличить быстродействие, получить только уникальные записи. Чтобы уметь пользоваться преимуществами встроенного языка, нужно следовать рекомендациям профессионалов.

Что такое параметры запроса 1С и как они используются?

image001

Рассмотрим на примере присвоения Запросу 1С параметра Текущая дата – выглядеть на языке запросов это будет следующим образом:

image002

Это примитивный тип конструкции, есть и более интересные.

Списочные параметры – работаем с операторами В/В ИЕРАРХИИ

Массив данных и список значений могут быть переданы в качестве параметров языка запроса 1С. К примеру, конструкция может выглядеть следующим образом:

image003

Функции языка запросов 1С v 8

image004

image005

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

image006

Функция языка запросов 1С даёт возможность провести сравнение выбранной строки с шаблонным вариантом. Параметр применяется в том случае, если строка, по которой производится поиск, чётко не закреплена. Шаблонное решение выстраивается по следующим правилам:

image007

Данный параметр работает следующим образом: в том случае, если значение поля не определено, то оно равно указанному выражению. С учётом синтаксиса языка запросов 1С получаем:

image008

  • В результате применения конструкции для соединения данных таблиц, если это не тип внутреннего соединения таблиц;
  • Если произошёл выбор реквизитов, значения которых предопределены исключительно для групп справочников;
  • По итогам выбора графы, находящейся в журнале документа, если у конкретного используемого документа отсутствуют реквизиты, являющиеся составной частью данной графы.

Все эти параметры – лишь краткий перечень эффективных функций языка Запросов 1С. Для грамотной работы в конфигураторе программы необходимо тщательно изучить все параметры языка запросов. Это не просто позволит получать нужные отчёты из базы данных 1С, но и увеличит быстродействие их обработки.

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