Итоги по иерархия

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

Использование данного свойства может быть полезно в случае, когда необходимо ограничить выбор элементов из иерархического справочника. Например, пусть существует справочник контрагентов, состоящий из двух групп элементов: поставщиков и покупателей. Также существует два списка документов, содержащих приходные и расходные накладные. Требуется осуществлять выбор из группы поставщиков данного справочника для списка приходных накладных, и из группы покупателей для списка расходных накладных. Выбор контрагента осуществляется в форме редактирования документа. Следовательно, для реализации данной задачи необходимо воспользоваться событием Начало выбора() поля ввода, в котором редактируется контрагент.

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

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

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

Пример обработки события Начало выбора() приведен ниже:

Пример обработки события При открытии() формы выбора контрагентов приведен ниже:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Программирование системы 16.06.2016 16:33 11945

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

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

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

Определить самого верхнего родителя

Универсальную функцию для определения самого верхнего родителя элемента можно реализовать с помощью встроенного языка программирования. Функции на вход подаётся ссылка на элемент иерархического справочника, а возвращается ссылка на самую верхнюю группу.

Определить самого верхнего родителя с использованием запроса

Для того чтобы добавить сообщение, необходимо Войти или Зарегистрироваться

Оглавление (нажмите, чтобы раскрыть)

Итоги без агрегации

Пример вывода итогов без агрегации //добаляем группировочные строки по //иерархии материалов //без подсчета итоговых остатков Запрос = Новый Запрос; Запрос.Текст = «ВЫБРАТЬ | Материал, | КоличествоОстаток КАК Количество |ИЗ | РегистрНакопления.ОстаткиМатериалов.Остатки |ИТОГИ |ПО | Материал ИЕРАРХИЯ»; Выборка = Запрос.Выполнить().Выбрать( ОбходРезультатаЗапроса.ПоГруппировкам); Пока Выборка.Следующий() Цикл Отступ = «»; Для Н = 0 По Выборка.Уровень() — 1 Цикл Отступ = Отступ + Символы.Таб; КонецЦикла; Если Выборка.ТипЗаписи() <> ТипЗаписиЗапроса.ИтогПоГруппировке Тогда //для обычной записи отображаем результат Сообщить(Отступ + Выборка.Материал); Иначе //для итоговой записи бежим по вложенным записям ВыборкаМатериал = Выборка.Выбрать(); Пока ВыборкаМатериал.Следующий() Цикл Сообщить(Отступ + ВыборкаМатериал.Материал + «: » + ВыборкаМатериал.Количество); КонецЦикла; КонецЕсли; КонецЦикла; //Пример результата: //Материалы // Радиодетали // Трансформатор: 3 // Транзистор: 5 // Прочие // Шланг: 12

Итоги по иерархии

Пример вывода итогов по иерархии //добаляем группировочные строки по //иерархии материалов //с подсчетом итоговых остатков Запрос = Новый Запрос; Запрос.Текст = «ВЫБРАТЬ | Материал, | КоличествоОстаток КАК Количество |ИЗ | РегистрНакопления.ОстаткиМатериалов.Остатки |ИТОГИ | СУММА(КоличествоОстаток) |ПО | Материал ИЕРАРХИЯ»; Выборка = Запрос.Выполнить().Выбрать( ОбходРезультатаЗапроса.ПоГруппировкам); Пока Выборка.Следующий() Цикл Отступ = «»; Для Н = 0 По Выборка.Уровень()-1 Цикл Отступ = Отступ + Символы.Таб; КонецЦикла; Сообщить(Отступ + Выборка.Материал + «: » + Выборка.Количество); КонецЦикла; //Пример результата: //Материалы: 20 // Радиодетали: 8 // Трансформатор: 3 // Транзистор: 5 // Прочие: 12 // Шланг: 12

Итоги по полю

Пример вывода итогов по полю //Оператор ИТОГИ добавляет к результатам //запроса группирующие строки //Выбираем суммы начислений по //сотруднику и виду расчета. //Затем добавляем строки с итоговыми //суммами по виду рачета. Запрос = Новый Запрос; Запрос.Текст = «ВЫБРАТЬ | ВидРасчета, | Сотрудник, | Результат |ИЗ | РегистрРасчета.Начисления |ИТОГИ | СУММА(Результат) |ПО | ВидРасчета»; Выборка = Запрос.Выполнить().Выбрать( ОбходРезультатаЗапроса.ПоГруппировкам); //цикл по группирующим строкам Пока Выборка.Следующий() Цикл Сообщить(«» + Выборка.ВидРасчета + «: » + Выборка.Результат); ВыборкаСотр = Выборка.Выбрать(); //цикл по подчиненным строкам Пока ВыборкаСотр.Следующий() Цикл Сообщить(» » + ВыборкаСотр.Сотрудник + «: » + ВыборкаСотр.Результат); КонецЦикла; КонецЦикла; //Пример результата: //Оклад: 13500 // Иванов: 7000 // Петров: 6500 //Премия: 700 // Иванов: 700

Итоги только по иерархии

Пример вывода итогов только по иерархии //получаем только группировочные строки по //иерархии материалов //с подсчетом итоговых остатков Запрос = Новый Запрос; Запрос.Текст = «ВЫБРАТЬ | Материал, | КоличествоОстаток КАК Количество |ИЗ | РегистрНакопления.ОстаткиМатериалов.Остатки |ИТОГИ | СУММА(КоличествоОстаток) |ПО | Материал ТОЛЬКО ИЕРАРХИЯ»; Выборка = Запрос.Выполнить().Выбрать( ОбходРезультатаЗапроса.ПоГруппировкам); Пока Выборка.Следующий() Цикл Отступ = «»; Для Н = 0 По Выборка.Уровень()-1 Цикл Отступ = Отступ + Символы.Таб; КонецЦикла; Сообщить(Отступ + Выборка.Материал + «: » + Выборка.Количество); КонецЦикла; //Пример результата: //Материалы: 20 // Радиодетали: 8 // Прочие: 12

Общие итоги

Пример вывода общих итогов //получаем только группировочные строки по //иерархии материалов //с подсчетом итоговых остатков Запрос = Новый Запрос; Запрос.Текст = «ВЫБРАТЬ | Материал, | КоличествоОстаток КАК Количество |ИЗ | РегистрНакопления.ОстаткиМатериалов.Остатки |ИТОГИ | СУММА(КоличествоОстаток) |ПО | Материал ТОЛЬКО ИЕРАРХИЯ»; Выборка = Запрос.Выполнить().Выбрать( ОбходРезультатаЗапроса.ПоГруппировкам); Пока Выборка.Следующий() Цикл Отступ = «»; Для Н = 0 По Выборка.Уровень()-1 Цикл Отступ = Отступ + Символы.Таб; КонецЦикла; Сообщить(Отступ + Выборка.Материал + «: » + Выборка.Количество); КонецЦикла; //Пример результата: //Материалы: 20 // Радиодетали: 8 // Прочие: 12

Общие итоги и итоги по полю

Пример вывода общих итогов и итогов по полю //Выбираем суммы начислений по //сотруднику и виду расчета. //Затем добавляем строку с общей //суммой по всем начислениям и //и строки с суммами по виду расчета. Запрос = Новый Запрос; Запрос.Текст = «ВЫБРАТЬ | ВидРасчета, | Сотрудник, | Результат |ИЗ | РегистрРасчета.Начисления |ИТОГИ | СУММА(Результат) |ПО | ОБЩИЕ, | ВидРасчета»; Выборка = Запрос.Выполнить().Выбрать( ОбходРезультатаЗапроса.ПоГруппировкам); //выводим итоговые данные Если Выборка.Следующий() Тогда Сообщить(«Итого: » + Выборка.Результат); ВыборкаВидРачета = Выборка.Выбрать( ОбходРезультатаЗапроса.ПоГруппировкам); //цикл по видам расчета Пока ВыборкаВидРачета.Следующий() Цикл Сообщить(» » + ВыборкаВидРачета.ВидРасчета + «: » + ВыборкаВидРачета.Результат); ВыборкаСотр = ВыборкаВидРачета.Выбрать(); //цикл по подчиненным строкам Пока ВыборкаСотр.Следующий() Цикл Сообщить(» » + ВыборкаСотр.Сотрудник + «: » + ВыборкаСотр.Результат); КонецЦикла; КонецЦикла; КонецЕсли; //Пример результата: //Итого: 14200 // Оклад: 13500 // Иванов: 7000 // Петров: 6500 // Премия: 700 // Иванов: 700