Работа с данными в системе 1С:Предприятие практически всегда сводится к их выборке и последующей обработке. Конструктор запросов и ручной ввод кода позволяют извлекать информацию из базы, но новички часто сталкиваются с трудностями при составлении сложных условий фильтрации. Самой распространенной задачей является необходимость отобрать записи, соответствующие сразу нескольким критериям одновременно.

Неправильное построение логической цепочки в секции ГДЕ может привести к тому, что отчет покажет либо все данные подряд, либо пустой результат. Понимание приоритетов логических операций и правильного синтаксиса операторов сравнения является фундаментальным навыком для любого разработчика платформы. В этой статье мы детально разберем, как корректно формировать выборку, используя несколько фильтров в языке запросов 1С и в системе компоновки данных.

Логика построения сложных условий в языке запросов

Основой любой выборки является оператор ВЫБРАТЬ, за которым следует список полей и таблица источника. Однако «сердцем» фильтрации выступает секция ГДЕ. Именно здесь формулируются правила, по которым система решает, оставить запись в результирующей таблице или отбросить её. Когда требуется проверить два условия, в дело вступают логические операторы И (AND) и ИЛИ (OR).

Оператор И требует одновременного выполнения всех перечисленных условий. Если хотя бы одно из них ложно, вся строка исключается из выборки. Это наиболее частый сценарий, например, при поиске товаров определенной номенклатуры на конкретном складе. Оператор ИЛИ, напротив, включает запись в выборку, если истинно хотя бы одно из условий. Это полезно, когда нужно объединить данные разных категорий или статусов в один общий список.

Критически важно помнить о приоритете операций. В языке запросов 1С оператор И имеет более высокий приоритет, чем ИЛИ. Это означает, что без использования скобок система сначала сгруппирует условия, соединенные через И, и только потом применит к ним ИЛИ. Игнорирование этого правила — самая частая причина логических ошибок в отчетах.

⚠️ Внимание: Никогда не полагайтесь на интуицию при смешивании операторов И и ИЛИ. Всегда явно используйте круглые скобки для группировки условий, чтобы логика работы запроса была прозрачной и предсказуемой для любого читателя кода.

Рассмотрим пример, где необходимо выбрать документы, которые проведены ИЛИ имеют определенный вид операции, но только если они относятся к текущему месяцу. Без скобок запрос может выбрать документы прошлого месяца, если они подходят по виду операции, что нарушит логику отчета.

💡

Используйте автоформатирование кода в конфигураторе (Ctrl+Shift+F), чтобы визуально выровнять вложенные условия и скобки — это значительно упрощает отладку сложных запросов.

Синтаксис оператора ГДЕ и работа со скобками

Правильная расстановка скобок в секции ГДЕ позволяет управлять порядком вычисления условий. Каждая пара скобок создает локальный контекст, который вычисляется независимо перед применением внешних логических операторов. Это аналог математических выражений, где действия в скобках выполняются в первую очередь.

Представьте ситуацию, когда нам нужно отобрать контрагентов из города «Москва» ИЛИ «Санкт-Петербург», но при этом они обязательно должны быть группой «Покупатели». Если написать условие линейно: Город = Москва ИЛИ Город = СПб И Группа = Покупатели, то система выберет всех из Москвы (независимо от группы) и только покупателей из СПб. Это классическая ошибка приоритета.

Чтобы исправить логику, необходимо сгруппировать города:

ВЫБРАТЬ

Контрагенты.Наименование,

Контрагенты.Город,

Контрагенты.Группа

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

(Контрагенты.Город = &Город1 ИЛИ Контрагенты.Город = &Город2)

И Контрагенты.Группа = &ГруппаПокупатели

В данном примере сначала вычисляется выражение в скобках (принадлежность к одному из двух городов), и только полученный результат проверяется на соответствие группе. Такой подход гарантирует, что в выборку попадут только нужные записи. Глубина вложенности скобок в 1С не ограничена, что позволяет строить сколь угодно сложные логические конструкции.

📊 Как вы чаще всего проверяете логику запросов?
Вручную по данным в базе
Через консоль запросов
С помощью отладчика
Пишу сразу в коде модуля

Использование параметров и переменных в фильтрах

Жесткая прописывание значений непосредственно в тексте запроса (хардкод) считается плохим тоном программирования в 1С, так как делает код негибким и уязвимым для SQL-инъекций (хотя в встроенном языке это менее актуально, но принцип един). Вместо этого следует использовать параметры, которые передаются в запрос из внешнего кода.

Параметры обозначаются символом амперсанда & перед именем. При выполнении запроса через объект Запрос в коде, значения этим параметрам присваиваются через метод УстановитьПараметр. Это позволяет одному и тому же тексту запроса работать с разными данными в зависимости от ситуации, например, при формировании отчета за разные периоды или для разных организаций.

  • 📌 Передача параметров делает код универсальным и переиспользуемым.
  • 📌 Система автоматически экранирует специальные символы в значениях параметров.
  • 📌 Удобство отладки: можно быстро менять значения, не лазая в текст запроса.
  • 📌 Возможность передавать сложные типы данных, такие как массивы или структуры.

Особое внимание стоит уделить типу данных передаваемого параметра. Если в запросе поле имеет тип Число, а параметру передана Строка, содержащая цифры, 1С попытается привести типы, но это может привести к ошибкам или непредсказуемому поведению. Всегда контролируйте типы данных в коде, устанавливающем параметры.

Пример установки параметров в коде 1С:

Запрос = Новый Запрос(ТекстЗапроса);

Запрос.УстановитьПараметр("ДатаНачала", ДатаНачалаПериода);

Запрос.УстановитьПараметр("Организация", ТекущаяОрганизация);

Результат = Запрос.Выполнить();

⚠️ Внимание: При передаче параметров типа Неопределено в условии сравнения (например, Поле = &Параметр), запись не попадет в выборку, так как Неопределено не равно ничему, даже другому Неопределено. Используйте конструкцию ЕСТЬNULL для обработки таких случаев.

Работа с составными типами и ссылками

В конфигурациях 1С часто встречаются поля с составными типами, например, реквизит «СчетКорреспондент», который может хранить ссылку на счет или быть пустым. При выборке по таким полям с двумя условиями необходимо учитывать возможность хранения разных типов данных в одной ячейке.

Если условие предполагает сравнение со ссылкой на объект, убедитесь, что тип параметра соответствует типу ссылки. Частая ошибка возникает при попытке сравнить поле составного типа со строковым представлением объекта. Платформа не всегда может неявно преобразовать строку «Счет 001» в объект типа ПланСчетовСсылка внутри запроса.

Также важно различать проверку на пустую ссылку и проверку на значение. Условие Поле = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) проверяет, не заполнено ли поле. Если же нужно проверить, что поле содержит конкретный элемент, используется прямое сравнение с параметром-ссылкой.

Тип условия Пример синтаксиса Описание поведения
Равенство значению Поле = &Значение Строгое совпадение значения поля с параметром.
Проверка на пустоту Поле = ЗНАЧЕНИЕ(Справочник.ПустаяСсылка) Истинно, если поле не заполнено (NULL).
Вхождение в список Поле В (&Список1, &Список2) Истинно, если значение поля совпадает с любым из перечисленных.
Диапазон значений Поле МЕЖДУ &Мин И &Макс Проверка попадания значения в интервал (включая границы).

При работе со ссылками на разные виды объектов (например, договоры контрагентов и договоры прочих партнеров), которые хранятся в одном поле составного типа, выборка может потребовать приведения типов или использования оператора ТИПЗНАЧЕНИЯ для уточнения, к какому именно объекту относится запись.

Нюансы работы с составными типами

Если в одном поле хранятся ссылки на разные справочники, прямое сравнение Поле = &Параметр сработает корректно только если тип параметра совпадает с типом хранимого значения. Если типы не совпадают, условие вернет Ложь, даже если визуально значения похожи.

Фильтрация в системе компоновки данных (СКД)

Для отчетов, построенных на базе СКД, механизм фильтрации визуально отличается от текстового запроса, но логически подчиняется тем же правилам. Настройки отчета позволяют пользователю или разработчику задавать отборы по полям. Когда требуется установить два условия, в СКД используется дерево отборов.

В конструкторе настроек отчета каждый уровень вложенности отборов по умолчанию связывается оператором И. Это означает, что если вы добавите два отбора на одном уровне (например, «Организация» и «Период»), система будет искать записи, удовлетворяющие обоим условиям одновременно.

Для реализации логики ИЛИ в СКД необходимо использовать группировки отборов. Вы создаете группу отборов, внутри которой условия связаны через ИЛИ, а сама группа затем связывается с остальными условиями через И. Интерфейс позволяет переключать тип связи для каждой группы через выпадающий список.

  • 📊 Отборы верхнего уровня всегда соединяются логическим И.
  • 📊 Группы отборов позволяют создавать сложные логические выражения.
  • 📊 Тип сравнения (Равно, Больше, В списке) выбирается для каждого поля отдельно.
  • 📊 Можно задавать отборы по полям, не выведенным в макет отчета.

Если в самом запросе схемы данных уже стоит жесткая фильтрация, отборы пользователя могут лишь сузить выборку, но не расширить её. Поэтому базовые условия безопасности или логики лучше закладывать в текст запроса схемы.

⚠️ Внимание: В некоторых версиях платформы интерфейс СКД может незначительно отличаться. Если вы не видите опцию создания группы отборов, проверьте права доступа или версию конфигурации, так как функционал мог быть расширен в последних обновлениях.

Оптимизация производительности при множественных условиях

Наличие нескольких условий в запросе напрямую влияет на скорость его выполнения. База данных должна проанализировать индексы и выбрать оптимальный план выполнения. Если условия написаны некорректно, СУБД может отказаться использовать индексы, что приведет к полному сканированию таблиц и тормозам при больших объемах данных.

Одной из распространенных проблем является использование функций в левой части условия сравнения. Например, конструкция ГДЕ ДатаЧасть(Период.Дата) = &Месяц вынуждает базу данных вычислять функцию для каждой строки таблицы, что убивает производительность. Правильнее использовать диапазон дат: ГДЕ Период.Дата >= &НачалоМесяца И Период.Дата <= &КонецМесяца.

Также стоит избегать избыточных условий. Если одно условие строго вытекает из другого (например, проверка конкретного элемента и проверка его родителя, когда элемент уникален), второе условие можно убрать. Лишняя логика усложняет анализ запроса оптимизатором СУБД.

💡

Главный принцип оптимизации: пишите условия так, чтобы СУБД могла использовать индексы. Избегайте функций над полями таблицы в секции ГДЕ и старайтесь использовать простые операторы сравнения.

Для анализа скорости выполнения сложных запросов с множеством условий используйте встроенный инструмент «Консоль запросов» с включенной опцией показа плана выполнения. Это позволит увидеть, какие индексы используются и где возникают «узкие места» при фильтрации по двум и более параметрам.

Частые ошибки и способы их устранения

Даже опытные разработчики иногда допускают ошибки при формировании выборок. Самая коварная из них — путаница в приоритетах логических операций, о которой уже говорилось выше. Вторая по популярности ошибка — неверное использование оператора В (IN) вместо перечисления условий через ИЛИ, или наоборот, когда типы данных в списке не совпадают.

Еще одна проблема возникает при работе с Null-значениями. В SQL-стандарте и в 1С значение NULL не равно самому себе. Условие Поле = NULL всегда ложно. Для проверки на пустое значение нужно использовать специальный синтаксис или сравнение с пустой ссылкой, как было показано ранее. Игнорирование этого факта приводит к тому, что записи с незаполненными полями пропадают из отчетов.

Не стоит забывать про экранирование специальных символов при поиске по строкам. Если одно из условий предполагает поиск подстроки, содержащей знак процента % или подчеркивание _, их необходимо экранировать, иначе они будут восприняты как символы подстановки (wildcards) в операторе ПОДОБНО.

☑️ Проверка корректности запроса

Выполнено: 0 / 5
В чем разница между операторами И и ИЛИ в 1С?

Оператор И требует, чтобы все объединенные им условия были истинны одновременно. Оператор ИЛИ требует истинности хотя бы одного из условий. Приоритет оператора И выше, чем ИЛИ, поэтому без скобок выражение A ИЛИ B И C будет понято как A ИЛИ (B И C).

Как сделать выборку, если поле может быть пустым?

Для проверки на пустое значение используйте сравнение с пустой ссылкой соответствующего типа: Поле = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка). Для составных типов или универсальной проверки можно использовать функцию ЕСТЬNULL(Поле, 0) в сочетании с другими условиями.

Почему запрос с двумя условиями работает медленно?

Вероятно, одно из условий использует функцию над полем таблицы (например, ГОД(Дата)), что запрещает использование индекса. Попробуйте переписать условие на диапазон значений. Также проверьте, есть ли индексы по полям, участвующим в выборке.

Можно ли использовать более двух условий в запросе?

Да, количество условий в секции ГДЕ практически не ограничено. Вы можете комбинировать любое количество операторов И и ИЛИ, используя скобки для группировки любой глубины вложенности.

Как передать список значений в параметр запроса?

Создайте объект СписокЗначений в коде, заполните его и передайте в параметр запроса. В тексте запроса используйте оператор В: ГДЕ Поле В (&СписокПараметр). Это аналог SQL оператора IN.