Разработка отчетов на базе Системы компоновки данных (СКД) в 1С — задача стандартная, но у начинающих разработчиков она часто вызывает массу трудностей. Типичная ситуация: создается запрос, на форму выводятся поля для фильтрации, но при попытке сформировать отчет система либо выдает ошибку, либо игнорирует введенные данные, либо наотрез отказывается принимать список значений или группы справочника. В этой статье мы подробно разберем, почему так происходит, выясним разницу между параметрами запроса и отборами СКД, а также пошагово настроим гибкую систему фильтрации.
Для начала давайте разберем ключевую архитектурную ошибку, которую совершают многие начинающие программисты. Они пытаются реализовать фильтрацию данных через жесткие параметры внутри текста запроса, используя конструкцию ГДЕ Поле = &Параметр, но при этом хотят, чтобы пользователь мог гибко управлять этим условием на форме.
Давайте проанализируем, почему этот подход не работает должным образом:
&Параметр прописан в секции ГДЕ обычным образом, СУБД потребует его обязательного заполнения. Если пользователь оставит поле пустым, программа выдаст ошибку "Значение параметра не задано".= никогда не позволит пользователю выполнить отбор по списку значений или по иерархии (с учетом папок справочника). На СУБД уйдет жесткий запрос, который не умеет трансформироваться на лету.Правильный подход СКД: Запрос пишется без жестких условий фильтрации в секции ГДЕ (выбираются абсолютно все данные). Все отборы накладываются динамически на уровне самой схемы компоновки. При формировании отчета СКД автоматически модифицирует итоговый SQL-запрос, добавляя в него только те условия, которые реально заполнил пользователь. Если пользователь оставил отбор пустым, СКД просто не будет добавлять это условие в запрос, и отчет сформируется без ошибок.
Давайте пошагово разберем, как правильно перенести фильтрацию в динамические отборы схемы компоновки данных:
Подразделение.Равно. Мы можем оставить его таким или сразу изменить на более универсальный.Чтобы пользователь увидел этот отбор непосредственно на форме отчета (в шапке или в панели быстрых настроек), его необходимо включить в пользовательские настройки. Давайте выполним следующие действия:
Быстрый доступ (тогда поле отобразится прямо в шапке отчета) или Обычный (отбор будет доступен в настройках отчета).После этого запустим отчет в режиме "1С:Предприятие". Мы увидим, что поле появилось на форме. Теперь пользователь может самостоятельно кликнуть на вид сравнения прямо на форме и выбрать нужный вариант: Равно, В списке, Не равно и так далее. Если поле оставить пустым, отчет корректно выведет все данные.
Иногда по соображениям производительности (например, при работе с виртуальными таблицами остатков или оборотов) нам критически важно передать отбор непосредственно в параметры виртуальной таблицы СУБД, но при этом мы хотим сохранить его необязательность. В обычных запросах 1С это сделать сложно, но в СКД для этого существует мощный механизм — расширение языка запросов, использующий фигурные скобки {}.
Рассмотрим пример правильного написания запроса с необязательными параметрами в СКД:
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот КАК Количество
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , {Номенклатура.* КАК Номенклатура}) КАК ПродажиОбороты
Давайте проанализируем, как работает эта конструкция:
В (&СписокНоменклатуры).Очень частая проблема, с которой столкнулся автор темы на форуме: при выборе вида сравнения В списке система позволяет выбирать только конкретные элементы справочника (например, конкретные средства индивидуальной защиты), но не дает выбрать группу (папку) целиком.
Давайте разберем, почему так происходит. Вид сравнения В списке в платформе 1С предназначен для поиска точного соответствия элементам из указанного перечня. Он преобразуется в SQL-инструкцию IN (...). Если вы поместите туда папку справочника, система будет искать записи, у которых в поле ссылки указана непосредственно эта папка, а не товары внутри нее. Естественно, такой отбор вернет пустой результат.
Чтобы отбор корректно работал как по конечным элементам, так и по целым папкам (иерархически), мы должны использовать другие виды сравнения:
Для того чтобы этот вид сравнения был доступен пользователю по умолчанию, настройте его в конфигураторе на вкладке Отбор, выбрав для поля вид сравнения В группе из списка перед выводом в пользовательские настройки.
Если вам по какой-то причине приходится работать с параметрами-списками напрямую в запросе без использования механизмов динамической компоновки СКД, стандартная конструкция ГДЕ Поле В (&Параметр) при пустом списке выдаст ошибку СУБД. Чтобы обойти это ограничение, программисты используют следующий логический прием в тексте запроса:
ВЫБРАТЬ
СпрСотрудники.Ссылка КАК Сотрудник,
СпрСотрудники.Подразделение КАК Подразделение
ИЗ
Справочник.Сотрудники КАК СпрСотрудники
ГДЕ
(СпрСотрудники.Подразделение В (&СписокПодразделений)
ИЛИ НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1 1
ИЗ Справочник.Подразделения КАК Спр
ГДЕ Спр.Ссылка В (&СписокПодразделений)))
Давайте разберем логику этого условия. Если список подразделений пуст, подзапрос во второй части условия вернет пустой результат (ложь), соответственно, выражение НЕ 1 В (ПустойРезультат) вернет истину. В итоге все условие ГДЕ превратится в истину для каждой строки базы данных, и отчет вернет все записи. Если же список заполнен, подзапрос вернет единицу, правая часть станет ложной, и СУБД будет фильтровать записи исключительно по левой части — то есть по вхождению в список.
Однако помните, что этот прием создает дополнительную нагрузку на сервер СУБД и усложняет чтение кода. Использование стандартных динамических отборов СКД является более современным, производительным и рекомендуемым стандартом разработки в экосистеме 1С.