Как программно изменить макет компоновки данных и передать изменения в настройки отчета?

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

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

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

Выясняем причину проблемы: почему настройки «теряют» схему?

Для того чтобы понять, как решить задачу, давайте проанализируем ситуацию и заглянем под капот платформы. Когда мы открываем форму отчета, платформа инициализирует объект компоновщика настроек. Однако форма настроек отчета или форма редактирования варианта — это отдельные, независимые окна (а часто и разные программные контексты). При их открытии платформа пытается восстановить схему компоновки данных.

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

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

Решение 1. Реализация в конфигурациях без БСП (чистая платформа)

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

Шаг 1. Подготовка реквизитов формы.

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

Шаг 2. Программное изменение схемы и ее сохранение.

В модуле формы отчета в обработчике события ПриСозданииНаСервере мы получаем исходную схему, выполняем её модификацию, помещаем результат во временное хранилище и инициализируем компоновщик. Посмотрим на пример кода:


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

Шаг 3. Использование измененной схемы при компоновке результата.

При непосредственном формировании отчета (например, в обработчике ПриКомпоновкеРезультата модуля объекта отчета или при ручном выводе в табличный документ на форме) мы должны использовать именно ту схему, которая сохранена в нашем временном хранилище. Разберем, как это реализовать:


&НаСервере
Функция СформироватьОтчетНаСервере()
    
    // Извлекаем модифицированную схему из временного хранилища
    СхемаКД = ПолучитьИзВременногоХранилища(АдресСхемыКомпоновкиДанных);
    
    // Выполняем стандартную компоновку макета
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКД, Отчет.КомпоновщикНастроек.Настройки);
    
    // Далее выполняем инициализацию процессора компоновки и вывод в табличный документ...
    // ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    // ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
    
КонецФункции

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

Решение 2. Использование штатных механизмов БСП

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

К счастью, разработчики БСП предусмотрели красивое штатное решение. Нам нужно использовать предопределенные процедуры перехвата в модуле объекта отчета.

Шаг 1. Переопределение настроек формы.

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


Процедура ОпределитьНастройкиФормы(Форма, КлючВарианта, Настройки) Экспорт
    
    // Указываем БСП необходимость вызова нашего обработчика перед загрузкой настроек
    Настройки.События.ПередЗагрузкойНастроекВКомпоновщик = Истина;
    
КонецПроцедуры

Шаг 2. Реализация обработчика изменения схемы.

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


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

При использовании данного БСП-подхода вам больше не нужно вручную следить за адресами временного хранилища. Общий модуль ОтчетыСервер самостоятельно зарегистрирует измененную схему и свяжет её со всеми дочерними диалогами настроек. Вы избавляетесь от ошибок несовместимости контекстов, а пользователь получает полноценный интерактивный доступ ко всем динамически созданным полям.

Важные правила при программном добавлении элементов в СКД

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

  1. Определение путей к данным: Свойство поля ПутьКДанным должно быть уникальным в рамках набора данных и строго соответствовать имени поля, которое вы будете использовать в выбранных полях и группировках настроек. Если вы используете вложенные структуры, разделяйте их точками.
  2. Заполнение заголовков: Обязательно заполняйте свойство Заголовок. Если оставить его пустым, поле появится в списке доступных полей как пустая строка, что запутает пользователя.
  3. Управление типами данных: Свойство ТипЗначения должно содержать корректный объект ОписаниеТипов. Если тип поля не определен, у пользователя могут возникнуть проблемы при попытке наложить отбор на это поле в режиме предприятия (например, будут недоступны стандартные диалоги выбора значений).
  4. Доступность параметров: Если вы программно добавляете новые параметры схемы компоновки данных, не забывайте сбрасывать флаг ОграничениеИспользования в значение Ложь и устанавливать флаг ВключатьВДоступныеПоля в значение Истина. Только в этом случае они отобразятся на панели быстрых настроек или в окне изменения варианта.

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

← На главную