Приветствуем вас, коллеги! Сегодня мы детально разберем крайне интересную и в то же время коварную проблему, с которой часто сталкиваются разработчики на платформе 1С:Предприятие при работе со справочниками в режиме обычных форм. Представьте ситуацию: у вас есть справочник, для которого настроен вид иерархии «Иерархия элементов» (когда один элемент подчинен другому напрямую, без использования папок и групп). Вы выводите этот справочник на форму в виде табличного поля с типом СправочникСписок. Однако на практике дерево элементов ведет себя неадекватно: дочерние элементы третьего уровня отображаются на втором уровне, у их реального родителя отсутствует значок «плюс»/«минус», а при сворачивании корневого элемента подчиненные элементы просто «выпадают» из видимости.
Проанализируем эту ситуацию, выясним, почему платформа ведет себя подобным образом, и разберем по шагам, как вернуть списку правильный иерархический вид.
Это наиболее распространенная техническая причина описанного поведения дерева. В конфигураторе для справочника может быть включено свойство «Ограничивать количество уровней» и установлено конкретное «Количество уровней» (например, 2). При этом в саму базу данных физически были записаны элементы с нарушением этого правила — то есть с фактической вложенностью в 3 или более уровней.
Выясним, как данные с некорректной иерархией могут попасть в базу данных вопреки ограничению метаданных:
ОбменДанными.Загрузка = Истина, платформа игнорирует ограничение на количество уровней вложенности и записывает элемент на любую глубину.Рассмотрим пример кода, который мог привести к записи некорректной иерархии:
// Пример программной записи элемента на недопустимую глубину
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Ручной инструмент";
НовыйЭлемент.Родитель = СсылкаНаИнструменты; // Ссылка на элемент 2-го уровня
НовыйЭлемент.ОбменДанными.Загрузка = Истина; // Обход ограничений метаданных
НовыйЭлемент.Записать();
Посмотрим, почему интерфейс платформы 1С реагирует на это искажением дерева:
Как исправить:
Если на табличное поле наложен программный или интерактивный отбор (фильтр), поведение дерева в режиме иерархии элементов резко меняется. В этом заключается ключевое отличие от иерархии групп и элементов.
При «иерархии групп и элементов» отборы накладываются только на конечные элементы, а группы (папки) всегда остаются видимыми, чтобы пользователь мог ориентироваться в структуре. При «иерархии элементов» деления на группы и элементы нет — все записи являются элементами. Отбор накладывается на абсолютно все строки справочника.
Если элемент «Инструменты» по какому-то критерию не подошел под условия текущего отбора, платформа скрывает его. Но если его подчиненные («Ручной инструмент») под отбор подходят, платформа обязана их вывести. Из-за этого структура дерева рушится: подчиненные элементы отрываются от своего родителя и выводятся на самом верхнем доступном уровне (в корне или под дедушкой «Запчасти»). При этом у родителя пропадают знаки иерархии.
Как исправить:
Проверьте, не установлены ли на табличное поле скрытые отборы (в свойствах объекта, в коде при инициализации формы или через настройки списка). Если отбор необходим, для сохранения строгой иерархии элементов стандартный СправочникСписок не подойдет. В таком случае нам придется строить дерево программно через запрос и выводить его в ДеревоЗначений.
Проанализируем пример запроса для построения иерархического дерева вручную:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Код КАК Код
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления
|ИТОГИ ПО
| Ссылка ИЕРАРХИЯ";
ДеревоДанных = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
// Полученное дерево значений можно связать с табличным полем на форме
В обычных формах 1С 8.2/8.3 за отрисовку дерева отвечает не сама платформа автоматически, а конкретные настройки элемента управления ТабличноеПоле на форме. Если вы случайно изменили свойства элемента управления, дерево может перестать отображаться.
Разберем основные свойства табличного поля, которые необходимо проверить:
Проверить и установить эти свойства можно также программно при открытии формы:
Процедура ПриОткрытии()
// Убедимся, что табличное поле отображает дерево
ЭлементыФормы.СправочникСписок.Дерево = Истина;
// Включаем отображение иерархии для колонки "Наименование"
ЭлементыФормы.СправочникСписок.Колонки.Наименование.ОтображатьИерархию = Истина;
КонецПроцедуры
Подводя итог, если вы столкнулись с «выпадением» элементов из иерархического списка в 1С, рекомендуем придерживаться следующего алгоритма диагностики:
Дерево и ОтображатьИерархию самого табличного поля формы.Для предотвращения подобных сбоев в будущем всегда контролируйте корректность родительских связей при программном импорте данных и избегайте необоснованного ограничения уровней иерархии в метаданных, если бизнес-логика допускает глубокую вложенность элементов. Правильно сопоставить объекты при миграции поможет обработка для переноса данных между похожими конфигурациями 1С.