При разработке и доработке прикладных решений на платформе 1С:Предприятие 8 часто возникает задача контекстного вызова отчетов. Например, при переходе из карточки номенклатуры к отчету по движениям товаров требуется сразу задать определенный период (например, за все время) и установить отбор по текущей позиции. Однако прямое изменение параметров компоновщика настроек в стандартных событиях формы нередко приводит к тому, что значения сбрасываются или перетираются. Разберем подробно, почему так происходит и как корректно управлять параметрами СКД при открытии отчета.
Проанализируем типичные ошибки, возникающие при попытке задать период программно, выясним внутреннюю логику работы подсистемы отчетов БСП и рассмотрим правильные варианты реализации задачи.
Посмотрим на распространенные способы, которые часто пытаются использовать разработчики, и разберем, почему они не работают как ожидается:
ПриОткрытии формы отчета. Если попытаться напрямую присвоить значения в КомпоновщикНастроек.Настройки.ПараметрыДанных при открытии формы, они будут перезаписаны. В типовых конфигурациях на базе БСП (Библиотеки Стандартных Подсистем) после события открытия срабатывают механизмы восстановления настроек пользователя и наложения параметров контекста, которые затирают введенные значения.Элементы[0].Значение крайне ненадежна. В схеме компоновки данных порядок следования параметров не фиксирован жестко: при изменении состава настроек или структуры отчета индекс нужного параметра сместится, что приведет к ошибке выполнения или установке значения не в то поле.СхемаКомпоновкиДанных.ВариантыНастроек. Редактирование схемы на сервере меняет ее глобально в оперативной памяти для всех сеансов и всех мест вызова данного варианта отчета, нарушая логику работы системы в других разделах конфигурации.ПриКомпоновкеРезультата модуля отчета. Данный обработчик вызывается каждый раз при формировании отчета. Если жестко перезаписывать даты в этом событии, пользователь потеряет возможность интерактивно поменять период на форме отчета после его открытия.Разберем по шагам наиболее правильный архитектурный вариант — передачу настроек напрямую из команды вызова отчета. В типовых конфигурациях (например, 1С:Управление торговлей 11, 1С:ERP, 1С:Комплексная автоматизация) отчеты открываются с помощью механизма параметров формы.
В обработчике команды вызова отчета (в форме элемента справочника или в модуле команды) сформируем структуру параметров с указанием ключа варианта, пользовательских настроек и отборов:
// Формируем структуру параметров для открытия формы отчета
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("КлючВарианта", "ВедомостьПоТоварамОрганизаций");
ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);
// Устанавливаем отбор по текущей номенклатуре
Отбор = Новый Структура;
Отбор.Вставить("Номенклатура", Объект.Ссылка);
ПараметрыФормы.Вставить("Отбор", Отбор);
// Для установки периода "за все время" передаем пустой стандартный период
ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных;
// Либо передаем структуру параметров БСП
ПараметрыФормы.Вставить("ПользовательскиеНастройки", ПользовательскиеНастройки);
ОткрытьФорму("Отчет.ВедомостьПоТоварамОрганизаций.Форма", ПараметрыФормы, ЭтотОбъект);
Такой подход обеспечивает корректное контекстное открытие: отчет формируется с нужным отбором, а стандартный период за все время не ломает работу отчета при его вызове из основного меню программы.
Если требуется модифицировать параметры непосредственно в кодовой логике формы или общего модуля отчетов, необходимо работать не с базовыми настройками, а с коллекцией ПользовательскиеНастройки, находя параметр по его имени, а не по числовому индексу.
Посмотрим на пример правильного поиска параметра по идентификатору пользовательской настройки:
// 1. Находим параметр в настройках компоновщика по его системному имени
ПараметрПериод = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Период"));
Если ПараметрПериод <> Неопределено И Не ПустаяСтрока(ПараметрПериод.ИдентификаторПользовательскойНастройки) Тогда
// 2. Находим соответствующий элемент в пользовательских настройках
ЭлементПользовательскойНастройки = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(ПараметрПериод.ИдентификаторПользовательскойНастройки);
Если ЭлементПользовательскойНастройки <> Неопределено Тогда
// 3. Устанавливаем период "за все время" (пустые даты начала и окончания)
ЭлементПользовательскойНастройки.Значение = Новый СтандартныйПериод(Дата(1, 1, 1), Дата(1, 1, 1));
ЭлементПользовательскойНастройки.Использование = Истина;
КонецЕсли;
КонецЕсли;
Рассмотрим важную особенность: для того чтобы отчет СКД выводил данные за все время, в типе СтандартныйПериод обе даты должны быть пустыми (то есть '00010101' или Дата(1, 1, 1)). Не следует задавать искусственные начальные даты вроде 2001.01.01 или 2017.01.01, так как это приведет к отсечению документов, введенных до указанного момента.
Если требуется изменить стандартное поведение отчета без изменения программного кода конфигурации, можно воспользоваться возможностями пользовательского интерфейса:
Таким образом, мы сохраняем стандартное поведение конфигурации без вмешательства в типовой код, а отчет сразу открывается с требуемыми границами периода.