Разработчики, работающие с классическими конфигурациями на обычных (неуправляемых) формах, такими как «Управление торговлей 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. Действительно, после этого события модуля менеджера начнут отрабатывать, и новое представление применится автоматически по всей системе. Однако в живых, кастомизированных базах данных такое решение может привести к катастрофическим последствиям.
Проанализируем основные риски смены режима совместимости:
rphosts) или вылеты клиентского приложения.Учитывая эти риски, изменять режим совместимости ради одной эстетической задачи категорически не рекомендуется. Ниже мы рассмотрим три безопасных способа реализации требований заказчика.
Наиболее надежный, архитектурно правильный и простой в поддержке способ — отказаться от ручного заполнения реквизита Наименование в справочнике договоров (или любом другом) и формировать его программно на основе значимых реквизитов.
Поскольку стандартное представление ссылок в 1С всегда опирается на основное представление (которое по умолчанию настроено «по наименованию»), изменение этого реквизита решит задачу глобально. Новое наименование будет корректно выводиться в полях документов, списках выбора, стандартных отчетах и при поиске по строке.
Рассмотрим по шагам, как это реализовать:
Шаг 1. Программное заполнение в модуле объекта. Откроем модуль объекта справочника ДоговорыКонтрагентов и добавим код в обработчик события ПередЗаписью:
Процедура ПередЗаписью(Отказ)
// Исключаем перезапись, если документ проводится или записывается из обмена без изменения ключевых полей
Наименование = "Договор № " + СокрЛП(Код) + " от " + Формат(Дата, "ДФ=dd.MM.yyyy");
КонецПроцедуры
Шаг 2. Корректировка формы элемента справочника. На форме элемента справочника найдем поле ввода реквизита Наименование. Сделаем его недоступным для редактирования пользователем (свойство Доступность = Ложь или ТолькоПросмотр = Истина) либо вовсе скроем его с формы. Заполнение кода и даты договора теперь будет автоматически определять имя элемента.
Шаг 3. Обработка исторических данных. Чтобы старые договора также получили новое представление, напишем простую групповую обработку для перезаписи существующих элементов:
Выборка = Справочники.ДоговорыКонтрагентов.Выбрать();
Пока Выборка.Следующий() Цикл
ОбъектДоговора = Выборка.ПолучитьОбъект();
// При записи сработает наш новый алгоритм в ПередЗаписью()
Попытка
ОбъектДоговора.Записать();
Исключение
Сообщить("Не удалось обновить договор: " + ОбъектДоговора.Ссылка + " - " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Если заказчик категорически запрещает менять наименования существующих элементов справочника в базе данных, мы можем решить задачу локально на форме конкретного документа с помощью элемента управления Надпись.
Выясним, как это настроить:
1. Откроем форму документа в конфигураторе и добавим элемент управления типа Надпись рядом с полем выбора договора. Назовем его НадписьДоговораЗаказчика.
2. Настроим логику обновления текста надписи при открытии формы и при изменении реквизита договора.
Проанализируем пример кода в модуле формы документа:
Процедура ПриОткрытии()
// Обновляем текст при открытии документа
ОбновитьОтображениеДоговора();
КонецПроцедуры
Процедура ДоговорКонтрагентаПриИзменении(Элемент)
// Обновляем текст при интерактивном изменении значения пользователем
ОбновитьОтображениеДоговора();
КонецПроцедуры
Процедура ОбновитьОтображениеДоговора()
ДоговорСсылка = ДоговорКонтрагента;
Если ЗначениеЗаполнено(ДоговорСсылка) Тогда
// Формируем красивое представление из реквизитов ссылки
ТекстПредставления = "Номер: " + СокрЛП(ДоговорСсылка.Код) + " от " + Формат(ДоговорСсылка.Дата, "ДФ=dd.MM.yyyy");
ЭлементыФормы.НадписьДоговораЗаказчика.Заголовок = ТекстПредставления;
Иначе
ЭлементыФормы.НадписьДоговораЗаказчика.Заголовок = "[Договор не выбран]";
КонецЕсли;
КонецПроцедуры
Этот метод полностью безопасен для структуры данных, но требует ручной прописки кода на каждой форме, где требуется такое представление.
Часто требуется изменить представление договора не только в одиночном поле ввода на шапке документа, но и в табличных частях или в списках документов. В обычных формах для этого используется мощный механизм событий табличного поля ПриВыводеСтроки.
Посмотрим на пример реализации для табличной части товаров, где добавлена колонка Договор:
Процедура ТоварыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
// Проверяем, заполнена ли ссылка на договор в текущей строке данных
Если ЗначениеЗаполнено(ДанныеСтроки.Договор) Тогда
// Получаем данные напрямую из ссылки без обращения через точку (для оптимизации производительности)
КодДоговора = ДанныеСтроки.Договор.Код;
ДатаДоговора = ДанныеСтроки.Договор.Дата;
НовоеПредставление = "Дг. № " + СокрЛП(КодДоговора) + " от " + Формат(ДатаДоговора, "ДФ=dd.MM.yyyy");
// Устанавливаем текст отображения в конкретную ячейку строки
ОформлениеСтроки.Ячейки.Договор.УстановитьТекст(НовоеПредставление);
КонецЕсли;
КонецПроцедуры
Важное предупреждение по производительности: Событие ПриВыводеСтроки вызывается очень часто — при любой прокрутке, обновлении или клике по таблице. Обращение «через точку» к реквизитам ссылки (ДанныеСтроки.Договор.Код) провоцирует неявные SQL-запросы к базе данных для каждой строки, что может привести к сильному «торможению» интерфейса при больших списках. Для оптимизации в таких случаях рекомендуется использовать событие ПриПолученииДанных, которое позволяет считать реквизиты ссылок пакетным запросом для всех отображаемых строк одновременно.
Мы выяснили, почему стандартная для управляемого приложения связка процедур ОбработкаПолученияПредставления не работает на обычных формах в старых режимах совместимости. Также мы убедились, что изменение режима совместимости конфигурации несет критические риски сбоев СУБД и транзакционных блокировок.
Наилучшим и самым стабильным решением является Вариант А (программное формирование наименования при записи объекта). Он решает задачу системно, один раз и для всех механизмов платформы. В случаях, когда редактирование существующих данных запрещено регламентом, используйте локальные доработки форм с помощью надписей и переопределения вывода строк табличного поля.