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

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

Основы синтаксиса и место перечисления

В языке запросов 1С перечисление встречается в двух основных контекстах: в секции ВЫБРАТЬ для указания полей и в секции ГДЕ для фильтрации значений. Синтаксически это выглядит как список элементов, разделенных запятыми, заключенный в круглые скобки.

Если вы перечисляете поля в начале запроса, вы определяете структуру результирующей таблицы. При этом каждое поле должно существовать в источнике данных. Например, конструкция ВЫБРАТЬ (Поле1, Поле2) создаст результат только с двумя колонками. Ошибка в названии поля приведет к сбою компиляции модуля.

Когда речь заходит о фильтрации, перечисление значений в операторе В становится мощным инструментом. Оно заменяет громоздкие конструкции с множеством условий ИЛИ. Использование такого подхода делает код более читаемым и упрощает его поддержку в будущем.

💡

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

Платформа автоматически приводит типы в некоторых случаях, но полагаться на это не стоит. Явное указание типов или использование констант правильного вида гарантирует стабильную работу алгоритма выборки данных.

Перечисление полей в секции ВЫБРАТЬ

Формирование списка выводимых полей — первый шаг при написании любого запроса. Здесь перечисление определяет, какие именно колонки попадут в итоговый набор данных. Вы можете выбирать поля из одной таблицы или из нескольких соединенных источников.

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

  • 📋 Всегда явно указывайте псевдонимы для полей, если их имена содержат спецсимволы или совпадают с зарезервированными словами.
  • 🔍 Используйте звездочку * осторожно: она выбирает все поля, но может замедлить работу при большом количестве колонок.
  • ⚙️ Группируйте поля логически: сначала ключевые поля, затем измерительные и ресурсные.

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

☑️ Проверка структуры выборки

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

Особое внимание стоит уделить полям типа ХранилищеЗначения. Их выборка без необходимости может существенно увеличить объем передаваемых данных и нагрузку на память клиента.

Фильтрация данных через оператор В

Оператор В является основным способом использования перечисления значений для отбора записей. Он позволяет передать список констант или параметров, по которым система будет искать совпадения. Это наиболее эффективный способ фильтрации по дискретному набору значений.

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

ВЫБРАТЬ

Номенклатура.Ссылка,

Номенклатура.Наименование

ИЗ

Справочник.Номенклатура КАК Номенклатура

ГДЕ

Номенклатура.ВидНоменклатуры В (ЗНАЧЕНИЕ(Справочник.ВидыНоменклатуры.Товар), ЗНАЧЕНИЕ(Справочник.ВидыНоменклатуры.Услуга))

Важно отметить, что количество элементов в перечислении не ограничено жестко, но слишком длинные списки (сотни элементов) могут ухудшить читаемость кода. В таких случаях лучше использовать временные таблицы.

Оптимизация длинных списков

Если список значений формируется динамически и содержит более 50 элементов, рассмотрите вариант загрузки их во временную таблицу и соединения по ней. Это часто работает быстрее, чем огромный список в операторе В.

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

Работа с типами данных и константами

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

Для указания конкретных элементов справочников или перечислений в тексте запроса используется функция ЗНАЧЕНИЕ(). Она сообщает компилятору, что внутри скобок находится не просто текст, а ссылка на объект метаданных.

Тип поля Пример значения в запросе Особенности
СправочникСсылка ЗНАЧЕНИЕ(Справочник.Контрагенты.Покупатель) Требует полного пути к элементу
ПеречислениеСсылка ЗНАЧЕНИЕ(Перечисление.СтатусыДокумента.Проведен) Частый случай фильтрации документов
Число 100, 200, 305.5 Записывается напрямую без кавычек
Строка "Товар А", "Товар Б" Обязательны кавычки, регистр зависит от БД

Игнорирование функции ЗНАЧЕНИЕ приведет к тому, что запрос попытается найти строку с текстом "Справочник.Контрагенты..", что неизбежно даст пустой результат. Это классическая ошибка новичков.

💡

Функция ЗНАЧЕНИЕ() обязательна для любых ссылок на объекты метаданных внутри текста запроса, иначе сравнение типов не пройдет.

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

Использование временных таблиц для списков

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

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

⚠️ Внимание: Временные таблицы создаются в памяти или во временном хранилище СУБД. Убедитесь, что у пользователя есть права на создание временных таблиц, иначе выполнение запроса прервется ошибкой прав доступа.

Преимущество такого подхода заключается в том, что оптимизатор запросов СУБД (например, MS SQL или PostgreSQL) может построить более оптимальный план выполнения, используя статистику по временной таблице.

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

📊 Как вы чаще всего передаете большие списки в запрос?
Через параметр СписокЗначений
Через временную таблицу
Прямым перечислением в коде
Через внешний файл

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

Типичные ошибки и отладка

Даже опытные разработчики допускают ошибки при работе с перечислениями. Самая распространенная проблема — синтаксическая ошибка из-за лишней запятой в конце списка или отсутствия закрывающей скобки. Конструктор запросов обычно подсвечивает такие места, но при ручном написании кода нужно быть внимательным.

Еще одна сложность возникает при использовании NULL (или ЕСТЬNULL) в сочетании с перечислением. Оператор В не обрабатывает пустые значения автоматически. Если в списке есть неопределенные значения, их нужно обрабатывать отдельно.

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

⚠️ Внимание: Интерфейс и возможности панели отладки могут различаться в разных версиях платформы 1С и режимах предприятия. Сверяйте доступные инструменты в вашей конкретной конфигурации.

Если запрос выполняется медленно, проверьте, используется ли индекс по полю, которое участвует в перечислении. Иногда явное указание индекса через директивы компиляции помогает ускорить выборку.

Часто задаваемые вопросы (FAQ)

Можно ли использовать перечисление в операторе ПОДОБНО?

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

Что делать, если список значений пуст?

Если перечисление в операторе В окажется пустым (например, параметр не заполнен), запрос вернет пустую таблицу результатов. Чтобы избежать этого, программно проверяйте заполненность списка перед выполнением запроса или используйте условие ЕСТЬNULL в комбинации с параметрами.

Как передать список из формы в запрос?

Используйте параметр запроса с типом СписокЗначений. В коде 1С создайте объект СписокЗначений, заполните его и передайте в метод Выполнить объекта запроса как значение параметра. В тексте запроса ссылку на параметр пишите как &ИмяПараметра.

Влияет ли порядок элементов в перечислении на скорость?

В большинстве современных СУБД порядок элементов в операторе IN (аналог В) не влияет на скорость выполнения, так как оптимизатор сам строит план поиска. Однако для читаемости кода рекомендуется сортировать списки или группировать их логически.

Можно ли использовать перечисление в предложении СГРУППИРОВАТЬ ПО?

Нет, в предложении СГРУППИРОВАТЬ ПО перечисляются поля, по которым производится агрегация. Синтаксически это тоже список через запятую, но смысловая нагрузка иная. Здесь нельзя указывать константы или значения, только имена полей из секции ВЫБРАТЬ.