Как изменить представление реквизита Подразделение только в документе Заявка

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

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

Анализ проблемы стандартного обработчика

Рассмотрим код, который часто пытаются использовать начинающие разработчики в модуле менеджера справочника:


Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
    НаименованиеГорода = "";
    Если Данные.Ссылка <> Неопределено Тогда
        СтандартнаяОбработка = Ложь;
        текПодразделение = Данные.Ссылка.Родитель;
        Пока ЗначениеЗаполнено(текПодразделение.Родитель) Цикл
             текПодразделение = текПодразделение.Родитель;
        КонецЦикла;
        Представление = СокрЛП(Данные.Ссылка.Наименование) + ", " + СокрЛП(текПодразделение);
    КонецЕсли;
КонецПроцедуры

Этот код отлично справляется с изменением текста во всей системе. Однако у него есть два критических недостатка:

  1. Глобальность: Обработчик в модуле менеджера справочника Подразделения срабатывает везде — в списках, в других документах, в отчетах. У этого метода нет встроенного параметра, который бы подсказал, из какой формы или документа вызвано получение представления.
  2. Производительность: Использование цикла Пока для поиска родителя внутри этого обработчика — это классическая проблема N+1 запросов. Если вы откроете динамический список с 50 строками, система выполнит десятки дополнительных обращений к базе данных, что приведет к ощутимым «тормозам» интерфейса.

Выясним, какими способами можно добиться нужного результата локально, только для формы документа Заявка.

Решение 1: Использование Условного оформления формы

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

Разберем реализацию по шагам:

  1. Откроем форму документа Заявка.
  2. Перейдем на вкладку Условное оформление.
  3. Добавим новый элемент оформления.
  4. В поле Оформление установим галочку Текст и укажем произвольное значение (на этапе конфигуратора это может быть заглушка).
  5. В поле Оформляемые поля выберем наше поле Подразделение.

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


&НаСервере
Процедура ОбновитьПредставлениеПодразделения()
    // Вычисляем нужное нам представление
    Если ЗначениеЗаполнено(Объект.Подразделение) Тогда
        РодительНазвание = Объект.Подразделение.Родитель.Наименование;
        НовоеПредставление = Строка(Объект.Подразделение) + ", " + РодительНазвание;
        
        // Устанавливаем текст через элемент оформления
        Для Каждого ЭлементОформления Из УсловноеОформление.Элементы Цикл
            Если ЭлементОформления.ОформляемыеПоля.Элементы[0].Поле = Новый ПолеКомпоновкиДанных("Подразделение") Тогда
                ЭлементОформления.ПараметрыОформления.УстановитьЗначениеПараметра("Текст", НовоеПредставление);
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Решение 2: Виртуальный реквизит на форме

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

Рассмотрим алгоритм действий:

  1. Добавим в форму документа Заявка новый реквизит ПодразделениеПредставление с типом Строка.
  2. Разместим его на форме вместо основного реквизита Подразделение.
  3. Для нового строкового поля включим кнопку выбора и кнопку очистки.
  4. В событии НачалоВыбора программно открываем форму выбора справочника Подразделения.
  5. При выборе значения записываем ссылку в скрытый основной реквизит Объект.Подразделение, а в строковый реквизит выводим наше расширенное наименование (Наименование + Родитель).

Посмотрим на пример обработки выбора:


&НаКлиенте
Процедура ПодразделениеПредставлениеОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Объект.Подразделение = ВыбранноеЗначение;
    // Вызываем серверную функцию для формирования красивой строки
    ПодразделениеПредставление = СформироватьПолноеНазвание(ВыбранноеЗначение);
КонецПроцедуры

Решение 3: Переопределение событий АвтоПодбора

Чтобы пользователь видел правильное представление не только после выбора, но и в процессе набора текста с клавиатуры, необходимо использовать событие АвтоПодбор.

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


&НаКлиенте
Процедура ПодразделениеАвтоПодбор(Элемент, Текст, ДанныеВыбора, Параметры, Ожидание, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    // Здесь мы вызываем серверный поиск, который возвращает массив структур
    // со значениями (ссылка) и представлениями (строка "Подразделение + Родитель")
    ДанныеВыбора = ПоискПодразделенийСРодителемНаСервере(Текст);
КонецПроцедуры

Оптимизация производительности (Важно!)

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

Рассмотрим пример запроса для списка:


ВЫБРАТЬ
    Док.Ссылка КАК Ссылка,
    Док.Номер КАК Номер,
    Док.Дата КАК Дата,
    Док.Подразделение.Наименование + ", " + ЕСТЬNULL(Док.Подразделение.Родитель.Наименование, "") КАК ПодразделениеПредставление
ИЗ
    Документ.Заявка КАК Док

Использование конструкции ЕСТЬNULL и прямое обращение через точку в запросе позволяют платформе эффективно сформировать SQL-запрос с LEFT JOIN, что работает в десятки раз быстрее, чем перебор в коде 1С.

Резюме

Мы проанализировали несколько способов решения задачи. Подведем итоги:

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

← На главную