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

Основная структура запроса строится вокруг ключевого слова ВЫБРАТЬ, за которым следует список полей, и ключевого слова ИЗ, указывающего на источник данных. Правильное написание запроса гарантирует не только получение нужной информации, но и оптимальную производительность системы при больших объемах данных. Ошибки в синтаксисе часто приводят к тому, что код просто не компилируется или возвращает пустой результат.

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

Базовая структура и синтаксис запроса

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

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

💡

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

Простой пример запроса выглядит следующим образом:

ВЫБРАТЬ

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

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

ИЗ

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

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

⚠️ Внимание: В языке запросов 1С нельзя использовать символ "*" для выбора всех полей. Вы должны явно перечислить каждое поле, которое планируете использовать в результате выборки.

Фильтрация данных с помощью оператора ГДЕ

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

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

📊 Какой тип фильтрации вы используете чаще всего?
Точное совпадение
По диапазону дат
По вхождению строки
Использование параметров

Рассмотрим пример фильтрации по дате и конкретному значению поля:

ВЫБРАТЬ

РеализацияТоваровУслуг.Номер,

РеализацияТоваровУслуг.Дата

ИЗ

Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

ГДЕ

РеализацияТоваровУслуг.Дата МЕЖДУ &НачалоПериода И &КонецПериода

И РеализацияТоваровУслуг.Проведен = ИСТИНА

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

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

Соединение таблиц и оператор СОЕДИНЕНИЕ

Часто данные, необходимые для отчета, расположены в разных таблицах или регистрах. Для их объединения в одном результирующем наборе используется оператор СОЕДИНЕНИЕ. В 1С поддерживаются различные виды соединений: ЛЕВОЕ, ВНУТРЕННЕЕ, ПРАВОЕ и ПОЛНОЕ.

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

☑️ Проверка соединения таблиц

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

Пример использования левого соединения для получения данных о контрагентах и их договорах:

ВЫБРАТЬ

Контрагенты.Наименование,

Договоры.Номер

ИЗ

Справочник.Контрагенты КАК Контрагенты

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ДоговорыКонтрагентов КАК Договоры

ПО Контрагенты.Ссылка = Договоры.Контрагент

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

Тип соединения Описание Когда использовать
ВНУТРЕННЕЕ Только совпадающие записи Когда нужны только связанные данные
ЛЕВОЕ Все из левой + совпадения из правой Для отображения списка с доп. информацией
ПОЛНОЕ Все записи из обеих таблиц Для полного сравнения двух списков

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

Группировка и агрегатные функции

Для получения сводных данных, таких как суммы, количества или средние значения, используются агрегатные функции. К ним относятся СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ и СРЕДНЕЕ. Применение этих функций требует обязательного использования оператора СГРУППИРОВАТЬ ПО.

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

Особенности работы с NULL в группировке

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

Рассмотрим пример подсчета суммы продаж по каждому менеджеру:

ВЫБРАТЬ

Продажи.Менеджер,

СУММА(Продажи.Сумма) КАК ОбщаяСумма

ИЗ

Документ.РеализацияТоваровУслуг КАК Продажи

СГРУППИРОВАТЬ ПО

Продажи.Менеджер

В этом запросе поле Менеджер вынесено в секцию группировки, а поле Сумма агрегировано функцией СУММА. Результатом будет список менеджеров с общей суммой проведенных ими документов. Если добавить в выборку поле "Контрагент" без группировки по нему, запрос станет некорректным.

⚠️ Внимание: Агрегатные функции игнорируют значения NULL. Если в поле стоят пустые значения, они не будут учтены в расчете суммы или среднего, но будут учтены в функции КОЛИЧЕСТВО(*).

Дополнительная фильтрация сгруппированных данных осуществляется с помощью оператора ИМЕЮЩИЕ. Он работает аналогично ГДЕ, но применяется уже после выполнения группировки и агрегации. Это позволяет отбирать только те группы, которые удовлетворяют определенным условиям, например, сумму продаж больше определенной величины.

Объединение результатов и оператор ОБЪЕДИНИТЬ

Иногда возникает необходимость объединить результаты нескольких независимых запросов в одну таблицу. Для этого служит оператор ОБЪЕДИНИТЬ. Он позволяет склеить вертикально два набора данных, при условии, что они имеют одинаковое количество полей и совместимые типы данных в соответствующих колонках.

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

💡

Оператор ОБЪЕДИНИТЬ выполняет вертикальное соединение таблиц, в отличие от СОЕДИНЕНИЕ, которое соединяет таблицы горизонтально по ключевым полям.

Пример объединения данных из двух разных регистров накопления:

ВЫБРАТЬ

Приход.Номенклатура,

Приход.Количество КАК Остаток

ИЗ

РегистрНакопления.ТоварыНаСкладах.Остатки КАК Приход

ГДЕ

Приход.Склад = &Склад1

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

Расход.Номенклатура,

-Расход.Количество КАК Остаток

ИЗ

РегистрНакопления.ТоварыНаСкладах.Остатки КАК Расход

ГДЕ

Расход.Склад = &Склад2

В данном примере мы получаем остатки с двух разных складов и объединяем их в один список. Обратите внимание на использование минуса во второй части запроса, что позволяет сразу получить сальдо при последующем суммировании. Типы данных поля "Номенклатура" и "Остаток" в обеих частях запроса должны совпадать.

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

Работа с временными таблицами

При построении сложных отчетов часто требуется промежуточное сохранение данных. Для этого в запросах 1С используются временные таблицы. Они создаются с помощью символа # в имени таблицы и существуют только в течение сеанса выполнения запроса или пакета запросов.

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

💡

Имена временных таблиц должны быть уникальными в рамках сеанса. Хорошей практикой является добавление префикса или уникального идентификатора к имени временной таблицы.

Синтаксис создания временной таблицы выглядит так:

ВЫБРАТЬ

Данные.Поле1,

Данные.Поле2

ПОМЕСТИТЬ ВременнаяТаблица

ИЗ

ИсточникДанных КАК Данные

ВЫБРАТЬ *

ИЗ

ВременнаяТаблица

Ключевое слово ПОМЕСТИТЬ указывает на то, что результат запроса должен быть сохранен во временную таблицу с указанным именем. Далее эту таблицу можно использовать как обычный источник данных в последующих запросах пакета. Удаление временной таблицы происходит автоматически при завершении сеанса или явном удалении.

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

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

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

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

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

📊 Что чаще всего тормозит ваши отчеты?
Сложные соединения
Отсутствие индексов
Большие выборки полей
Функции в условиях

Для оптимизации следует стремиться к тому, чтобы условия в секции ГДЕ были максимально простыми и задействовали индексируемые поля. Также рекомендуется использовать оператор ТОЛЬКО для справочников, если вам не нужны помеченные на удаление элементы, что уменьшает объем обрабатываемых данных.

Анализ плана выполнения запроса через консоль запросов или технологический журнал помогает выявить узкие места. Если вы видите операции "Table Scan" вместо "Index Seek" на больших таблицах, стоит пересмотреть структуру условий выборки или добавить необходимые индексы в конфигурацию.

Можно ли использовать подзапросы в 1С?

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

В чем разница между параметрами и переменными в запросе?

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

Как обработать пустой результат запроса?

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

Допустимы ли кириллические имена полей в запросе?

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

Что такое виртуальные таблицы в запросах?

Виртуальные таблицы — это специальные представления регистров, которые позволяют получать срезы данных (Остатки, Обороты) без написания сложных алгоритмов выборки. Они указываются в секции ИЗ после имени регистра через точку, например: РегистрНакопления.Товары.Остатки.