При разработке отчетов на системе компоновки данных (СКД) в современных управляемых формах большинство настроек, таких как период или отборы, появляются на форме автоматически — достаточно лишь поставить галочку «Включать в пользовательские настройки». Однако в обычных формах (которые до сих пор активно используются в таких конфигурациях, как УПП 1.3 или КА 1.1) этот механизм работает иначе. Здесь программисту зачастую приходится вручную создавать элементы управления на форме и программно связывать их с параметрами схемы компоновки.
В этой статье мы подробно разберем, как вывести период и другие параметры (например, организацию) непосредственно на форму отчета, проанализируем типичные ошибки программного формирования и составим правильный алгоритм работы с компоновщиком настроек.
Прежде чем приступать к написанию кода, нам необходимо подготовить саму форму отчета. В обычном приложении параметры СКД не «пробрасываются» на форму сами по себе. Рассмотрим пошагово процесс подготовки:
ДатаНач (тип Дата), ДатаКон (тип Дата) и Организация (тип соответствующего справочника).Совет: Вместо двух дат (начала и конца) в 1С версии 8.2 и выше удобнее использовать один реквизит с типом СтандартныйПериод. Это избавит вас от лишних полей на форме и даст пользователю привычный интерфейс выбора дат.
После того как элементы на форме созданы, нам нужно объяснить системе, что значение из поля ДатаНач должно попасть в параметр компоновки НачалоПериода. Проанализируем, как это сделать правильно в модуле формы.
Рассмотрим пример кода для событий изменения дат на форме:
Процедура ДатаНачПриИзменении(Элемент)
// Поиск параметра в компоновщике настроек по имени
ПараметрДатаНач = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("НачалоПериода");
Если ПараметрДатаНач <> Неопределено Тогда
ПараметрДатаНач.Использование = Истина;
// Устанавливаем начало дня, чтобы не потерять данные за утро
ПараметрДатаНач.Значение = НачалоДня(ДатаНач);
КонецЕсли;
КонецПроцедуры
Процедура ДатаКонПриИзменении(Элемент)
ПараметрДатаКон = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("КонецПериода");
Если ПараметрДатаКон <> Неопределено Тогда
ПараметрДатаКон.Использование = Истина;
// Устанавливаем конец дня, чтобы захватить данные до последней секунды суток
ПараметрДатаКон.Значение = КонецДня(ДатаКон);
КонецЕсли;
КонецПроцедуры
Обратите внимание на использование функций НачалоДня и КонецДня. Это критически важно для отчетов. Если пользователь выберет дату окончания «31.12.2023», но не укажет время, система подставит «31.12.2023 00:00:00», и все движения, совершенные в течение этого дня, в отчет не попадут.
Для того чтобы предоставить пользователю возможность выбирать период «одним кликом» (например, «Текущий месяц»), мы можем использовать объект НастройкаПериода. Разберем пример реализации нажатия на кнопку выбора периода:
Процедура ВыборПериодаНажатие(Элемент)
НП = Новый НастройкаПериода;
НП.ВариантНастройки = ВариантНастройкиПериода.Период;
// Инициализируем диалог текущими значениями с формы
НП.УстановитьПериод(ДатаНач, ?(ДатаКон = '00010101', ДатаКон, КонецДня(ДатаКон)));
Если НП.Редактировать() Тогда
ДатаНач = НП.ПолучитьДатуНачала();
ДатаКон = НП.ПолучитьДатуОкончания();
// Сразу синхронизируем с параметрами СКД
ДатаНачПриИзменении(Неопределено);
ДатаКонПриИзменении(Неопределено);
КонецЕсли;
КонецПроцедуры
Часто разработчики сталкиваются с ситуацией, когда параметры вроде бы установлены, но отчет выходит пустым или без учета настроек пользователя. Проанализируем распространенную ошибку в модуле объекта при программном формировании:
Ошибка: Настройки = Новый КомпоновщикНастроекКомпоновкиДанных;
Почему это не работает: Когда вы создаете Новый компоновщик, вы получаете «чистый лист». В нем нет ни полей, которые вы выбрали в СКД, ни группировок, ни иерархии. Выполнение отчета с таким компоновщиком приведет либо к ошибке, либо к пустому результату.
Как правильно: Нужно использовать настройки, которые уже хранятся в КомпоновщикНастроек формы, так как именно их видит и меняет пользователь.
Выясним, как должен выглядеть итоговый код формирования отчета в модуле объекта или формы, чтобы он учитывал все настройки и корректно выводил результат в табличный документ.
Процедура СформироватьОтчет(РезультатТабличныйДокумент) Экспорт
// 1. Получаем основную схему
СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// 2. Получаем текущие настройки из компоновщика (те, что на форме)
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// 3. Подготавливаем данные расшифровки
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
// 4. Компонуем макет
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
// 5. Инициализируем процессор компоновки
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
// 6. Очищаем поле результата и выводим отчет
РезультатТабличныйДокумент.Очистить();
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(РезультатТабличныйДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
КонецПроцедуры
Рассмотрим еще несколько моментов, которые помогут сделать ваш отчет стабильным:
ДанныеРасшифровки (тип Строка) в свойствах табличного документа на форме. Это позволит пользователю детализировать показатели отчета (например, открыть документ из ячейки).Организация в СКД помечен как «Запрещать незаполненные значения», а пользователь её не выбрал, отчет выдаст ошибку.ПолучитьФорму("ФормаОтчета").ЭлементыФормы внутри модуля. Это создает новый экземпляр формы в памяти, который не имеет отношения к тому окну, которое открыто перед пользователем. Всегда передавайте объект табличного документа (Результат) как параметр в процедуру формирования.Соблюдение этого алгоритма позволит вам создавать гибкие и удобные отчеты в обычных формах 1С, предоставляя пользователю простой доступ к основным фильтрам данных без необходимости глубоко заходить в настройки компоновки.