Синтаксис и применение Условия в языке запросов в платформе 1С:Предприятие. Описание и примеры кода.
Полное описание, параметры и ограничения
Условия в языке запросов
В языке запросов используются условия отбора, в соответствии с которыми осуществляется отбор данных в предложениях ГДЕ, ИМЕЮЩИЕ и СОЕДИНЕНИЕ. Условия описываются по следующим правилам:
<Условие отбора>
|
<Логическое слагаемое> [ИЛИ <Логическое слагаемое>]
|
<Логический сомножитель> [И <Логический сомножитель>]
|
НЕ <Логический сомножитель> |
( <Условие отбора> ) |
<Логическое выражение>
В простейшем случае условие является выражением, результат которого имеет значение логического типа.
Условия могут определяться и как более сложные логические выражения, где фигурируют простые логические выражения, соединенные между собой с помощью логических операторов И, ИЛИ, НЕ.
Логические операторы имеют приоритет:
Самый высокий приоритет имеет логический оператор НЕ;
Следующим по приоритету является оператор И;
Самый низкий приоритет у оператора ИЛИ.
В условиях сначала вычисляются простые логические выражения, затем операции НЕ, затем операции И, в последнюю очередь – операции ИЛИ. Для того, чтобы обеспечить другой порядок вычислений, можно использовать круглые скобки ().
Практические примеры
МЕЖДУ и скобки: границы цены и приоритет И/ИЛИ
Проверяем включительность 50 и 250, противоположный диапазон и два почти одинаковых условия с разным результатом из-за скобок.
Где и как запускать
Полный серверный общий модуль учебной базы. Собственные значения в памяти, без чтения или записи рабочих данных.
Подготовка
В отдельной учебной базе 8.5.1.1343 создайте общий модуль УчебныйЯзык: Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь. Клиентские и внешнее соединение отключены; ПовторноеИспользованиеВозвращаемыхЗначений=НеИспользовать.
Вставьте весь приведённый текст в этот общий модуль. ВыполнитьПример — экспортная точка входа; остальные процедуры и функции располагаются рядом, а не внутри неё.
В своей внешней учебной обработке создайте управляемую форму, команду Выполнить и кнопку. Клиентский обработчик Выполнить(Команда) вызывает свою процедуру ВыполнитьНаСервере(); она имеет директиву &НаСервереБезКонтекста и одну строку УчебныйЯзык.ВыполнитьПример();. Это серверный вызов общего модуля, а не разрешение клиенту прямо обращаться к серверной библиотеке.
Все товары, количества и строки придуманы в этом модуле. Запись документов, подключение к чужой базе, файлы, сеть и печать не используются. В рабочие общие модули текст не вставляйте.
HTML только показывает BSL. Код в 1С не запускался; перечисленные результаты и отрицательные опыты проверяйте самостоятельно в собственном стенде.
Источник — четыре собственные продажи: Север/Книга/3×250, Север/Ручка/1×50, Юг/Книга/2×250, Юг/Книга/1×300. Всего 1600. Таблица ограниченных типов создаётся в коде, затем попадает в собственную временную таблицу.
Весь урок выполняется в одном серверном вызове с одним МенеджерВременныхТаблиц. При успехе и исключении он закрывается; рабочие таблицы конфигурации не читаются.
Процедура ВыполнитьПример() Экспорт
Источник = Новый ТаблицаЗначений;
Источник.Колонки.Добавить("Магазин", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(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);
Исключение
Менеджер.Закрыть();
ВызватьИсключение;
КонецПопытки;
Менеджер.Закрыть();
КонецПроцедурыРазбор по шагам
Параметры границ — собственные числа 50 и 250. Подготовительная проверка запрещает нижнюю границу выше верхней вместо угадывания поведения обратного диапазона.
МЕЖДУ включает обе границы: ручка по 50 и две книжные строки по 250 попадают в отбор. Итог — 3 строки, 1300.
НЕ МЕЖДУ выбирает южную книгу по 300: 1 строка и 300. Это дополнение для четырёх известных числовых цен этого источника.
Без скобок И вычисляется раньше ИЛИ: Север ИЛИ (Книга И Цена=300). Обе северные строки и южная по 300 дают 3 строки, 1100.
Со скобками (Север ИЛИ Книга) И Цена=300 остаётся только цена 300: 1 строка и 300. Скобки меняют условие, не просто его оформление.
НЕ имеет более высокий приоритет; явное НЕ (Товар=Книга) выбирает ручку на 50. Используем скобки, чтобы намерение читалось однозначно.
Диапазоны и логические сочетания применяются в ГДЕ до агрегирования. Суммы здесь считаются по уже выгруженным строкам для проверки.
Как проверить результат
Десять сравнений Истина: пары 3/1300, 1/300, 3/1100, 1/300, 1/50.
Сверьте записи по граничным ценам: 50 и 250 не исключаются из МЕЖДУ.
При перестановке начальных границ подготовка останавливается до отбора. Не называйте это результатом обратного МЕЖДУ на сервере.
Ожидаемый результат
На собственных продажах видны включённые границы диапазона и измеримая разница двух условий с разными скобками.
На что обратить внимание
Не путайте И в синтаксисе МЕЖДУ с внешним логическим И. Границы — значения, не названия колонок.
Не переносите арифметический приоритет на логические операторы: НЕ выше И, И выше ИЛИ.
Цена и Сумма разные поля. Отбор цены 250 не означает сумму строки 250 при количестве 2 или 3.
Сравнения со ссылками, строками и NULL имеют другие правила. Здесь используются известные числовые цены; рабочие товары не читаются.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.