Работа с данными в платформе 1С:Предприятие неразрывно связана с написанием запросов. Когда разработчику необходимо получить выборку из регистра сведений или документа, часто возникает потребность отфильтровать результаты не по одному, а сразу по нескольким критериям. Синтаксис встроенного языка запросов 1С, основанный на SQL, позволяет гибко управлять логикой отбора, используя логические операторы. Понимание того, как правильно сформулировать условие отбора, является фундаментом для создания корректных отчетов и печатных форм.
Рассмотрим типовую ситуацию: вам нужно получить список товаров, которые находятся на конкретном складе И имеют определенную категорию номенклатуры. Это классический пример пересечения множеств. Ошибки в расстановке приоритетов или неверное использование скобок могут привести к тому, что система вернет лишние записи или, наоборот, исключит нужные. В этой статье мы детально разберем механизмы формирования сложных условий, работу в Конструкторе запроса и ручное написание кода.
Основы синтаксиса оператора ВЫБРАТЬ
Любой запрос в 1С начинается с ключевого слова ВЫБРАТЬ, за которым следует список полей. Однако"сердцем" фильтрации является секция ГДЕ. Именно здесь прописываются условия, которые могут быть как простыми (одно поле равно значению), так и составными. Когда в запросе фигурируют два условия, между ними обязательно должен стоять логический оператор: И (AND) или ИЛИ (OR). От выбора этого оператора зависит итоговая логика работы программы.
Оператор И требует одновременного выполнения всех перечисленных условий. Если хотя бы одно из них ложно, запись в выборку не попадет. Например, запрос"Номенклатура ='ТоварА' И Склад ='Основной'" вернет строки только там, где оба параметра совпадают. Напротив, оператор ИЛИ расширяет выборку: запись будет выбрана, если верно первое условие ИЛИ второе условие, либо оба сразу. Это критически важно учитывать при построении отчетов для бухгалтерии или склада.
Платформа 1С автоматически приводит типы данных при сравнении, но полагаться на это полностью не стоит. Явное приведение типов или использование правильных констант в условии повышает читаемость кода и снижает риск ошибок исполнения. В сложных запросах, где задействовано несколько таблиц через ИЗ и ЛЕВОЕ СОЕДИНЕНИЕ, условия могут применяться как к полям основной таблицы, так и к полям присоединенных таблиц.
Работа с логическими операторами И и ИЛИ
Комбинирование условий требует понимания приоритетов выполнения операций. В языке запросов 1С оператор И имеет более высокий приоритет, чем ИЛИ. Это означает, что если вы напишете условие без скобок, смешав эти операторы, система сначала выполнит группировку по И, а затем применит ИЛИ. Такая логика часто приводит к непредсказуемым результатам для новичков. Чтобы избежать путаницы, всегда используйте скобки для явного группирования условий.
Представим задачу: нужно выбрать документы, которые проведены ИЛИ имеют пометку удаления, но только если они относятся к организации"Ромашка". Без скобок запрос может сработать некорректно, выбрав все проведенные документы всех организаций. Правильная запись в секции ГДЕ должна выглядеть так: (Проведение = ИСТИНА ИЛИ ПометкаУдаления = ИСТИНА) И Организация = Ссылка.Организации.Ромашка. Здесь скобки четко отделяют группу условий статуса документа от условия фильтрации по контрагенту.
Использование вложенных условий позволяет строить сколь угодно сложные фильтры. Вы можете вкладывать одни скобки в другие, создавая многоуровневую логику отбора. Главное правило — следить за парностью скобок. среды разработки 1С обычно подсвечивает парные скобки, что облегчает визуальный контроль структуры запроса. При большом количестве условий рекомендуется разбивать их на строки для улучшения читаемости кода.
Используйте форматирование кода (Ctrl+Shift+F) в редакторе модуля, чтобы автоматически выровнять скобки и отступы в сложных запросах. Это поможет сразу заметить незакрытую скобку.
Использование Конструктора запроса
Для тех, кто не хочет писать код вручную или хочет ускорить процесс разработки, в конфигураторе 1С предусмотрен мощный инструмент — Конструктор запроса. Он позволяет визуально формировать структуру выборки, добавлять таблицы и настраивать отборы. При работе с двумя и более условиями конструктор автоматически расставляет необходимые скобки и операторы, минимизируя риск синтаксических ошибок. Это особенно полезно при работе с виртуальными таблицами регистров.
Чтобы добавить второе условие в конструкторе, необходимо перейти на вкладку"Отбор". Здесь вы увидите список полей, доступных для фильтрации. Добавляя новое поле в список отбора, вы можете выбрать условие сравнения (Равно, Больше, В списке) и значение. Логическая связь между строками отбора по умолчанию часто устанавливается как И, но конструктор позволяет изменять эту связь, группируя условия. Визуальное представление дерева отборов помогает понять, как именно система будет фильтровать данные.
Однако стоит помнить, что конструктор не всегда генерирует оптимальный код с точки зрения производительности. В простых случаях разницы нет, но при сложных объединениях (ОБЪЕДИНИТЬ) или вложенных запросах ручной контроль может быть предпочтительнее. Тем не менее, для стандартных задач фильтрации по двум полям (например, период и контрагент) этот инструмент является незаменимым помощником, экономящим время разработчика.
Оптимизация выборки и индексы
Наличие двух условий в запросе напрямую влияет на производительность системы. Если одно из условий накладывается на поле, по которому нет индекса, а второе — на проиндексированное поле, база данных может пойти по пути полного сканирования таблицы, что крайне медленно на больших объемах данных. Платформа 1С стремится использовать индексы максимально эффективно, но структура условия играет решающую роль. Важно, чтобы условия, сужающие выборку сильнее всего, попадали в индексируемые поля.
При использовании оператора И оптимизатор запросов обычно может использовать индекс хотя бы по одному из полей, если такой существует. Но если вы используете ИЛИ, ситуация усложняется. Часто при условии Поле1 = Знач1 ИЛИ Поле2 = Знач2 индекс не используется вовсе, так как системе проще прочитать всю таблицу, чем делать два поиска и объединять результаты. В таких случаях иногда выгоднее переписать логику программы, используя два отдельных запроса и объединяя их результаты в коде или через ОБЪЕДИНИТЬ ВСЕ.
Анализ плана выполнения запроса (доступен в режиме отладки или через консоль запросов) показывает, какие индексы были использованы. Если вы видите предупреждение о полном обходе таблицы (Table Scan) при выборке из миллионов записей, это сигнал к пересмотру структуры условий. Возможно, стоит изменить порядок полей в индексе справочника или регистра, чтобы он соответствовал частым сценариям выборки с двумя условиями.
Оператор ИЛИ часто приводит к отказу от использования индексов. Для больших баз данных старайтесь заменять сложные условия ИЛИ на объединение результатов нескольких простых запросов.
Типичные ошибки при формировании условий
Одной из самых распространенных ошибок является путаница между значениями NULL (Неопределено) и пустыми строками или нулями. В 1С сравнение поля с NULL требует специального синтаксиса: Поле ИС NULL или Поле ЕСТЬ NULL. Обычное равенство Поле = NULL всегда вернет ложь, так как неопределенное значение не может быть равно самому себе в контексте стандартного сравнения. Это часто приводит к тому, что второе условие в запросе просто игнорируется системой.
Еще одна проблема возникает при работе со ссылочными типами данных. Начинающие разработчики часто пытаются сравнить ссылку на элемент справочника со строковым представлением его наименования. Это грубая ошибка. Условие должно сравнивать ссылку с ссылкой: Номенклатура = &ПараметрНоменклатуры, где параметр имеет тип СправочникСсылка.Номенклатура. Сравнение разных типов может привести к неявным преобразованиям, которые замедляют запрос или дают неверный результат.
Также стоит упомянуть ошибку"лишних" условий. Иногда разработчики дублируют фильтрацию: сначала в запросе, а потом в коде перебирают результат и отбирают нужное. Это двойная работа, которая нагружает сервер. Все условия, которые можно выразить на языке запросов, должны быть вынесены в секцию ГДЕ. Фильтрация в цикле по полученному набору данных допустима только в исключительных случаях, когда логика не может быть выражена средствами SQL.
⚠️ Внимание: При использовании условий с датами помните о временной зоне сервера. Условие
Дата < КонецДня(Сегодня)может работать некорректно, если сервер и клиент находятся в разных часовых поясах. Всегда используйте функции работы с датами платформы 1С.
Примеры кода и практическое применение
Рассмотрим конкретный пример запроса на встроенном языке 1С. Допустим, нам нужно получить остатки товаров на конкретную дату для определенного склада. Здесь мы используем виртуальную таблицу остатков регистра накопления. В условии будут фигурировать два параметра: склад и момент времени.
ВЫБРАТЬ
ОстаткиНоменклатуры.Номенклатура,
ОстаткиНоменклатуры.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК ОстаткиНоменклатуры
ГДЕ
ОстаткиНоменклатуры.Склад = &Склад
И ОстаткиНоменклатуры.КоличествоОстаток > 0
В данном примере первое условие фильтрует данные по складу, а второе отсеивает товары с нулевым остатком. Обратите внимание на использование параметров (&Период, &Склад). Это обязательная практика для безопасности и переиспользования запроса. Значения параметров передаются из кода программы перед выполнением. Такой подход защищает от SQL-инъекций и позволяет компилятору 1С кэшировать план выполнения запроса.
Если бы нам потребовалось выбрать товары, у которых остаток больше нуля ИЛИ которые имеют отрицательный остаток (пересортица), но только для избранной группы номенклатуры, запрос усложнился бы. Мы бы использовали конструкцию (КоличествоОстаток > 0 ИЛИ КоличествоОстаток < 0) И Номенклатура.ГруппаВладельца = &Группа. Такая логика позволяет гибко управлять отчетностью в зависимости от потребностей пользователя.
☑️ Проверка запроса перед запуском
Сравнение методов фильтрации данных
Выбор способа реализации условий зависит от контекста задачи. Ниже приведена таблица, сравнивающая различные подходы к фильтрации данных при наличии двух и более условий в системе 1С.
| Метод | Производительность | Сложность реализации | Рекомендуемое использование |
|---|---|---|---|
Оператор И в запросе |
Высокая (использует индексы) | Низкая | Стандартная фильтрация по нескольким полям |
Оператор ИЛИ в запросе |
Средняя/Низкая (риск сканирования) | Низкая | Поиск по альтернативным критериям |
| Фильтрация в коде (цикл) | Очень низкая (на больших данных) | Средняя | Сложная логика, не выражаемая в SQL |
| Виртуальные таблицы | Высокая (оптимизировано платформой) | Средняя | Работа с остатками и оборотами регистров |
Как видно из таблицы, наиболее эффективным методом остается использование операторов непосредственно в тексте запроса. Платформа 1С спроектирована так, чтобы перекладывать максимальный объем работы по фильтрации на сервер баз данных. Выгрузка всех данных в оперативную память клиента с последующей фильтрацией в цикле — это антипаттерн, которого следует избегать при работе с большими объемами информации.
⚠️ Внимание: Интерфейс и возможности конструктора запросов могут незначительно отличаться в разных версиях платформы 1С (8.2, 8.3, 8.3.20+). Всегда проверяйте актуальность функций в справке вашей конфигурации.
Как работает оптимизатор запросов 1С?
Оптимизатор анализирует текст запроса перед его отправкой в СУБД. Он перестраивает дерево условий, стараясь применить самые селективные фильтры (те, что отбирают меньше всего записей) как можно раньше. Если в условии есть"И", он попытается найти индекс для любого из полей. Если есть"ИЛИ", он часто вынужден читать таблицу полностью, поэтому такие запросы требуют особого внимания к индексам.
Часто задаваемые вопросы (FAQ)
Можно ли использовать более двух условий в одном запросе 1С?
Да, количество условий в секции ГДЕ практически не ограничено. Вы можете комбинировать десятки условий, используя скобки для группировки. Главное — следить за производительностью и читаемостью кода.
В чем разница между И и & в условиях 1С?
В языке запросов 1С используется ключевое слово И. Символ & используется для обозначения параметров запроса (например, &МойПараметр), а не как логический оператор. Использование & вместо И приведет к синтаксической ошибке.
Почему запрос с двумя условиями работает медленно?
Вероятнее всего, одно из условий наложено на поле без индекса, либо используется оператор ИЛИ, который мешает использованию существующих индексов. Также причиной может быть функция в условии (например, ГОД(Дата) = 2026), которая запрещает использование индекса по дате.
Как проверить, правильно ли сработали условия?
Используйте консоль запросов в конфигураторе или режиме предприятия (если есть права). Выполните запрос и сверите полученную выборку с данными в таблице. Также можно использовать отладчик, чтобы пошагово проконтролировать формирование параметров.
⚠️ Внимание: Никогда некодируйте (не вписывайте жестко) значения в текст запроса, если они могут меняться. Всегда используйте параметры. Это не только безопасно, но и позволяет системе кэшировать план выполнения запроса, ускоряя повторные запуски.