Как работают несколько строк секции «Условие» в черных запросах 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Логика объединения нескольких директив «Условие»

Рассмотрим типовую ситуацию, когда в тексте запроса указано несколько отдельных строк с ключевым словом Условие:


ТекстЗапроса = "
|Номенклатура = Регистр.ОстаткиТоваров.Номенклатура;
|Количество = Регистр.ОстаткиТоваров.Количество;
|Функция КонОст = КонОст(Количество);
|Условие (Номенклатура = ВыбНоменклатура1);
|Условие (Номенклатура В СписокНоменклатуры);
|";

В платформе 1С 7.7 каждая отдельная строка Условие объединяется с предыдущими исключительно по логическому «И» (AND). Это означает, что строка данных попадет в результат выборки только в том случае, если одновременно удовлетворяет каждому из перечисленных условий.

Проанализируем последствия такого поведения на примере:

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

Как реализовать логическое «ИЛИ» в черном запросе

Если бизнес-логика требует выборки записей, удовлетворяющих хотя бы одному из критериев (логическое «ИЛИ» / OR), все выражения необходимо объединить в рамках одной директивы Условие:


ТекстЗапроса = "
|Номенклатура = Регистр.ОстаткиТоваров.Номенклатура;
|Количество = Регистр.ОстаткиТоваров.Количество;
|Функция КонОст = КонОст(Количество);
|Условие ((Номенклатура = ВыбНоменклатура1) ИЛИ (Номенклатура В СписокНоменклатуры));
|";

Обратите внимание на расстановку круглых скобок: внутренние скобки определяют приоритет логических выражений, а внешние обрамляют тело самой директивы.

Динамическое формирование текста запроса

Когда параметры фильтрации задаются пользователем на форме отчета опционально, оптимальным решением является динамическая сборка текста запроса перед его выполнением. Посмотрим на практический пример реализации:


ТекстЗапроса = "
|Период с НачДата по КонДата;
|Номенклатура = Регистр.ОстаткиТоваров.Номенклатура;
|Количество = Регистр.ОстаткиТоваров.Количество;
|Функция КонОст = КонОст(Количество);
|Группировка Номенклатура без групп;
|";

Если ПустоеЗначение(ВыбНоменклатура) = 0 Тогда
    ТекстЗапроса = ТекстЗапроса + "
    |Условие (Номенклатура = ВыбНоменклатура);";
ИначеЕсли СписокНоменклатуры.РазмерСписка() > 0 Тогда
    ТекстЗапроса = ТекстЗапроса + "
    |Условие (Номенклатура В СписокНоменклатуры);";
КонецЕсли;

Запрос = СоздатьОбъект("Запрос");
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
    Возврат;
КонецЕсли;

Такой подход исключает наложение лишних условий и предотвращает получение пустых выборок из-за взаимно исключающих фильтров.

Особенности работы оператора «В» и учет иерархии

Разберем важные нюансы фильтрации данных по справочникам и спискам значений:

  1. Проверка иерархии: Конструкция Реквизит В СписокЗначений или Реквизит В ВыбГруппа автоматически обрабатывает иерархическую структуру справочника. Если в список передана группа (папка), запрос вернет все входящие в нее элементы и подпапки.
  2. Прямое равенство: Оператор Реквизит = ВыбЭлемент иерархию не разворачивает. Если переменная содержит группу, запрос будет искать только точное совпадение с самой группой.
  3. Отрицание вхождения: Для исключения элементов используется конструкция со скобками: Условие (НЕ (Номенклатура В СписокНоменклатуры));.
  4. Пустой список значений: Если в директиву В передается объект СписокЗначений с нулевым размером (пустой), условие всегда возвращает Ложь, и запрос возвращает пустой результат.
  5. Область видимости переменных: Все идентификаторы, используемые внутри секции Условие, сопоставляются с именами переменных того модуля, где вызывается метод Выполнить(). Они должны быть объявлены и доступны в контексте исполнения.

Производительность и альтернативные варианты

Черные запросы платформы 1С 7.7 имеют архитектурные ограничения: в клиент-серверном (SQL) варианте фильтры из секции Условие не транслируются в SQL-предложение WHERE, а применяются движком локально после загрузки всего объема записей за период. При работе с большими объемами данных рассмотрим альтернативные инструменты:

  1. Фильтры объектов «Регистр»: Использование платформенных методов УстановитьЗначениеФильтра(), ВыбратьИтоги() и ВыбратьДвиженияСОткатом() работает напрямую по индексам таблиц и обеспечивает максимальное быстродействие.
  2. Выборки справочников и документов: Применение методов ИспользоватьРодителя(), ИспользоватьВладельца() и прямой обход через ВыбратьЭлементы() или ВыбратьДокументы() с последующей обработкой в объекте ТаблицаЗначений.
← На главную