Что такое родитель в 1с
Перейти к содержимому

Что такое родитель в 1с

  • автор:

Работа с иерархическими детальными записями

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

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

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

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

ВЫБРАТЬ Номенклатура.Ссылка, Номенклатура.Родитель, Номенклатура.Код, Номенклатура.Наименование, Номенклатура.ЭтоГруппаИЗ Справочник.Номенклатура КАК НоменклатураГДЕ Номенклатура.Родитель В(&Родители)

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

Набор данных с указанным запросом назовем Номенклатура.

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

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

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

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

Т.к. запрос получает данные с фильтрацией по родителю, в связи укажем параметр связи «Родитель». Таким образом, при получении дочерних записей система будет передавать значения поля Ссылка дочернему запросу через этот параметр. Т.к. параметр Родитель используется в конструкции языка запроса В, то в качестве значения параметра система может передавать не одно, а сразу несколько значений. Чтобы система это делала, укажем в связи признак «Список параметров».

Справочник Номенклатура имеет иерархию групп и элементов. При этом дочерние записи могут существовать только у групп. Поэтому, для того, чтобы система не осуществляла поиск дочерних записей не у групповых записей, укажем в связи условие связи: «ЭтоГруппа». Таким образом, система будет выполнять запросы для получения дочерних записей только для тех записей, у которых значение поля ЭтоГруппа имеет значение Истина, т.е. только для групп.

Последнее, что нам нужно сделать, это указать, с какого значения система должна начинать получать иерархические записи. Делается это при помощи свойства связи «Начальное значение связи». Нам нужно, чтобы на первом уровне отчета выдавались записи, у которых родитель отсутствует. Поэтому в качестве начального значения связи укажем выражение «Значение(Справочник.Номенклатура.ПустаяСсылка)» (без кавычек). Таким образом, при первом получении данных из набора данных система будет получать записи, у которых значение поля Родитель равно пустой ссылке, т.е. корневые записи.

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

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

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

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

Код Наименование
0000001 Мониторы
0000021 Монитор 15′ LG Studioworks 575N
0000022 Монитор 17′ Philips 107S20
0000023 Монитор 19′ Hitachi CM715ET
0000024 Монитор LCD 22′ M8537ZM/A
0000002 Системные блоки и комплектующие
0000036 Сист. блок Hewlett-Packard Brio BA410
0000037 Сист. блок Hewlett-Packard Vectra VL420
0000038 Сист. блок IBM NetVista A22p
0000039 Сист. блок IBM NetVista M41
0000003 Принтеры
0000030 Лазерный принтер Canon LBP-810
0000031 Лазерный принтер 5250197-203 Minolta-QMS
0000032 Лазерный принтер HP LaserJet 2200
0000004 Мыши
0000025 Мышь 2-кноп A4Tech PS/2
0000026 Мышь OK-720 Mouse A4Tech PS/2
0000027 Мышь Ice Mouse MUS-2
0000028 Мышь LOGITECH M-S48 PS/2
0000029 Мышь GENIUS «EASY» (3 кнопки),
0000005 Клавиатуры
0000018 Клавиатура Apple Pro Keyboards
0000020 Клавиатура LK-601 KB-2000 PS/2
0000006 Программное обеспечение
0000045 Windows
0000009 Windows XP Home Edition Russian CD
0000010 Windows XP Home Edition Russian UPG CD
0000011 Windows XP Professional Russian CD
0000012 1С:Бухгалтерия 7.7 Базовая версия
0000013 1С:Бухгалтерия 7.7 Стандартная версия
0000014 1С:Бухгалтерия ПРОФ версия 7.7
0000015 1С:Аспект 7.7
0000016 1С:Торговля и Склад 7.7 Проф
0000007 Услуги
0000041 Доставка
0000042 Инсталляция ПО
0000043 Консультации по настройке ОС Windiws
0000044 Консультации по настройке 1С
0000033 Ноутбуки
0000034 Ноутбук Rover Computers Navigator KT7
0000035 Ноутбук Rover Computers Explorer
0000046 Телефоны
0000047 Телефон Vega 700
0000048 Телефон Vega 300
0000051 Телефон Siemens SL45
0000052 Телефон LG W7200
0000049 Копировальные аппараты
0000050 Копировальный аппарат Omega

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

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

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

РодительСсылка = СправочникСсылка.Родитель.Родитель.Родитель; 

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

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

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

Функция ПолучитьРодителя(СправочникСсылка) 

Пока НЕ СправочникСсылка.Родитель.Пустая() Цикл
СправочникСсылка = СправочникСсылка.Родитель;
КонецЦикла;

Возврат СправочникСсылка;

КонецФункции

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

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

Функция ПолучитьРодителейЗапросе(СправочникСсылка) 

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Справочник1.Родитель.Родитель.Родитель КАК Родитель
|ИЗ
| Справочник.Справочник1 КАК Справочник1
|ГДЕ
| Справочник1.Ссылка = &Справочник1Ссылка"
;

Запрос.УстановитьПараметр("Справочник1Ссылка", СправочникСсылка);
Результат = Запрос.Выполнить();

Если НЕ Результат.Пустой() Тогда

Выборка = Результат.Выбрать();
Выборка.Следующий();
Возврат Выборка.Родитель;

КонецЕсли;

Возврат Справочники.Справочник1.ПустаяСсылка();

КонецФункции

Комментарии (0)

О сайте Обратная связь Правила Новости 1С Copyright © 2023
Цитирование материалов (тексты, изображения, программный код) допускается только с размещением активной ссылки на сайт 1CLenta.ru

Что такое родитель в 1с

Родитель – это группа (папка), которой принадлежит элемент.

Основные методы работы с родителем:

Все примеры рассматриваются для справочников, в которых установлен Переключатель «Серии Кодов» — «Во всем справочнике»
Иначе, используемая автором функция Спр.НайтиПоКоду() мягко говоря может дать непредсказуемый результат.

Выбор всех элементов, принадлежащих группе:

//Выбираем элементы, лежащие в группе с кодом Гл005172 Спр = СоздатьОбъект("Справочник.Номенклатура"); Если Спр.НайтиПоКоду("Гл005172") = 1 Тогда Спр.ИспользоватьРодителя(Спр.ТекущийЭлемент()); КонецЕсли; Спр.ВыбратьЭлементы(); Пока Спр.ПолучитьЭлемент() = 1 Цикл Сообщить(Спр.ТекущийЭлемент()); КонецЦикла;

Выбор элементов, непосредственно принадлежащих выбранной группе.

//Выбираем элементы, непосредственно принадлежащих группе с кодом Гл005172 Спр = СоздатьОбъект("Справочник.Номенклатура"); Если Спр.НайтиПоКоду("Гл005172") = 1 Тогда Ур = Спр.ТекущийЭлемент().Уровень() + 1; Спр.ИспользоватьРодителя(Спр.ТекущийЭлемент()); Спр.ВыбратьЭлементы(); Пока Спр.ПолучитьЭлемент() = 1 Цикл Если Спр.ТекущийЭлемент().Уровень() = Ур Тогда Сообщить(Спр.ТекущийЭлемент()); КонецЕсли; КонецЦикла; КонецЕсли;

Здесь проверяется уровень элементов и выбираются только те, чей уровень на 1 больше, чем у выбранной группы. Если нужно выбрать только элементы без групп, тогда нужно добавить проверку на ЭтоГруппа().
А если заюзать чудный метод , то код можно сделать проще:

//Выбираем элементы, непосредственно принадлежащих группе с кодом Гл005172 Спр = СоздатьОбъект("Справочник.Номенклатура"); Если Спр.НайтиПоКоду("Гл005172") = 1 Тогда // Ур = Спр.ТекущийЭлемент().Уровень() + 1; Спр.ИспользоватьРодителя(Спр.ТекущийЭлемент()); Спр.ВключатьПодчиненные(0); //  Спр.ВыбратьЭлементы(); Пока Спр.ПолучитьЭлемент() = 1 Цикл // Если Спр.ТекущийЭлемент().Уровень() = Ур Тогда Сообщить(Спр.ТекущийЭлемент()); // КонецЕсли; КонецЦикла; КонецЕсли;

Изменение родителя уже существующего элемента:

//Переносим элемент с кодом Гл000485 в группу с кодом Гл005172 Спр = СоздатьОбъект("Справочник.Номенклатура"); Если Спр.НайтиПоКоду("Гл005172") = 1 Тогда Род = Спр.ТекущийЭлемент(); Если Спр.НайтиПоКоду("Гл000485") = 1 Тогда Спр.Родитель = Род; Спр.Записать(); КонецЕсли; КонецЕсли;

p.s. Обратите внимание на Спр.Записать() – часто забывают это сделать и изменения не принимаются J
p.p.s Обратите внимание на Спр.Родитель = Род. Часто пишут Спр.ТекущийЭлемент().Родитель = Род и получают ошибку о невозможности перепозиционироваться.

Перенос элементов из одной группы в другую:

//Перенос всех элементов из группы с кодом Гл000476 в группу с кодом Гл005172 Спр = СоздатьОбъект("Справочник.Номенклатура"); Справ = СоздатьОбъект("Справочник.Номенклатура"); Если Спр.НайтиПоКоду("Гл005172") = 1 Тогда Род = Спр.ТекущийЭлемент(); Если Спр.НайтиПоКоду("Гл000476") = 1 Тогда Спр.ИспользоватьРодителя(Спр.ТекущийЭлемент()); Пока Спр.ВыбратьЭлементы() = 1 Цикл Спр.ПолучитьЭлемент(); Спр.Родитель = Род; Спр.Записать(); КонецЦикла; КонецЕсли; КонецЕсли;

Перенос из одной группы в другую только элементов, без групп:

//Перенос всех элементов из группы с кодом Гл000476 в группу с кодом Гл005172 Спр = СоздатьОбъект("Справочник.Номенклатура"); Если Спр.НайтиПоКоду("Гл005172") = 1 Тогда Род = Спр.ТекущийЭлемент(); Если Спр.НайтиПоКоду("Гл000476") = 1 Тогда Спр.ИспользоватьРодителя(Спр.ТекущийЭлемент()); nn = 0; Пока nn = 0 Цикл nn = 1; Спр.ВыбратьЭлементы(); Пока Спр.ПолучитьЭлемент() = 1 Цикл Если Спр.ЭтоГруппа() = 0 Тогда Спр.Родитель = Род; Спр.Записать(); nn = 0; КонецЕсли; КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли;

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

Для проверки принадлежности элемента группе следует использовать метод ПринадлежитГруппе().

P.S. Самая распространенная ошибка — сравнение элемента справочника со строкой. Происходит из-за непонимания, что это разные типы данных.

Если ЭлементСправочника cb">Капуста" Тогда
Если ЭлементСправочника.Наименование cb">Капуста" Тогда

Получить первого родителя справочника

72465

Не устроил ответ?
Зарегистрируйся и задай свой вопрос. Живое общение приносит результат намного быстрее.

Реклама

Новые вакансии

  • Вакансия «Прораммист/разработчи 1С» Екатеринбург от Денис Спеиалист
    22 ноября 2023 г.
  • Вакансия Стажер Аналитик от Elizavetashkr
    17 ноября 2023 г.
  • Вакансия Стажер Программист 1С от Elizavetashkr
    17 ноября 2023 г.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *