Разработка отчетов на схеме компоновки данных (СКД) в платформе «1С:Предприятие 8.3» — задача стандартная, но часто преподносящая сюрпризы даже опытным разработчикам. Одной из наиболее распространенных проблем является ситуация, когда условия по периоду или датам, добавленные в запрос, попросту игнорируются системой. Отчет упорно продолжает выводить данные за все время существования базы данных, несмотря на установленные пользователем параметры.
В этой статье мы подробно разберем, почему так происходит, проанализируем неочевидные логические ошибки в запросах с объединениями, научимся правильно связывать параметры с типом СтандартныйПериод, использовать возможности расширения языка запросов СКД и бороться с коварным кэшированием внешних отчетов в конфигурациях на базе БСП (Библиотеки Стандартных Подсистем), таких как «Управление торговлей 11».
Рассмотрим ситуацию, когда в основе набора данных СКД лежит запрос, состоящий из нескольких частей, объединенных с помощью конструкции ОБЪЕДИНИТЬ ВСЕ. Это частая практика, когда необходимо собрать данные из разных таблиц документа или разных регистров в один плоский список.
Типичная ошибка начинающего разработчика заключается в том, что условие фильтрации по датам накладывается только на одну из частей объединения. Посмотрим на упрощенную схему такого некорректного запроса:
ВЫБРАТЬ
Реализация.Ссылка КАК Ссылка,
Реализация.Дата КАК Дата,
Реализация.СуммаДокумента КАК Сумма
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Проведен
И Реализация.Дата >= &ДатаНач
И Реализация.Дата <= &ДатаКон
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Реализация.Ссылка,
Реализация.Дата,
Реализация.СуммаДокумента
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Проведен
// Условия по датам здесь отсутствуют!
Проанализируем работу этого пакета. Первая ветка объединения честно отсекает документы, не попадающие в указанный интервал между &ДатаНач и &ДатаКон. Однако вторая ветка, не имеющая ограничений в секции ГДЕ, выбирает абсолютно все проведенные документы из базы данных за весь период ее существования. При объединении результатов мы получаем полную выборку документов, что сводит на нет все усилия по фильтрации в первой ветке.
Правило: Если в вашем запросе используется конструкция ОБЪЕДИНИТЬ или ОБЪЕДИНИТЬ ВСЕ, условия ограничения периода должны быть продублированы во всех частях запроса, которые обращаются к документам или периодическим регистрам. Исправленный вариант запроса должен выглядеть следующим образом:
ВЫБРАТЬ
Реализация.Ссылка КАК Ссылка,
Реализация.Дата КАК Дата,
Реализация.СуммаДокумента КАК Сумма
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Проведен
И Реализация.Дата >= &ДатаНач
И Реализация.Дата <= &ДатаКон
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Реализация.Ссылка,
Реализация.Дата,
Реализация.СуммаДокумента
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Проведен
И Реализация.Дата >= &ДатаНач
И Реализация.Дата <= &ДатаКон
Когда отчет выводит некорректные данные, сложно сразу определить, где именно кроется ошибка — в тексте запроса или в настройках самой компоновки данных. СКД представляет собой сложный механизм, который перед отправкой SQL-запроса к СУБД существенно видоизменяет его текст, накладывая собственные отборы, группировки и параметры.
Для локализации проблемы всегда используем простое правило: проверяем работу запроса отдельно от СКД. Для этого выполним следующие действия:
&ДатаНач и &ДатаКон и запустим выполнение.Если в консоли запросов выборка отработала корректно и вернула документы строго за выбранный период времени, значит, проблема кроется исключительно в настройках схемы компоновки данных. Если же консоль запросов вернула лишние данные — ошибка допущена непосредственно в логике самого SQL-запроса (например, пропущены условия в объединениях, как было описано выше).
С точки зрения юзабилити заставлять пользователя выбирать даты начала и окончания периода в двух отдельных полях — дурной тон. Гораздо удобнее предоставить ему стандартный интерактивный выбор периода (например, «Текущий месяц», «Прошлый квартал» или «Произвольный период»). Для этого в 1С используется специальный тип данных — СтандартныйПериод.
Разберем по шагам, как связать этот пользовательский период с техническими параметрами нашего запроса &ДатаНач и &ДатаКон:
Период, ДатаНач и ДатаКон.Период укажем тип данных СтандартныйПериод. Этот параметр мы сделаем доступным для пользователя (флаг «Ограничение доступности» должен быть снят).ДатаНач и ДатаКон установим флаг «Ограничение доступности». Пользователю не нужно видеть их на форме настроек, они будут заполняться автоматически на основе выбранного периода.ДатаНач пропишем строгое системное выражение: &Период.ДатаНачала.ДатаКон пропишем выражение: &Период.ДатаОкончания.Очень важно не допускать синтаксических ошибок в написании свойств структуры. У типа СтандартныйПериод нет свойств «ДатаНач» или «ДатаКон». Платформа распознает только полные имена свойств: ДатаНачала и ДатаОкончания. Попытка написать &Период.ДатаНач приведет к возникновению критической ошибки «Поле не найдено» при компиляции отчета.
Когда мы жестко прописываем в запросе условие ГДЕ Реализация.Дата >= &ДатаНач, эти параметры автоматически становятся обязательными для заполнения. Если пользователь попытается сформировать отчет с пустыми датами, система выдаст ошибку. Но что делать, если мы хотим сделать отбор по периоду необязательным?
Для решения этой задачи в СКД применяется механизм расширения языка запросов, использующий фигурные скобки {}. Конструкции внутри фигурных скобок обрабатываются компоновщиком данных динамически. Если параметр заполнен — условие встраивается в итоговый запрос к базе данных, если не заполнен — СКД просто игнорирует и вырезает этот кусок кода.
Рассмотрим пример правильного написания условий с использованием фигурных скобок:
ВЫБРАТЬ
Реализация.Ссылка КАК Ссылка,
Реализация.Дата КАК Дата,
Реализация.Склад КАК Склад
ИЗ
Документ.RealizacijaТоваровУслуг КАК Реализация
ГДЕ
Реализация.Проведен
И {Реализация.Дата >= &ДатаНач}
И {Реализация.Дата <= &ДатаКон}
Также важно упомянуть вкладку «Компоновка данных» в конструкторе запроса. Если вы используете сложные запросы с временными таблицами или вложенными выборками, автозаполнение СКД может сработать некорректно. В таких случаях рекомендуется зайти во вкладку «Компоновка данных» -> «Условия» и вручную указать поля, на которые компоновщик имеет право накладывать динамические фильтры.
Если вы проверили запрос в консоли (там он работает), настроили параметры в СКД, но при запуске отчета в режиме «1С:Предприятие» он все равно выдает старые результаты, вы, скорее всего, столкнулись с системным кэшированием внешних обработок в БСП.
В современных конфигурациях (таких как «Управление торговлей 11.4», «ERP Управление предприятием», «Комплексная автоматизация») все дополнительные отчеты регистрируются в справочнике ДополнительныеОтчетыИОбработки. Двоичные файлы этих отчетов хранятся непосредственно в базе данных 1С.
Когда вы вносите изменения в схему компоновки данных внешнего отчета в Конфигураторе, сохраняете файл на диске под именем, например, МойОтчет.erf, а затем пытаетесь запустить его через стандартное меню «Файл» -> «Открыть», платформа 1С распознает отчет по его внутреннему идентификатору (свойству Имя в конфигураторе) и подменяет его версией, сохраненной в кэше или справочнике дополнительных обработок.
Чтобы гарантированно преодолеть эту проблему и увидеть результаты ваших изменений в процессе разработки, используйте следующие приемы:
МойОтчет_0108). Это разорвет связь с кэшированным объектом в БСП, и платформа загрузит актуальный код с диска.Соблюдение этих простых правил убережет вас от ложных выводов о неработоспособности вашего кода и сэкономит массу времени при отладке отчетов на СКД.