Условия в языке запросов

Язык запросов

Синтаксис и применение Условия в языке запросов в платформе 1С:Предприятие. Описание и примеры кода.

Полное описание, параметры и ограничения

Условия в языке запросов

В языке запросов используются условия отбора, в соответствии с которыми осуществляется отбор данных в предложениях ГДЕ, ИМЕЮЩИЕ и СОЕДИНЕНИЕ. Условия описываются по следующим правилам:

<Условие отбора>

|

<Логическое слагаемое> [ИЛИ <Логическое слагаемое>]

|

<Логический сомножитель> [И <Логический сомножитель>]

|

НЕ <Логический сомножитель> |
( <Условие отбора> ) |
<Логическое выражение>

В простейшем случае условие является выражением, результат которого имеет значение логического типа.

Условия могут определяться и как более сложные логические выражения, где фигурируют простые логические выражения, соединенные между собой с помощью логических операторов И, ИЛИ, НЕ.

Логические операторы имеют приоритет:

Самый высокий приоритет имеет логический оператор НЕ;

Следующим по приоритету является оператор И;

Самый низкий приоритет у оператора ИЛИ.

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

Практические примеры

МЕЖДУ и скобки: границы цены и приоритет И/ИЛИ

Проверяем включительность 50 и 250, противоположный диапазон и два почти одинаковых условия с разным результатом из-за скобок.

Где и как запускать

Полный серверный общий модуль учебной базы. Собственные значения в памяти, без чтения или записи рабочих данных.

Подготовка

  1. В отдельной учебной базе 8.5.1.1343 создайте общий модуль УчебныйЯзык: Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь. Клиентские и внешнее соединение отключены; ПовторноеИспользованиеВозвращаемыхЗначений=НеИспользовать.

  2. Вставьте весь приведённый текст в этот общий модуль. ВыполнитьПример — экспортная точка входа; остальные процедуры и функции располагаются рядом, а не внутри неё.

  3. В своей внешней учебной обработке создайте управляемую форму, команду Выполнить и кнопку. Клиентский обработчик Выполнить(Команда) вызывает свою процедуру ВыполнитьНаСервере(); она имеет директиву &НаСервереБезКонтекста и одну строку УчебныйЯзык.ВыполнитьПример();. Это серверный вызов общего модуля, а не разрешение клиенту прямо обращаться к серверной библиотеке.

  4. Все товары, количества и строки придуманы в этом модуле. Запись документов, подключение к чужой базе, файлы, сеть и печать не используются. В рабочие общие модули текст не вставляйте.

  5. HTML только показывает BSL. Код в 1С не запускался; перечисленные результаты и отрицательные опыты проверяйте самостоятельно в собственном стенде.

  6. Источник — четыре собственные продажи: Север/Книга/3×250, Север/Ручка/1×50, Юг/Книга/2×250, Юг/Книга/1×300. Всего 1600. Таблица ограниченных типов создаётся в коде, затем попадает в собственную временную таблицу.

  7. Весь урок выполняется в одном серверном вызове с одним МенеджерВременныхТаблиц. При успехе и исключении он закрывается; рабочие таблицы конфигурации не читаются.

Процедура ВыполнитьПример() Экспорт
    Источник = Новый ТаблицаЗначений;
    Источник.Колонки.Добавить("Магазин", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(20)));
    Источник.Колонки.Добавить("Товар", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(20)));
    Источник.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Неотрицательный)));
    Источник.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 2, ДопустимыйЗнак.Неотрицательный)));
    Данные = Новый Массив;
    Данные.Добавить(Новый Структура("Магазин,Товар,Количество,Цена", "Север", "Книга", 3, 250));
    Данные.Добавить(Новый Структура("Магазин,Товар,Количество,Цена", "Север", "Ручка", 1, 50));
    Данные.Добавить(Новый Структура("Магазин,Товар,Количество,Цена", "Юг", "Книга", 2, 250));
    Данные.Добавить(Новый Структура("Магазин,Товар,Количество,Цена", "Юг", "Книга", 1, 300));
    Для Каждого Продажа Из Данные Цикл
        СтрокаИсточника = Источник.Добавить();
        СтрокаИсточника.Магазин = Продажа.Магазин;
        СтрокаИсточника.Товар = Продажа.Товар;
        СтрокаИсточника.Количество = Продажа.Количество;
        СтрокаИсточника.Цена = Продажа.Цена;
    КонецЦикла;
    Если Источник.Количество() <> 4 Или Источник.Итог("Количество") <> 7 Тогда
        ВызватьИсключение "Изменились собственные учебные продажи";
    КонецЕсли;
    Менеджер = Новый МенеджерВременныхТаблиц;
    Попытка
        Создание = Новый Запрос;
        Создание.МенеджерВременныхТаблиц = Менеджер;
        Создание.Текст = "ВЫБРАТЬ
        |    Продажи.Магазин КАК Магазин,
        |    Продажи.Товар КАК Товар,
        |    Продажи.Количество КАК Количество,
        |    Продажи.Цена КАК Цена,
        |    Продажи.Количество * Продажи.Цена КАК Сумма
        |ПОМЕСТИТЬ ВТСобственныеПродажи
        |ИЗ &Источник КАК Продажи";
        Создание.УстановитьПараметр("Источник", Источник);
        Создание.Выполнить();
        Запрос = Новый Запрос;
        Запрос.МенеджерВременныхТаблиц = Менеджер;
        НижняяЦена = 50;
        ВерхняяЦена = 250;
        Если НижняяЦена > ВерхняяЦена Тогда
            ВызватьИсключение "Нижняя граница своей цены не должна превышать верхнюю";
        КонецЕсли;
        Запрос.УстановитьПараметр("НижняяЦена", НижняяЦена);
        Запрос.УстановитьПараметр("ВерхняяЦена", ВерхняяЦена);
        Запрос.Текст = "ВЫБРАТЬ Продажи.Магазин, Продажи.Товар, Продажи.Сумма
        |ИЗ ВТСобственныеПродажи КАК Продажи
        |ГДЕ Продажи.Цена МЕЖДУ &НижняяЦена И &ВерхняяЦена";
        Результат = Запрос.Выполнить().Выгрузить();
        Сообщить(Результат.Количество() = 3);
        Сообщить(Результат.Итог("Сумма") = 1300);
        Запрос.Текст = "ВЫБРАТЬ Продажи.Магазин, Продажи.Товар, Продажи.Сумма
        |ИЗ ВТСобственныеПродажи КАК Продажи
        |ГДЕ Продажи.Цена НЕ МЕЖДУ &НижняяЦена И &ВерхняяЦена";
        Результат = Запрос.Выполнить().Выгрузить();
        Сообщить(Результат.Количество() = 1);
        Сообщить(Результат.Итог("Сумма") = 300);
        Запрос.Текст = "ВЫБРАТЬ Продажи.Магазин, Продажи.Товар, Продажи.Сумма
        |ИЗ ВТСобственныеПродажи КАК Продажи
        |ГДЕ Продажи.Магазин = ""Север"" ИЛИ Продажи.Товар = ""Книга"" И Продажи.Цена = 300";
        Результат = Запрос.Выполнить().Выгрузить();
        Сообщить(Результат.Количество() = 3);
        Сообщить(Результат.Итог("Сумма") = 1100);
        Запрос.Текст = "ВЫБРАТЬ Продажи.Магазин, Продажи.Товар, Продажи.Сумма
        |ИЗ ВТСобственныеПродажи КАК Продажи
        |ГДЕ (Продажи.Магазин = ""Север"" ИЛИ Продажи.Товар = ""Книга"") И Продажи.Цена = 300";
        Результат = Запрос.Выполнить().Выгрузить();
        Сообщить(Результат.Количество() = 1);
        Сообщить(Результат.Итог("Сумма") = 300);
        Запрос.Текст = "ВЫБРАТЬ Продажи.Магазин, Продажи.Товар, Продажи.Сумма
        |ИЗ ВТСобственныеПродажи КАК Продажи
        |ГДЕ НЕ (Продажи.Товар = ""Книга"")";
        Результат = Запрос.Выполнить().Выгрузить();
        Сообщить(Результат.Количество() = 1);
        Сообщить(Результат.Итог("Сумма") = 50);
    Исключение
        Менеджер.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Менеджер.Закрыть();
КонецПроцедуры

Разбор по шагам

  1. Параметры границ — собственные числа 50 и 250. Подготовительная проверка запрещает нижнюю границу выше верхней вместо угадывания поведения обратного диапазона.

  2. МЕЖДУ включает обе границы: ручка по 50 и две книжные строки по 250 попадают в отбор. Итог — 3 строки, 1300.

  3. НЕ МЕЖДУ выбирает южную книгу по 300: 1 строка и 300. Это дополнение для четырёх известных числовых цен этого источника.

  4. Без скобок И вычисляется раньше ИЛИ: Север ИЛИ (Книга И Цена=300). Обе северные строки и южная по 300 дают 3 строки, 1100.

  5. Со скобками (Север ИЛИ Книга) И Цена=300 остаётся только цена 300: 1 строка и 300. Скобки меняют условие, не просто его оформление.

  6. НЕ имеет более высокий приоритет; явное НЕ (Товар=Книга) выбирает ручку на 50. Используем скобки, чтобы намерение читалось однозначно.

  7. Диапазоны и логические сочетания применяются в ГДЕ до агрегирования. Суммы здесь считаются по уже выгруженным строкам для проверки.

Как проверить результат

  1. Десять сравнений Истина: пары 3/1300, 1/300, 3/1100, 1/300, 1/50.

  2. Сверьте записи по граничным ценам: 50 и 250 не исключаются из МЕЖДУ.

  3. При перестановке начальных границ подготовка останавливается до отбора. Не называйте это результатом обратного МЕЖДУ на сервере.

Ожидаемый результат

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

На что обратить внимание

  1. Не путайте И в синтаксисе МЕЖДУ с внешним логическим И. Границы — значения, не названия колонок.

  2. Не переносите арифметический приоритет на логические операторы: НЕ выше И, И выше ИЛИ.

  3. Цена и Сумма разные поля. Отбор цены 250 не означает сумму строки 250 при количестве 2 или 3.

  4. Сравнения со ссылками, строками и NULL имеют другие правила. Здесь используются известные числовые цены; рабочие товары не читаются.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.