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

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

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

Базовый синтаксис операторов сравнения

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

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

  • 🔍 = (Равно) — проверяет точное совпадение значений. Часто используется для фильтрации по конкретному контрагенту или документу.
  • 🔍 <> (Не равно) — исключает записи с указанным значением. Полезен при отборе "всего, кроме" определенного статуса.
  • 🔍 >, <, >=, <= — операторы строгого и нестрогого неравенства. Критичны для отборов по датам и суммам.

При работе с ссылочными типами данных (справочники, документы) часто возникает необходимость проверить, является ли ссылка пустой. Для этого используется специальное значение NULL или константа ЗначениеПустойСсылки в встроенном языке, но в тексте запроса чаще оперируют параметрами. Неправильная проверка на пустоту — одна из главных причин появления "лишних" строк в отчетах.

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

💡

Используйте параметризованные запросы вместо подстановки значений напрямую в текст. Это не только защитит от SQL-инъекций, но и позволит платформе 1С кэшировать план выполнения запроса, что значительно ускорит работу при повторных вызовах.

Логические операторы и приоритет вычислений

Сложные выборки редко строятся на одном условии. Чаще всего требуется комбинация нескольких критериев. Для объединения простых условий используются логические операторы И (AND), ИЛИ (OR) и НЕ (NOT). Понимание приоритета их выполнения — ключ к написанию корректной логики отбора.

В языке запросов 1С приоритет операторов строго фиксирован: сначала выполняется НЕ, затем И, и в последнюю очередь ИЛИ. Это означает, что выражение А ИЛИ Б И В будет воспринято системой как А ИЛИ (Б И В), а не как (А ИЛИ Б) И В. Игнорирование этого правила приводит к классическим логическим ошибкам, когда в выборку попадают совершенно лишние записи.

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

Оператор Приоритет Описание Пример использования
НЕ Высокий (1) Инвертирует условие НЕ ПометкаУдаления
И Средний (2) Оба условия должны быть истинны Дата > Начало И Дата < Конец
ИЛИ Низкий (3) Достаточно истинности одного условия ВидОперации = "Приход" ИЛИ ВидОперации = "Расход"

Рассмотрим типичную ошибку: отбор документов, которые проведены ИЛИ не помечены на удаление, но относятся к конкретному складу. Если написать Проведен = ИСТИНА ИЛИ ПометкаУдаления = ЛОЖЬ И Склад = &Склад, то условие склада применится только ко второй части. В результат попадут все проведенные документы со всех складов, что явно не соответствует задаче.

📊 С каким аспектом написания условий в 1С у вас возникают наибольшие трудности?
Приоритет логических операторов
Работа с NULL и пустыми ссылками
Оптимизация сложных отборов
Синтаксис ПОДОБНО и В

Работа со строками и оператор ПОДОБНО

Часто возникает задача найти запись по части названия или кода. Для этого в 1С предусмотрен мощный оператор ПОДОБНО (LIKE), который позволяет использовать шаблоны поиска. Это незаменимый инструмент при реализации пользовательских поисковых форм или аналитических отчетов по номенклатуре.

В шаблонах оператора ПОДОБНО используются специальные символы-заменители. Символ процента % заменяет любую последовательность символов (включая пустую строку), а символ подчеркивания _ заменяет ровно один любой символ. Понимание разницы между ними позволяет строить как широкие, так и очень точные выборки.

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

⚠️ Внимание: Оператор ПОДОБНО чувствителен к регистру в зависимости от настроек сравнения строк в вашей конфигурации и СУБД. Если поиск не находит ожидаемые значения, проверьте, не требуется ли приведение строки к нижнему регистру через функцию СТРОЧНЫЕ() перед сравнением.

Помимо ПОДОБНО, для работы со строками существует оператор В (IN), который позволяет проверить вхождение значения в список. Это более читаемая альтернатива цепочке условий ИЛИ. Например, вместо Валюта = "USD" ИЛИ Валюта = "EUR" ИЛИ Валюта = "RUB" можно написать лаконичное Валюта В ("USD", "EUR", "RUB").

Секреты оптимизации ПОДОБНО

Если вы используете СУБД PostgreSQL или MSSQL, помните, что поиск по шаблону с ведущим процентом ("%слово") отключает использование B-Tree индексов. Для больших таблиц это может увеличить время выполнения запроса с миллисекунд до минут. Старайтесь проектировать условия так, чтобы переменная часть находилась в конце строки.

Особенности отбора по датам и периодам

Работа с временными интервалами — одна из самых частых задач в учетных системах. В 1С даты хранятся с высокой точностью, включая время, что иногда приводит к сюрпризам при отборе. Например, если вы отбираете документы за "1 января", система по умолчанию может понять это как момент начала дня, и документы, проведенные 1 января в 14:00, не попадут в выборку при условии Дата = &Дата.

Для корректного отбора по периодам рекомендуется использовать диапазон дат. Вместо проверки на равенство используйте комбинацию >= для начала периода и < для конца периода. При этом конец периода обычно сдвигается на одну секунду или используется следующий день, чтобы захватить все документы последнего дня включительно.

Типичный паттерн для отбора документов за месяц выглядит следующим образом:

ГДЕ

Дата >= &НачалоПериода

И Дата < &КонецПериода + 1

Здесь важно, что к дате окончания периода мы прибавляем 1 день, но используем строгое неравенство <. Это гарантирует, что будут выбраны все документы до 23:59:59 последнего дня месяца, но не захватится первый документ следующего месяца. Такой подход универсален и работает корректно независимо от того, хранится ли в дате время или нет.

  • 📅 Используйте тип ДатаВремя для точного отбора документов с учетом времени проведения.
  • 📅 Для отчетов по остаткам чаще используется срез последних или первых на дату, где время не так критично, как сама дата среза.
  • 📅 Помните о часовых поясах при работе с веб-сервисами и распределенными базами данных.
💡

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

Проверка на пустые значения и NULL

Одна из самых коварных областей в написании условий — обработка отсутствующих данных. В реляционных базах данных и в 1С понятие "пусто" может означать разные вещи: пустая строка, число 0, пустая ссылка или специальное значение NULL. Смешение этих понятий в одном условии ведет к логическим дырам в отчетах.

Оператор ЕСТЬ NULL предназначен специально для проверки полей, которые могут не иметь значения. Если поле в таблице имеет тип, допускающий неопределенность, простое сравнение Поле = NULL всегда вернет ЛОЖЬ, так как NULL не равен ничему, даже самому себе. Это фундаментальное правило трехзначной логики SQL.

Часто разработчики сталкиваются с проблемой, когда нужно отобрать записи, где поле заполнено ИЛИ не заполнено, но при этом игнорировать записи, где оно равно пустой ссылке. Здесь помогает комбинация условий:

ГДЕ

(Поле ЕСТЬ NULL)

ИЛИ (Поле = &Значение)

И (Поле <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка))

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

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

☑️ Проверка условий перед запуском запроса

Выполнено: 0 / 4

Частые ошибки и оптимизация условий

Написание работающего кода — это только половина дела. Запрос должен работать быстро, особенно на больших объемах данных. Самая распространенная ошибка, убивающая производительность — применение функций к полям таблицы в левой части условия. Когда вы пишете ГДЕ ГОД(Дата) = 2023, база данных вынуждена применить функцию ГОД к каждой записи в таблице, что делает невозможным использование индекса по полю Дата.

Правильный подход — вычислять значения параметров до начала запроса и сравнивать с ними поле напрямую. Вместо функции над полем используйте диапазон: ГДЕ Дата >= НачалоГода И Дата < КонецГода. Это позволяет движку СУБД использовать индекс и мгновенно находить нужный диапазон записей, пропуская миллионы ненужных строк.

Еще одна ошибка — избыточные условия. Не стоит писать ГДЕ Сумма > 0 И Сумма <> 0. Анализатор запросов 1С может упростить некоторые конструкции, но лучше не нагружать его лишней работой. Также следует избегать условий, которые всегда истинны или всегда ложны, так как они могут запутать оптимизатор запросов.

При использовании составных типов в условиях (например, поле хранит и Справочник, и Документ) будьте готовы к тому, что отбор по конкретному типу может работать медленнее. В таких случаях иногда эффективнее разбить выборку на два отдельных запроса с объединением через ОБЪЕДИНИТЬ ВСЕ, если объем данных велик.

Миф об оптимизации

Многие считают, что порядок условий в блоке ГДЕ влияет на скорость. В современных версиях 1С и СУБД это не так. Оптимизатор запросов сам перестраивает условия в наиболее выгодном порядке. Пишите условия в том порядке, который удобен для чтения человеком, а не для машины.

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

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

В чем разница между ПУСТОЙ ССЫЛКОЙ и NULL в условиях 1С?

Пустая ссылка — это конкретное значение ссылочного типа, указывающее на несуществующий объект (обычно UUID из нулей). NULL — это отсутствие значения как такового. В запросах 1С пустая ссылка часто используется как заполнитель в табличных частях, тогда как NULL характерен для полей, которые могут быть не заполнены. Проверка ЕСТЬ NULL не сработает для пустой ссылки, и наоборот.

Можно ли использовать сложные выражения в условиях запроса?

Да, язык запросов 1С поддерживает вычисления прямо в условии. Вы можете писать ГДЕ (Цена * Количество) > 1000. Однако помните правило оптимизации: если выражение зависит только от полей таблицы, это может запретить использование индексов. Старайтесь выносить вычисления в виртуальные таблицы или предварительные отборы, если это критично для скорости.

Как отобрать записи, где поле содержит одно из нескольких подстрок?

Для этого нужно использовать оператор ИЛИ с несколькими условиями ПОДОБНО. Например: ГДЕ Наименование ПОДОБНО "%слово1%" ИЛИ Наименование ПОДОБНО "%слово2%". Альтернативный вариант — использование временной таблицы с шаблонами и соединение с основной таблицей, что может быть быстрее при очень большом количестве искомых подстрок.

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

Скорее всего, вы применяете функцию к полю даты (например, МЕСЯЦ(Дата)) или сравниваете дату с строковым представлением. Убедитесь, что тип параметра совпадает с типом поля (Дата), и вы используете диапазон значений вместо функций. Также проверьте, есть ли индекс по этому полю в конфигурации базы данных.