Работа с иерархическими детальными записями
Система компоновки данных позволяет выводить в отчет иерархические детальные записи. В данной статье описываются особенности работы с данным механизмом.
При выводе в результат детальных записей система анализирует наличие у выводимого набора данных связи к самому себе. В случае если такая связь обнаружена, система рекурсивно выполняет связь для получения вложенных записей.
Рассмотрим пример. В примере будем выдавать в отчет иерархический справочник номенклатуры.
Запрос набора данных для получения номенклатуры будет выглядеть так:
ВЫБРАТЬ Номенклатура.Ссылка, Номенклатура.Родитель, Номенклатура.Код, Номенклатура.Наименование, Номенклатура.ЭтоГруппаИЗ Справочник.Номенклатура КАК НоменклатураГДЕ Номенклатура.Родитель В(&Родители)
При помощи данного запроса будут получаться записи с указанным родителем. Если параметр Родитель будет содержать пустую ссылку, то будут получены записи, у которых родителей нет, т.е. корневые записи.
Набор данных с указанным запросом назовем Номенклатура.
Для обеспечения вывода иерархии опишем связь набора данных Номенклатура к самому себе.
В качестве выражения — источника будем использовать значение поля Ссылка.
В качестве выражения — приемника буем использовать значение поля Родитель.
Таким образом, для каждой записи набора данных в наборе данных будут искаться записи, у которых поле Родитель имеет значение поля Ссылка родительской записи.
Т.к. запрос получает данные с фильтрацией по родителю, в связи укажем параметр связи «Родитель». Таким образом, при получении дочерних записей система будет передавать значения поля Ссылка дочернему запросу через этот параметр. Т.к. параметр Родитель используется в конструкции языка запроса В, то в качестве значения параметра система может передавать не одно, а сразу несколько значений. Чтобы система это делала, укажем в связи признак «Список параметров».
Справочник Номенклатура имеет иерархию групп и элементов. При этом дочерние записи могут существовать только у групп. Поэтому, для того, чтобы система не осуществляла поиск дочерних записей не у групповых записей, укажем в связи условие связи: «ЭтоГруппа». Таким образом, система будет выполнять запросы для получения дочерних записей только для тех записей, у которых значение поля ЭтоГруппа имеет значение Истина, т.е. только для групп.
Последнее, что нам нужно сделать, это указать, с какого значения система должна начинать получать иерархические записи. Делается это при помощи свойства связи «Начальное значение связи». Нам нужно, чтобы на первом уровне отчета выдавались записи, у которых родитель отсутствует. Поэтому в качестве начального значения связи укажем выражение «Значение(Справочник.Номенклатура.ПустаяСсылка)» (без кавычек). Таким образом, при первом получении данных из набора данных система будет получать записи, у которых значение поля Родитель равно пустой ссылке, т.е. корневые записи.
На следующем рисунке показана полностью заполненная связь в конструкторе схемы:
Для вывода в результат такого набора данных достаточно вывести в результат детальные записи с нужными полями.
Для этого добавим в настройки детальные записи (группировку без полей группировки) и выберем поля, которые мы хотели бы видеть в результате:
Результат такого отчета будет выглядеть следующим образом:
Код | Наименование |
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с
Ключевые слова: родитель, элемент, группа, справочник, перенос
Родитель – это группа (папка), которой принадлежит элемент.
Основные методы работы с родителем:
Все примеры рассматриваются для справочников, в которых установлен Переключатель «Серии Кодов» — «Во всем справочнике»
Иначе, используемая автором функция Спр.НайтиПоКоду() мягко говоря может дать непредсказуемый результат.
Выбор всех элементов, принадлежащих группе:
//Выбираем элементы, лежащие в группе с кодом Гл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">Капуста" Тогда
Что такое родитель в 1с
Добрый день кто подскажет как родителя в справочнике при создании элемента определять автоматом, т.е. в справочник ВИДЫ РАБОТ, пользователь вносит элемент, мне нужно чтобы автоматом у этого элемента проставился родитель = текущему пользователю.
Родитель в терминологии 1С это группа, в которой создается элемент справочника, а не пользователь, который его «родил».
Что вы сделать пытаетесь?
(0) Это называется «ОбработкаЗаполнения()». Располагается в модуле объекта.
(2) А в поле Владелец необходимо вписать Ф.И.О. генерального директора!
(1) У меня есть пользователи (они же службы предприятия), каждый в справочник заносит виды работ, у меня в справочнике для каждого пользователя группа, я хочу чтобы при создании элемента, группа уже была заполнена под конкретного пользователя а не выбирать ее руками
(4) ну «прибей» пользователю группу справочника-родителя в реквизиты или настройки и бери от пользователя
(4) тогда сделай в системе связку — Пользователь-Группа, например доп свойство юзеру назначь, и заполняй в обработке заполнения согласно связке
(5) (6) так вот и вопрос как это сделать
(7) Перечитай ещё раз (2) и (6)
Глака Заполнять из данных заполнения
(9) Я далек походу от этой темы, как пользователя с группой связать, где галку ставить или мне надо программно писать. Мозг уже плывет
(11) Как связать пользователя с группой это ты сам придумай. Можно настройку пользователя добавить по аналогии с организацией по умолчанию, например.
(11) Надо программно писать.
Можно примерный визуальный код Обработки заполнения.
(13) Ты главное не пугайся. Программа будет не очень сложная. Всего одна строка.
родитель=справочники.видыработ.найтипонаименованию(«имяпользователя»);
(16) Спасибо буду пробовать)))
(16) Не работает, родитель не заполняется никак, даже если написать Объект.Родитель = «Электроцех»
(18) Правильно. Родитель — не строка. Родитель — это ссылка на элемент справочника. Если в справочнике есть группа с именем «Электроцех», надо писать
родитель=справочники.видыработ.найтипонаименованию(«Электроцех»);
с соблюдением регистра букв
(19) Так по вашему коду он будет искать элемент справочника а не название групп
(20) Поиск сквозной по группам и элементам.
ну значит не работает он
как открывало пустой так и открывает
(22) А все потомучто нельзя обратиться к справачнику на клиенте а как реализовать не знаю
(23) Модуль объекта работает на сервере.
(23) Мальчик, отойди от компьютера и позови взрослых
Я понимаю но если пишешь с контекстом НаСервере ничего не выдается, соответсвенно ваш код не правильный
(25) попросил бы без оскорблений, уверен и ты девочка не мастер класс в 1С, если бы таковой Вы были, вы бы помогли, а не кидались фразами из синтаксис помощника.
(26) А вы точно получили объект, в нужном месте указали строку из (16) и записали объект?
(26) чем помочь? Вы элементарных вещей не знаете и не понимаете. И с орфографией беда. Я не мастер класс, это точно, я специалист.
(26) Код, который пишешь, выкладывай.
Всем спасибо! Заработало (19)! Была ошибка с наименованием! За ошибки в орфографии извиняюсь, может не заметил, просто не люблю когда переходят на личности. (28), Вы знаете даже элементарные вещи бывают тяжелыми, когда в них ни разу не вникал за ненадобностью, я начинающий 1С программист, пишу только третью разработку самостоятельно, с чем не встречался и в чем не помогла книга спрашиваю, у хороших людей на данном форуме. Когда-то и Вы начинали и не думаю что у Вас все гладко было даже в элементарном, если ошибаюсь, тогда я Вам завидую!
Использование свойства РодительВерхнегоУровня расширения табличного поля списка
Если табличное поле отображает данные в виде дерева или иерархического списка, то может возникнуть ситуация, когда необходимо отобразить данные, начиная только с определенного уровня иерархии, включая все подчиненные уровни. Для решения данной задачи предназначено свойство РодительВерхнегоУровня расширений табличных полей списков справочников, планов видов характеристик, а также для списков планов счетов. В качестве значения данного свойства используется значение, идентифицирующее строку отображаемого списка или значение Неопределено . Если данное свойство имеет значение Неопределено , то табличное поле отображает весь список, начиная с верхнего уровня иерархии, иначе в табличном поле отображаются только строки, подчиненные указанной строке. В данном случае, свойство РодительВерхнегоУровня содержит родителя верхнего уровня иерархии, начиная с которого отображаются данные в табличном поле.
Использование данного свойства может быть полезно в случае, когда необходимо ограничить выбор элементов из иерархического справочника. Например, пусть существует справочник контрагентов, состоящий из двух групп элементов: поставщиков и покупателей. Также существует два списка документов, содержащих приходные и расходные накладные. Требуется осуществлять выбор из группы поставщиков данного справочника для списка приходных накладных, и из группы покупателей для списка расходных накладных. Выбор контрагента осуществляется в форме редактирования документа. Следовательно, для реализации данной задачи необходимо воспользоваться событием Начало выбора() поля ввода, в котором редактируется контрагент.
Поясним использование данного метода на примере списка приходных накладных.
В обработчике события Начало выбора() поля ввода нужно получить ссылку на группу «Поставщики» справочника контрагенты. Для этого можно воспользоваться методом НайтиПоНаименованию() менеджера справочника контрагентов. Для передачи полученной ссылки в форму выбора контрагентов необходимо создать в данной форме специальный реквизит РодительВерхнегоУровня и присвоить полученную ссылку этому реквизиту. Затем, в обработчике события При открытии() формы выбора необходимо присвоить значение данного реквизита свойству РодительВерхнегоУровня расширения табличного поля списка справочника.
В нашем случае в форме выбора расположено два табличных поля, отображающих список контрагентов в виде дерева и иерархического списка. Поэтому полученную ссылку необходимо присвоить обоим табличным полям.
Пример обработки события Начало выбора() приведен ниже:
ФормаВыбора ФормаВыбора ПоставщикиСсылка Пример обработки события При открытии() формы выбора контрагентов приведен ниже:
В результате в форме выбора контрагентов будут отображаться только поставщики.
Аналогичным образом можно установить ограничение на отображение в форме выбора только элементов, принадлежащих группе «Покупатели». Стоит отметить, что способ получения ссылки на группу справочника по наименованию приведен для примера, и правильней использовать другой способ определения группы.