При работе с типовыми конфигурациями, такими как 1С:Зарплата и управление персоналом 3.1, часто возникает необходимость модифицировать стандартные отчеты. Одной из популярных задач является добавление произвольного параметра (например, для выбора подписанта или ответственного лица), который не предусмотрен в типовой схеме компоновки данных (СКД), но должен отображаться в пользовательских настройках на форме. Рассмотрим подробно, как это реализовать, какие подводные камни нас ждут и почему программно добавленные параметры могут «исчезать» при формировании отчета.
Представим ситуацию: в отчете «Табель учета рабочего времени» (Т-13) нам нужно выводить руководителя подразделения, отличного от руководителя организации. Типовой механизм подставляет руководителя предприятия, что не всегда корректно для крупных структур. Наша цель — добавить на форму отчета поле выбора сотрудника, значение которого мы перехватим в коде и используем для заполнения макета. Поскольку форма отчета в ЗУП является общей, мы не можем просто «нарисовать» на ней новый реквизит. Нам необходимо внедрить его в структуру КомпоновщикНастроек программно.
Прежде всего, параметр должен появиться в самой схеме. Если мы не хотим снимать конфигурацию с поддержки, нам придется модифицировать схему в памяти перед инициализацией компоновщика. Проанализируем, как добавить описание параметра в коллекцию Параметры схемы.
Для этого мы обращаемся к объекту СхемаКомпоновкиДанных. Нам нужно создать новый элемент, задать ему имя, заголовок и тип значения. Важно установить свойство ОграничениеИспользования в значение Ложь, иначе параметр будет скрыт от пользователя.
ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
Схема = ОтчетОбъект.СхемаКомпоновкиДанных;
// Добавляем параметр в саму схему
НовыйПараметр = Схема.Параметры.Добавить();
НовыйПараметр.Имя = "Руководитель2";
НовыйПараметр.Заголовок = "Руководитель подразделения";
НовыйПараметр.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.Сотрудники");
НовыйПараметр.ОграничениеИспользования = Ложь;
НовыйПараметр.Использование = ИспользованиеПараметраКомпоновкиДанных.Всегда;
Добавления в схему недостаточно для того, чтобы пользователь увидел поле на форме. Теперь нам нужно внести изменения в КомпоновщикНастроек.Настройки.ПараметрыДанных. Рассмотрим ситуацию, когда мы хотим, чтобы параметр попал в Пользовательские настройки (раздел «Быстрый доступ» на форме отчета).
Критически важным моментом здесь является создание уникального идентификатора пользовательской настройки. Без этого 1С не поймет, какое поле на форме привязано к нашему параметру.
// Добавляем элемент настройки
ЗначениеПараметра = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Добавить();
ЗначениеПараметра.Параметр = Новый ПараметрКомпоновкиДанных("Руководитель2");
ЗначениеПараметра.Использование = Истина;
ЗначениеПараметра.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Обычный;
// Создаем связь с пользовательскими настройками (GUID)
ЗначениеПараметра.ИдентификаторПользовательскойНастройки = Новый УникальныйИдентификатор();
Многие разработчики сталкиваются с тем, что после выполнения вышеуказанного кода параметр на мгновение появляется, но после нажатия кнопки «Сформировать» или открытия окна настроек он исчезает. Проанализируем ситуацию: это происходит из-за вызова метода ЗагрузитьНастройки() или Инициализировать().
В типовых отчетах БСП (Библиотека стандартных подсистем) настройки часто перечитываются из хранилища или сбрасываются к «Настройкам по умолчанию» при открытии формы. Если вызвать Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию) после нашего кода, то коллекция параметров будет полностью перезаписана данными из XML-схемы, где нашего динамического параметра еще нет.
Решение: Программное добавление параметров должно происходить в расширении в процедуре ПриСозданииНаСервере формы отчета после выполнения типовых механизмов инициализации (аннотация &После). Либо мы должны модифицировать саму схему в модуле объекта в событии ПриКомпоновкеРезультата.
Наиболее надежный способ внедрить параметр так, чтобы он участвовал в формировании — использовать расширение модуля объекта отчета. Рассмотрим перехват события ПриКомпоновкеРезультата. Здесь мы можем подменить схему компоновки на лету.
&Вместо("ПриКомпоновкеРезультата")
Процедура Расш_ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
// Получаем текущую схему
Схема = ЭтотОбъект.СхемаКомпоновкиДанных;
// Проверяем, есть ли уже наш параметр (чтобы не дублировать)
Если Схема.Параметры.Найти("Руководитель2") = Неопределено Тогда
// Код добавления параметра в схему (как в Шаге 1)
// ...
КонецЕсли;
// Далее типовой вызов компоновщика
// ...
КонецПроцедуры
Чтобы параметр был доступен пользователю без перехода в расширенные настройки, нужно убедиться, что он включен в состав пользовательских настроек компоновщика. В современных управляемых формах за это отвечает метод СоздатьЭлементыФормыПользовательскихНастроек. Однако при программной модификации лучше принудительно обновить коллекцию на форме:
ЭтаФорма.СоздатьЭлементыФормыПользовательскихНастроек(РежимОтображенияНастроекКомпоновкиДанных.БыстрыйДоступ);
Помните, что если в КомпоновщикНастроек.ПользовательскиеНастройки.Элементы уже есть записи, ваш идентификатор должен соответствовать им. Важный нюанс: если вы добавляете параметр в схему, а потом загружаете настройки, обязательно делайте это в правильном порядке. Сначала меняем схему, потом инициализируем источник доступных настроек, и только потом загружаем сами настройки.
Иногда задачу можно решить проще, не прибегая к сложному кодингу СКД. Рассмотрим вариант с Дополнительными сведениями. В 1С:ЗУП к справочнику «Подразделения» или «Организации» можно привязать дополнительное сведение «Руководитель для подписи». В самой СКД (если вы правите запрос в расширении) можно соединиться с таблицей сведений и вытягивать это значение автоматически. В этом случае пользователю вообще не придется выбирать параметр вручную — система сама определит нужного сотрудника по контексту отчета.
Для успешного программного добавления параметра необходимо соблюдать следующую последовательность действий:
ПараметрКомпоновкиДанных в коллекцию Схема.Параметры.ОграничениеИспользования = Ложь.Настройки.ПараметрыДанных и обязательно генерируем ИдентификаторПользовательскойНастройки.ПриСозданииНаСервере формы или непосредственно перед компоновкой).Используя этот структурный подход, мы обеспечиваем стабильную работу отчета и сохраняем возможность гибкой настройки под нужды бизнеса, не нарушая типовую логику конфигурации.