Как реализовать автоматическую подстановку значения подчиненного справочника при выборе владельца?

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

В разработке на платформе 1С:Предприятие 8.3 часто возникает задача автоматизации ввода данных. Типичный сценарий: в документе есть два поля, например, «Оснастка» и «Чертеж». Справочник «Чертежи» подчинен справочнику «Оснастка». Мы хотим, чтобы при выборе конкретной оснастки поле с чертежом заполнялось автоматически, если это возможно, чтобы избавить пользователя от лишних кликов. В этой статье мы разберем несколько способов реализации этой задачи: от простых настроек свойств до программного кода.

Метод 1. Использование механизма «Связи параметров выбора»

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

Рассмотрим, как это настроить по шагам:

  1. Откроем форму документа или свойства реквизита в дереве метаданных.
  2. Найдем реквизит, который должен заполняться (например, Чертеж).
  3. В палитре свойств найдем пункт Связи параметров выбора.
  4. Нажмем на кнопку выбора и добавим новую связь: в колонке «Параметр выбора» укажем Отбор.Владелец, а в колонке «Путь к данным» — имя поля, которое является владельцем (например, Объект.НаименованиеМодельнойОснастки).

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

Метод 2. Программная подстановка через событие ПриИзменении

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

Проанализируем ситуацию: на стороне клиента нам недоступны запросы к базе данных, поэтому основную логику поиска значения мы вынесем в серверную функцию. Рассмотрим пример кода:


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

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

Теперь разберем серверную часть. Для оптимизации работы мы используем директиву &НаСервереБезКонтекста. Это позволяет не передавать всю форму на сервер, что значительно ускоряет работу системы, особенно в условиях медленного интернет-соединения.


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

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

Метод 3. Обработка ситуации с несколькими подчиненными элементами

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

  1. Использование признака «Основной»: Добавим в справочник Чертежи реквизит типа Булево с названием Основной. В запросе выше добавим условие: ГДЕ Чертежи.Владелец = &Владелец И Чертежи.Основной = ИСТИНА. Это гарантирует подстановку именно той записи, которую администратор или ответственный пометил как приоритетную.
  2. Проверка на количество: Если подчиненных элементов больше одного, мы можем не заполнять поле автоматически, а программно вызвать выпадающий список выбора, чтобы пользователь сам принял решение.

Метод 4. Очистка зависимых данных

Важным моментом, который часто упускают начинающие разработчики, является поддержание актуальности данных. Если пользователь сначала выбрал «Оснастку А» и «Чертеж А.1», а затем передумал и выбрал «Оснастку Б», поле чертежа должно быть либо очищено, либо перезаполнено.

Рассмотрим пример логики очистки: в начале процедуры НаименованиеМодельнойОснасткиПриИзменении всегда стоит проверять, принадлежит ли текущий Чертеж новому Владельцу. Если нет — поле Чертеж обязательно нужно очистить. Это предотвратит логические ошибки в базе данных, когда в документе указан чертеж, не имеющий отношения к выбранной оснастке.

Метод 5. Дополнительная валидация на сервере

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


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

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

← На главную