Как получить стандартное представление документа в 1С, если оно переопределено в модуле менеджера?

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

В процессе разработки в системе «1С:Предприятие» мы часто сталкиваемся с необходимостью кастомизации интерфейса. Один из стандартных способов сделать это — переопределить представление документов или справочников с помощью процедур ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления в модуле менеджера объекта. Например, для удобства пользователей в журналах документов стандартную строку «Реализация товаров № 15 от 10.10.2023» превращают в длинное составное представление, содержащее контрагента, сумму или статус договора.

Однако возникает обратная задача: что делать, если для конкретного отчета, выгрузки или формы нам требуется вернуть именно базовое, классическое представление документа вида «ИмяДокумента № Номер от Дата»? Попытка использовать в запросе стандартную функцию ПРЕДСТАВЛЕНИЕ(Ссылка) не даст результата, так как платформа все равно вернет переопределенный вариант. В этой статье мы подробно разберем, почему так происходит, и рассмотрим несколько эффективных способов решения этой проблемы.

Почему стандартный запрос игнорирует ПРЕДСТАВЛЕНИЕ() и как это работает «под капотом»

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

Когда мы пишем запрос и выбираем виртуальное поле Представление или используем функцию языка запросов ПРЕДСТАВЛЕНИЕ(Ссылка), СУБД (например, MS SQL Server или PostgreSQL) не занимается формированием этой строки. Происходит следующее:

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

Поскольку этот механизм зашит глубоко в ядро платформы, любой вызов функции ПРЕДСТАВЛЕНИЕ() в запросе всегда будет приводить к выполнению вашего переопределенного кода в модуле менеджера.

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

Решение 1. Оптимальный обход в Системе компоновки данных (СКД)

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

Многие разработчики совершают классическую ошибку, прописывая в выражении представления поля СКД конструкции с обращением через точку, например:


Строка(Ссылка.Метаданные().Синоним) + " № " + Строка(Ссылка.Номер) + " от " + Строка(Ссылка.Дата)

Важное предупреждение: Использование обращений через точку (Ссылка.Номер, Ссылка.Дата) в выражениях СКД приводит к проблеме производительности, известной как «N+1 запрос». Для каждой выводимой строки отчета платформа будет делать отдельный неявный запрос к СУБД, чтобы получить эти поля. Если в отчете 10 000 строк, отчет будет формироваться крайне медленно.

Разберем по шагам, как решить эту задачу правильно и быстро:

  1. В основном запросе набора данных СКД обязательно выберите поля Номер и Дата (а также Ссылка):
    
    ВЫБРАТЬ РАЗРЕШЕННЫЕ
        РакурсДанных.Ссылка КАК Ссылка,
        РакурсДанных.Номер КАК Номер,
        РакурсДанных.Дата КАК Дата
    ИЗ
        Документ.РакурсДанных КАК РакурсДанных
    
  2. Перейдите на вкладку «Наборы данных» в конструкторе схемы компоновки данных.
  3. Найдите поле Ссылка в списке полей набора данных.
  4. В колонке «Выражение представления» для поля Ссылка пропишите следующее выражение:
    
    Строка(Ссылка.Метаданные().Синоним) + " № " + [Номер] + " от " + Формат([Дата], "ДФ='dd.MM.yyyy HH:mm:ss'")
    

Использование квадратных скобок [Номер] и [Дата] указывает СКД на то, что нужно взять уже выбранные в текущей строке запроса значения полей. Это полностью исключает дополнительные запросы к базе данных и обеспечивает максимальную скорость работы отчета. Использование Ссылка.Метаданные().Синоним позволяет получить корректное имя документа на языке пользователя.

Решение 2. Использование управляющего флага в модуле менеджера

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

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

Посмотрим на пример реализации в модуле менеджера документа:


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

Перед выполнением вашего запроса вам достаточно установить значение параметра сеанса в Истина, а после выполнения запроса — вернуть его в Ложь. Это чистое решение, которое не требует дублирования логики склейки строк в запросах или СКД.

Решение 3. Обработка данных в динамических списках

Динамические списки очень чувствительны к скорости загрузки данных и прокрутке. Если вы попытаетесь вычислять сложные выражения на лету, интерфейс начнет «тормозить».

Если ваш динамический список отображает документы только одного типа, лучшим решением будет:

  1. Добавить в текст запроса динамического списка текстовую константу с синонимом документа:
    
    ВЫБРАТЬ
        Ссылка КАК Ссылка,
        Номер КАК Номер,
        Дата КАК Дата,
        "Реализация товаров и услуг" КАК ИмяДокумента
    ИЗ
        Документ.РеализацияТоваровУслуг
    
  2. В свойствах пути к данным колонок или через условное оформление объединить эти поля на форме для отображения пользователю.

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

Решение 4. Сборка строки на уровне СУБД (для старых версий платформы)

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

Поэтому мы настоятельно рекомендуем использовать разделение обязанностей: запрос должен отвечать исключительно за выборку данных (получение Номера, Даты и Синонима типа), а форматирование и вывод красивой строки должны происходить на уровне представления — в СКД, в коде модуля формы или при обработке результата запроса.

← На главную