При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда отчет должен объединять данные из разных источников. Трудности начинаются тогда, когда один набор данных берется из регистров накопления (через виртуальные таблицы), а другой — напрямую из табличных частей документов. Рассмотрим подробнее, почему стандартный механизм выбора периода может работать для регистров, но игнорировать документы, и как это исправить.
Проанализируем ситуацию: когда мы работаем с виртуальной таблицей, например, РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты, платформа 1С предоставляет нам готовые параметры &НачалоПериода и &КонецПериода. Эти параметры встроены в саму структуру виртуальной таблицы. Система компоновки данных автоматически связывает их с настройками периода на форме отчета.
Однако, когда мы пишем запрос к физической таблице документа (например, к табличной части Документ.ПроизводственныеЦиклы.ТаблицаЦиклов), у этой таблицы нет встроенных параметров периода. Если мы просто выберем поля, запрос вернет все документы за все время, игнорируя даты, указанные пользователем в настройках отчета. Выясним причину: в обычном запросе к документу система «не знает», по какому именно полю нужно фильтровать данные, пока мы не укажем это явно.
Самый простой и прямолинейный способ заставить отчет фильтровать документы по дате — добавить секцию ГДЕ в текст запроса набора данных. Разберем по шагам, как это реализовать. Посмотрим на пример правильного запроса для документов:
ВЫБРАТЬ
ПроизводственныеЦиклыТаблицаЦиклов.Ссылка.Дата КАК Дата,
ПроизводственныеЦиклыТаблицаЦиклов.Продукт,
ПроизводственныеЦиклыТаблицаЦиклов.Количество
ИЗ
Документ.ПроизводственныеЦиклы.ТаблицаЦиклов КАК ПроизводственныеЦиклыТаблицаЦиклов
ГДЕ
ПроизводственныеЦиклыТаблицаЦиклов.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
В данном примере мы явно указываем системе, что поле Дата (полученное через обращение к ссылке документа) должно входить в диапазон между нашими параметрами. Обратите внимание, что имена параметров &НачалоПериода и &КонецПериода должны совпадать с именами параметров, используемых в запросах к регистрам в этом же отчете. Это позволит пользователю устанавливать один период для всего отчета целиком.
Рассмотрим более гибкий подход. В СКД существует механизм фигурных скобок {}, который называется расширениями языка запросов. Использование стандартного ГДЕ делает заполнение периода обязательным. Если пользователь очистит даты, отчет может выдать ошибку или не вернуть данные. Чтобы сделать условие необязательным и позволить СКД управлять им более эффективно, используем следующий синтаксис:
ВЫБРАТЬ
ПроизводственныеЦиклыТаблицаЦиклов.Ссылка.Дата,
ПроизводственныеЦиклыТаблицаЦиклов.Количество
ИЗ
Документ.ПроизводственныеЦиклы.ТаблицаЦиклов КАК ПроизводственныеЦиклыТаблицаЦиклов
{ГДЕ
(ПроизводственныеЦиклыТаблицаЦиклов.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода)}
В этом случае, если параметры периода не будут заполнены пользователем, СКД просто проигнорирует это условие и не будет накладывать лишних фильтров на уровне СУБД.
Часто пользователям неудобно вводить две даты вручную. Гораздо проще выбрать вариант «Прошлый месяц» или «Текущий квартал». Для этого в 1С используется тип данных СтандартныйПериод. Разберем, как связать его с нашим запросом в СКД:
ПериодОтчета и установим ему тип СтандартныйПериод.НачалоПериода и КонецПериода установим галочку Ограничение доступности (чтобы пользователь не видел их отдельно).НачалоПериода напишем: &ПериодОтчета.ДатаНачала.КонецПериода напишем: &ПериодОтчета.ДатаОкончания.Такой подход обеспечивает профессиональный интерфейс и корректную работу всех наборов данных отчета.
Проанализируем важный технический нюанс. Если пользователь выбирает дату окончания периода как «31.12.2023», то по умолчанию 1С трактует это как начало дня — «31.12.2023 00:00:00». В результате все документы, созданные в течение этого дня (например, в 12:00), не попадут в отчет, так как их дата больше, чем значение параметра.
Чтобы избежать этой ошибки, в выражении параметра КонецПериода на вкладке «Параметры» СКД всегда следует использовать функцию КонецПериода():
КонецПериода(&КонецПериода, "День")
Или, если используется связь со стандартным периодом:
КонецПериода(&ПериодОтчета.ДатаОкончания, "День")
В некоторых случаях, когда форма отчета сильно кастомизирована, стандартная связь параметров может нарушаться. Тогда нам поможет использование модуля объекта отчета и процедуры ПриКомпоновкеРезультата. Рассмотрим пример кода, который принудительно устанавливает значения параметров перед формированием отчета:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
Настройки = КомпоновщикНастроек.Настройки;
// Поиск параметра в настройках компоновщика
ПараметрНачало = Настройки.ПараметрыДанных.Элементы.Найти("НачалоПериода");
Если ПараметрНачало <> Неопределено Тогда
ПараметрНачало.Значение = ДатаНачалаСФормы; // Ваша переменная с формы
ПараметрНачало.Использование = Истина;
КонецЕсли;
ПараметрКонец = Настройки.ПараметрыДанных.Элементы.Найти("КонецПериода");
Если ПараметрКонец <> Неопределено Тогда
ПараметрКонец.Значение = КонецДня(ДатаКонцаСФормы);
ПараметрКонец.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Использование этого метода гарантирует, что какие бы манипуляции ни производились на форме, в запрос СКД попадут именно те даты, которые выбрал пользователь. Важно помнить, что при использовании программной установки параметров необходимо следить за актуальностью имен параметров в тексте запроса и в коде 1С.
Подведем итог: для корректной работы периода в сложных отчетах СКД необходимо всегда проверять наличие условия ГДЕ в запросах к физическим таблицам (документам, справочникам) и правильно настраивать выражения параметров для обработки времени (конец дня).