Как настроить автоматический выбор типа подчиненного реквизита, если его владелец тоже имеет составной тип?

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

При проектировании сложных конфигураций в среде 1С:Предприятие разработчики часто сталкиваются с необходимостью связывания нескольких реквизитов составного типа. Типичный пример: в документе есть реквизит Учреждение (составной тип, ссылающийся на справочники МуниципальныеУчреждения и ПодведомственныеУчреждения), а также подчиненный реквизит ЗданиеУчреждения (составной тип, ссылающийся на подчиненные справочники ЗданияМуниципальныхУчреждений и ЗданияПодведомственныхУчреждений соответственно).

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

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

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

  1. Выбор типа данных происходит на уровне метаданных. Когда поле ввода в табличной части или на форме имеет составной тип и его текущее значение равно Неопределено, платформа физически не знает, к какой таблице СУБД отправлять запрос на получение списка элементов. Для нее оба подчиненных справочника зданий равнозначны. Поэтому шаг предварительного выбора типа является обязательным техническим условием для инициализации запроса к базе данных.
  2. Связи параметров выбора накладываются позже. Свойство реквизита Связи параметров выбора (в нашем случае отбор Отбор.Владелец(Учреждение)) начинает работать только в момент открытия формы выбора конкретного справочника. Платформа не умеет автоматически сопоставлять типы «на лету» без жестко заданной логики связи типов, так как связь «Владелец — Подчиненный» в метаданных задается для объектов (ссылок на элементы), а не для самих типов данных в интерфейсе поля ввода.
  3. Ограничение стандартного свойства «Связь по типу». Многие разработчики пытаются использовать стандартное свойство Связь по типу (LinkByType) в свойствах реквизита. Однако в платформе 1С этот механизм жестко завязан на работу с Планами видов характеристик (ПВХ) либо с субконто в регистрах бухгалтерии. Напрямую связать два обычных реквизита составного типа через это свойство без участия ПВХ платформа не позволит.

Рассмотрим по шагам решения, которые помогут обойти это ограничение.

Решение №1. Архитектурное объединение справочников (Полностью без программирования)

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

Разберем ситуацию: у нас есть два разных справочника зданий. Если их реквизитный состав во многом совпадает (а для зданий это практически всегда так: адрес, общая площадь, кадастровый номер), то разделение их на два отдельных объекта метаданных является избыточным. Мы можем объединить их в один общий справочник ЗданияУчреждений.

Выполним следующие настройки в конфигураторе:

  1. Создадим один общий справочник ЗданияУчреждений вместо двух старых.
  2. В свойстве Владельцы нового справочника укажем составной тип данных, отметив галочками оба справочника учреждений: СправочникСсылка.МуниципальныеУчреждения и СправочникСсылка.ПодведомственныеУчреждения. Платформа 1С отлично поддерживает работу справочников с составными владельцами.
  3. В нашем документе для реквизита Здание укажем простой, несоставной тип данных — СправочникСсылка.ЗданияУчреждений.
  4. В свойствах реквизита Здание настроим свойство Связи параметров выбора. Добавим новую строку:
    • Имя параметра: Отбор.Владелец
    • Путь к данным: Объект.Учреждение (или Элементы.ИмяТабличнойЧасти.ТекущиеДанные.Учреждение, если реквизит находится в табличной части).

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

Решение №2. Минимальный программный обход (Best Practice)

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

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

Выполним настройку по шагам:

Шаг 1. Отключение выбора типа в интерфейсе.

Откроем форму документа в конфигураторе. Нам нужно найти элемент формы, отображающий реквизит Здание. В свойствах этого поля ввода (в палитре свойств) снимем флаг Выбирать тип (установим его в значение Ложь). Это заблокирует появление стандартного платформенного окна выбора типа при интерактивном нажатии на кнопку выбора.

Шаг 2. Написание обработчика изменения владельца.

Создадим для поля ввода Учреждение на форме обработчик события ПриИзменении. В этом обработчике мы определим тип выбранного учреждения и программно запишем в поле здания пустую ссылку соответствующего справочника зданий. Рассмотрим пример реализации кода для реквизитов табличной части документа:


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

КонецПроцедуры

Шаг 3. Обработка начала редактирования строки.

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


&НаКлиенте
Процедура ТЧПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
    
    Если Не НоваяСтрока Тогда
        Возврат;
    КонецЕсли;
    
    СтрокаТЧ = Элементы.ТабличнаяЧасть.ТекущиеДанные;
    
    Если СтрокаТЧ <> Неопределено И ЗначениеЗаполнено(СтрокаТЧ.Учреждение) Тогда
        
        // Повторяем логику предопределения типа для новых строк
        ТипУчреждения = ТипЗнч(СтрокаТЧ.Учреждение);
        
        Если ТипУчреждения = Тип("СправочникСсылка.МуниципальныеУчреждения") Тогда
            СтрокаТЧ.Здание = ПредопределенноеЗначение("Справочник.ЗданияМуниципальныхУчреждений.ПустаяСсылка");
        ИначеЕсли ТипУчреждения = Тип("СправочникСсылка.ПодведомственныеУчреждения") Тогда
            СтрокаТЧ.Здание = ПредопределенноеЗначение("Справочник.ЗданияПодведомственныхУчреждений.ПустаяСсылка");
        КонецЕсли;
        
    КонецЕсли;

КонецПроцедуры

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

Решение №3. Использование Плана видов характеристик (Классический метод связи по типу)

Если вы хотите настроить связь типов максимально близко к стандартным платформенным механизмам без написания кода в формах документов, можно применить классический паттерн с использованием **Плана видов характеристик (ПВХ)**. Этот способ отлично подходит для гибких, расширяемых систем.

Проанализируем шаги по реализации этого механизма:

  1. Создание ПВХ: Добавим в конфигурацию новый План видов характеристик с именем ТипыУчреждений. В качестве типа значений характеристик (свойство Тип значения) укажем составной тип, содержащий ссылки на наши справочники зданий: СправочникСсылка.ЗданияМуниципальныхУчреждений и СправочникСсылка.ЗданияПодведомственныхУчреждений.
  2. Создание предопределенных элементов: В созданном ПВХ добавим два предопределенных элемента:
    • МуниципальноеУчреждение (с типом значения СправочникСсылка.ЗданияМуниципальныхУчреждений).
    • ПодведомственноеУчреждение (с типом значения СправочникСсылка.ЗданияПодведомственныхУчреждений).
  3. Связывание учреждений с характеристиками: В справочники учреждений добавим реквизит ТипХарактеристики с типом ПланВидовХарактеристикСсылка.ТипыУчреждений. Для муниципальных учреждений заполним его значением МуниципальноеУчреждение, для подведомственных — ПодведомственноеУчреждение (это можно сделать один раз кодом при обновлении информационной базы или сделать реквизит предопределенным/заполняемым при создании).
  4. Настройка реквизитов документа:
    • В документе реквизит Учреждение остается составного типа.
    • Реквизит Здание настраивается с типом данных Характеристика.ТипыУчреждений.
    • В свойствах реквизита Здание находим свойство Связь по типу. В качестве источника связи (поле Связь по типу) выбираем реквизит Учреждение.ТипХарактеристики.

Результат: Благодаря использованию механизма характеристик, платформа «1С:Предприятие» на уровне ядра связывает тип значения реквизита Здание с типом, который прописан в реквизите ТипХарактеристики у выбранного учреждения. Окно выбора типа блокируется автоматически, и платформа сразу переходит к открытию формы списка нужного справочника зданий.

Сравнение и выбор оптимального решения

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

Выбирайте наиболее подходящий под ваши задачи вариант и делайте интерфейсы ваших решений удобными и интуитивно понятными для пользователей!

← На главную