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