Почему в форме выбора справочника не работает режим Дерево и Иерархический список, но работает Список?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

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

 

Физика процесса: почему ломаются режимы просмотра дерева?

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

Рассмотрим, как функционируют эти режимы «изнутри»:

  1. Режим «Список» (плоский вид):

    В данном режиме платформа полностью игнорирует иерархические связи справочника. Происходит выполнение стандартного плоского запроса к базе данных. Если на список наложен скрытый (неявный) отбор, например, по родителю или по владельцу (скажем, Родитель = ПустаяСсылка или Владелец = ПустаяСсылка), СУБД вернет ровно те записи, которые соответствуют этому условию.

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

  2. Режимы «Дерево» и «Иерархический список»:

    В этих режимах динамический список пытается построить сложную иерархическую структуру отношений «родитель — потомок». Логика наложения отборов в дереве имеет свои особенности:

    • Согласно стандартам платформы 1С, отбор по обычным реквизитам не скрывает родительские группы, если в них есть элементы, удовлетворяющие условию отбора. Но если отбор накладывается непосредственно на ключевые реквизиты связи — такие как Родитель или Владелец — то логика построения дерева нарушается.
    • Если на форму выбора неявно наложен жесткий отбор Родитель = ПустаяСсылка, то динамический список честно выберет из базы данных только корневые элементы. Попытка раскрыть любую из этих папок (нажав на «плюсик») ни к чему не приведет. Платформа попытается запросить подчиненные элементы, у которых поле Родитель равно ссылке на текущую группу, но этот запрос будет заблокирован глобальным отбором Родитель = ПустаяСсылка. В результате подчиненные элементы отсекаются, и дерево «сворачивается» до корневых узлов без возможности раскрытия.
    • В режиме «Иерархический список» ситуация аналогична: если текущий отбор исключает элементы, которые должны отображаться на текущем уровне иерархии, список будет абсолютно пустым.

 

Главный источник проблемы: неявные настройки метаданных

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

Выясним причину появления этой проблемы на практике. Довольно часто новые документы или реквизиты создаются путем копирования или «перетаскивания» существующих реквизитов других объектов в дереве метаданных конфигуратора. Вместе с реквизитом копируются и его внутренние свойства, о которых разработчик может забыть. К таким свойствам относятся:

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

 

Пошаговая инструкция по диагностике и устранению проблемы

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

Шаг 1. Анализ метаданных реквизита

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

  1. Найдите проблемный документ в дереве метаданных конфигурации.
  2. Разверните список его реквизитов (или реквизитов табличной части) и откройте палитру свойств того реквизита, при выборе которого открывается проблемная форма.
  3. Прокрутите список свойств до раздела «Параметры выбора» и «Связи параметров выбора».
  4. Проверьте, установлены ли там какие-либо значения. Если вы обнаружите там старые связи, оставшиеся после копирования реквизита (например, связь по родителю или владельцу с реквизитами, которых нет на новой форме), очистите их.

Шаг 2. Программный перехват отборов в отладчике

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

Для этого выполним следующие действия:

  1. Если у вашего справочника нет собственной формы выбора, временно создайте ее в конфигураторе через конструктор (просто пустую форму выбора по умолчанию).
  2. В модуле этой созданной формы выбора найдите или создайте обработчик события ПриСозданииНаСервере.
  3. Установите точку останова внутри этой процедуры.
  4. Запустите сеанс в режиме «1С:Предприятие», откройте проблемный документ и нажмите кнопку выбора в поле реквизита.
  5. При срабатывании точки останова добавьте в табло отладки переменную Параметры.

Рассмотрим структуру параметров, которую мы увидим в отладчике. Нас интересует свойство Параметры.Отбор. Это структура, содержащая все отборы, которые платформа применила к динамическому списку формы выбора при ее инициализации.

Пример программного анализа параметров выбора в коде формы выбора:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проанализируем, какие скрытые отборы пришли в форму выбора
    Если Параметры.Свойство("Отбор") Тогда
        Для Каждого ЭлементОтбора Из Параметры.Отбор Цикл
            // Выведем в окно сообщений имя поля отбора и его значение
            Сообщить("Поле отбора: " + ЭлементОтбора.Ключ + "; Значение: " + ЭлементОтбора.Значение);
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

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

 

Шаг 3. Исправление связей на уровне элементов управляемой формы

Иногда связи параметров выбора могут быть переопределены непосредственно в свойствах элемента формы (в окне «Элементы» управляемой формы документа). Проверим и эту гипотезу:

  1. Откройте форму проблемного документа в конфигураторе.
  2. В списке элементов формы найдите поле ввода, соответствующее нашему реквизиту.
  3. Откройте его свойства и найдите свойства «Связи параметров выбора» и «Параметры выбора».
  4. Убедитесь, что там нет некорректных путей к данным. При необходимости удалите ошибочные настройки.

 

Альтернативное решение: программная установка параметров выбора

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

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


&НаКлиенте
Процедура ИмяРеквизитаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    // Отменяем стандартное открытие формы, чтобы настроить параметры вручную
    СтандартнаяОбработка = Ложь;
    
    // Формируем структуру параметров для открытия формы выбора
    ПараметрыВыбора = Новый Структура;
    
    // Задаем структуру отбора, которая не сломает дерево иерархии
    СтруктураОтбора = Новый Структура;
    // Например, отбираем только по какому-то пользовательскому реквизиту, не трогая Родителя
    СтруктураОтбора.Вставить("ПометкаУдаления", Ложь); 
    
    ПараметрыВыбора.Вставить("Отбор", СтруктураОтбора);
    
    // Открываем форму выбора справочника программно с нашими параметрами
    ОткрытьФорму("Справочник.ИмяВашегоСправочника.ФормаВыбора", ПараметрыВыбора, Элемент);
    
КонецПроцедуры

Такой подход гарантирует, что на форму выбора будут переданы только те параметры, которые вы явно указали в коде, исключая влияние скрытых настроек метаданных, скопированных из других объектов. Это позволяет избежать «поломок» режимов отображения дерева и обеспечивает стабильную работу интерфейса вашей конфигурации.

← На главную