Как изменить представление элемента справочника в обычных (неуправляемых) формах 1С

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

Разработчики, работающие с классическими конфигурациями на обычных (неуправляемых) формах, такими как «Управление торговлей 10.3», «Управление производственным предприятием 1.3» или «Зарплата и управление персоналом 2.5», часто сталкиваются с жесткими требованиями заказчиков по кастомизации интерфейса. Типичная задача — изменить стандартное представление ссылки на справочник в полях ввода документов. Например, вместо обычного наименования договора заказчик хочет видеть строку формата «[Номер договора] от [Дата договора]».

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

Техническая суть проблемы: почему не работает ОбработкаПолученияПредставления

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


Процедура ОбработкаПолученияПолейПредставления(Поля, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Поля.Добавить("Код");
    Поля.Добавить("Дата");
КонецПроцедуры

Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Представление = "" + Данные.Код + " от " + Формат(Данные.Дата, "ДФ=dd.MM.yyyy");
КонецПроцедуры

Однако при попытке применить этот код в типовой конфигурации на обычных формах (например, УТ 10.3) вы обнаружите, что платформа полностью игнорирует эти процедуры. Синтаксический контроль конфигуратора при этом проходит без ошибок.

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

Опасности повышения режима совместимости в работающих базах

Иногда у разработчиков возникает соблазн просто изменить свойство конфигурации РежимСовместимости на «Не использовать» или установить актуальную версию 8.3. Действительно, после этого события модуля менеджера начнут отрабатывать, и новое представление применится автоматически по всей системе. Однако в живых, кастомизированных базах данных такое решение может привести к катастрофическим последствиям.

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

  1. Конфликты блокировок (Переход на управляемые блокировки). В режиме совместимости с 8.2 конфигурация по умолчанию использует автоматический режим блокировок данных в транзакции. При снятии совместимости платформа переходит на строгий контроль управляемых блокировок. Если код проведения документов не адаптирован под управляемый режим, вы начнете получать критические ошибки при любой транзакционной операции.
  2. Ошибки реструктуризации СУБД (SDBL). При изменении режима совместимости платформа выполняет глубокую конвертацию таблиц базы данных на уровне SQL. На крупных базах это может затянуться на долгие часы и завершиться аварийно, повредив индексы, служебные таблицы или схемы итогов регистров накопления. Чтобы обезопасить данные перед такими критическими изменениями, предварительное резервное копирование и проверку конфигурации можно настроить через программу для автоматического архивирования и тестирования 1С.
  3. Аварийные завершения работы платформы (Дампы). Старые внешние компоненты, драйверы торгового оборудования, объекты ActiveX или интеграционные HTML-поля, используемые в обычных формах, часто несовместимы с ядром платформы 8.3 в «чистом» режиме. Это начнет вызывать внезапные падения рабочих процессов сервера 1С (rphosts) или вылеты клиентского приложения.
  4. Изменение логики работы запросов и СКД. В режиме совместимости 8.3 иначе интерпретируются некоторые конструкции языка запросов (например, поведение итогов при обходе группировок). Это может исказить данные в ключевых отчетах предприятия.

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

Вариант А: Автоматическое формирование Наименования при записи (Best Practice)

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

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

Рассмотрим по шагам, как это реализовать:

Шаг 1. Программное заполнение в модуле объекта. Откроем модуль объекта справочника ДоговорыКонтрагентов и добавим код в обработчик события ПередЗаписью:


Процедура ПередЗаписью(Отказ)
    
    // Исключаем перезапись, если документ проводится или записывается из обмена без изменения ключевых полей
    Наименование = "Договор № " + СокрЛП(Код) + " от " + Формат(Дата, "ДФ=dd.MM.yyyy");
    
КонецПроцедуры

Шаг 2. Корректировка формы элемента справочника. На форме элемента справочника найдем поле ввода реквизита Наименование. Сделаем его недоступным для редактирования пользователем (свойство Доступность = Ложь или ТолькоПросмотр = Истина) либо вовсе скроем его с формы. Заполнение кода и даты договора теперь будет автоматически определять имя элемента.

Шаг 3. Обработка исторических данных. Чтобы старые договора также получили новое представление, напишем простую групповую обработку для перезаписи существующих элементов:


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

Вариант Б: Динамическое отображение через вспомогательную надпись на форме

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

Выясним, как это настроить:

1. Откроем форму документа в конфигураторе и добавим элемент управления типа Надпись рядом с полем выбора договора. Назовем его НадписьДоговораЗаказчика.

2. Настроим логику обновления текста надписи при открытии формы и при изменении реквизита договора.

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


Процедура ПриОткрытии()
    // Обновляем текст при открытии документа
    ОбновитьОтображениеДоговора();
КонецПроцедуры

Процедура ДоговорКонтрагентаПриИзменении(Элемент)
    // Обновляем текст при интерактивном изменении значения пользователем
    ОбновитьОтображениеДоговора();
КонецПроцедуры

Процедура ОбновитьОтображениеДоговора()
    
    ДоговорСсылка = ДоговорКонтрагента;
    
    Если ЗначениеЗаполнено(ДоговорСсылка) Тогда
        // Формируем красивое представление из реквизитов ссылки
        ТекстПредставления = "Номер: " + СокрЛП(ДоговорСсылка.Код) + " от " + Формат(ДоговорСсылка.Дата, "ДФ=dd.MM.yyyy");
        ЭлементыФормы.НадписьДоговораЗаказчика.Заголовок = ТекстПредставления;
    Иначе
        ЭлементыФормы.НадписьДоговораЗаказчика.Заголовок = "[Договор не выбран]";
    КонецЕсли;
    
КонецПроцедуры

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

Вариант В: Переопределение вывода в списках и табличных частях

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

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


Процедура ТоварыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    
    // Проверяем, заполнена ли ссылка на договор в текущей строке данных
    Если ЗначениеЗаполнено(ДанныеСтроки.Договор) Тогда
        
        // Получаем данные напрямую из ссылки без обращения через точку (для оптимизации производительности)
        КодДоговора = ДанныеСтроки.Договор.Код;
        ДатаДоговора = ДанныеСтроки.Договор.Дата;
        
        НовоеПредставление = "Дг. № " + СокрЛП(КодДоговора) + " от " + Формат(ДатаДоговора, "ДФ=dd.MM.yyyy");
        
        // Устанавливаем текст отображения в конкретную ячейку строки
        ОформлениеСтроки.Ячейки.Договор.УстановитьТекст(НовоеПредставление);
        
    КонецЕсли;
    
КонецПроцедуры

Важное предупреждение по производительности: Событие ПриВыводеСтроки вызывается очень часто — при любой прокрутке, обновлении или клике по таблице. Обращение «через точку» к реквизитам ссылки (ДанныеСтроки.Договор.Код) провоцирует неявные SQL-запросы к базе данных для каждой строки, что может привести к сильному «торможению» интерфейса при больших списках. Для оптимизации в таких случаях рекомендуется использовать событие ПриПолученииДанных, которое позволяет считать реквизиты ссылок пакетным запросом для всех отображаемых строк одновременно.

Резюме

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

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

← На главную