Язык запросов 1С:Предприятия: название, синтаксис и приёмы работы
Содержание
Язык запросов в 1С так и называется — «язык запросов 1С:Предприятия». Отдельного торгового имени у него нет. В документации платформы он идёт разделом «Язык запросов», а в разговоре программисты говорят «запросы 1С» или полушутя «1С-SQL».
По сути это диалект SQL, урезанный до чтения данных и расширенный под объекты 1С: справочники, документы, регистры. Писать на нём можно по-русски (ВЫБРАТЬ, ИЗ, ГДЕ) и по-английски (SELECT, FROM, WHERE). Платформа сама переводит текст запроса в SQL той СУБД, на которой работает база.
Как официально называется язык запросов 1С
Полное название — язык запросов системы «1С:Предприятие 8». Платформа 8.3 использует ту же основу, что и 8.2, с добавлением новых функций от релиза к релизу.
В 1С 7.7 тоже был язык запросов, но совсем другой: без ВЫБРАТЬ и ИЗ, со своими конструкциями для периодов и группировок. SQL-подобный синтаксис появился только в восьмой версии платформы. Поэтому старые примеры из форумов про 7.7 к 8.3 не подходят.
Встречаются и другие названия. Все они про одно и то же:
- 📘 «Язык запросов 1С:Предприятия» — формулировка документации и учебных курсов.
- 💬 «Запросы 1С», «1С-запросы» — разговорный вариант.
- 😏 «1С-SQL» — неофициальное прозвище, подчёркивает родство с SQL.
- 🧩 «Язык СКД» — неточно. Система компоновки данных использует тот же язык запросов, только с дополнительными конструкциями в фигурных скобках.
Если в вакансии пишут «знание языка запросов 1С», имеют в виду именно его: умение писать выборки из регистров, работать с виртуальными таблицами и временными таблицами, а не знание T-SQL.
Отдельно стоит не путать язык запросов со встроенным языком 1С. Встроенный язык — это код модулей: процедуры, циклы, условия. Язык запросов живёт внутри встроенного: текст запроса — это строка, которую передают объекту Запрос.
Синтаксис языка запросов 1С: из чего состоит запрос
Запрос строится из предложений в строгом порядке. Ключевые слова не чувствительны к регистру, но принято писать их заглавными — так текст читается легче.
Базовая выборка
ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 100
Товары.Ссылка КАК Номенклатура,
Товары.Артикул КАК Артикул
ИЗ
Справочник.Номенклатура КАК Товары
ГДЕ
НЕ Товары.ПометкаУдаления
И Товары.Наименование ПОДОБНО &Шаблон
УПОРЯДОЧИТЬ ПО
Товары.Наименование
Что здесь происходит:
ВЫБРАТЬ— список полей.РАЗЛИЧНЫЕубирает повторы,ПЕРВЫЕ 100ограничивает число строк.ИЗ— источник. Таблица называется по типу объекта:Справочник.,Документ.,РегистрНакопления.,РегистрСведений..КАК— псевдоним поля или таблицы.ГДЕ— условие отбора.&Шаблон— параметр, его значение задают из кода.УПОРЯДОЧИТЬ ПО— сортировка.
Группировка и итоги
ВЫБРАТЬ
Продажи.Контрагент,
СУММА(Продажи.Сумма) КАК Сумма
ИЗ
Документ.РеализацияТоваровУслуг КАК Продажи
ГДЕ
Продажи.Проведен
И Продажи.Дата МЕЖДУ &Начало И &Конец
СГРУППИРОВАТЬ ПО
Продажи.Контрагент
ИМЕЮЩИЕ
СУММА(Продажи.Сумма) > 100000
Агрегатные функции те же, что в SQL: СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ. Предложение ИТОГИ ПО добавляет к результату строки промежуточных итогов — в обычном SQL такого нет.
Соединения и объединения
- 🔗
ЛЕВОЕ СОЕДИНЕНИЕ,ПРАВОЕ СОЕДИНЕНИЕ,ВНУТРЕННЕЕ СОЕДИНЕНИЕ,ПОЛНОЕ СОЕДИНЕНИЕ— с условиемПО. - ➕
ОБЪЕДИНИТЬиОБЪЕДИНИТЬ ВСЕ— склейка результатов двух выборок. Второй вариант не убирает дубли и работает быстрее.
Полезные функции и операторы
| Конструкция | Для чего |
|---|---|
ЕСТЬNULL(Поле, 0) | Заменить NULL после левого соединения |
ВЫБОР КОГДА … ТОГДА … ИНАЧЕ … КОНЕЦ | Условное значение поля |
ЗНАЧЕНИЕ(Перечисление.Имя.Значение) | Сослаться на предопределённое значение |
ВЫРАЗИТЬ(Поле КАК Тип) | Привести тип, в том числе составной |
ПРЕДСТАВЛЕНИЕ(Поле) | Получить текстовое представление ссылки |
НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА | Округлить дату до дня, месяца, года |
В ИЕРАРХИИ | Отбор по группе справочника с подчинёнными |
ССЫЛКА | Проверить тип ссылки в составном поле |
Пакеты и временные таблицы
Несколько запросов можно записать одним текстом через точку с запятой — это пакетный запрос. Промежуточный результат кладут во временную таблицу через ПОМЕСТИТЬ, а в конце освобождают через УНИЧТОЖИТЬ. Для больших временных таблиц добавляют ИНДЕКСИРОВАТЬ ПО.
Где в 1С:Предприятии работает язык запросов
Запросы в 1С — не экзотика для программистов. Почти всё, что пользователь видит в списках и отчётах, получено запросом.
- 💻 Объект
Запросво встроенном языке. Основной способ получить данные в коде: проверка остатков при проведении, заполнение табличной части, обработки. - 📊 Система компоновки данных (СКД). Отчёты в типовых конфигурациях строятся на СКД, а её набор данных — это запрос.
- 📋 Динамические списки. Формы списков документов и справочников могут работать на произвольном запросе.
- 🔐 Ограничение доступа на уровне записей (RLS). Условия в ролях пишутся на языке запросов.
- 🛠 Консоль запросов. Внешняя обработка, в которой запрос пишут и выполняют прямо в пользовательском режиме. Ею пользуются и программисты, и опытные бухгалтеры для разовых выборок.
Вот как выглядит типичный запрос из кода. Имена регистра и полей условные — в вашей конфигурации они свои.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура КАК Номенклатура,
| Остатки.КоличествоОстаток КАК Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, Склад = &Склад) КАК Остатки
|ГДЕ
| Остатки.КоличествоОстаток > 0";
Запрос.УстановитьПараметр("Дата", ТекущаяДатаСеанса());
Запрос.УстановитьПараметр("Склад", Склад);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(СтрШаблон("%1: %2", Выборка.Номенклатура, Выборка.Количество));
КонецЦикла;
Отбор по складу стоит в параметрах виртуальной таблицы Остатки(...), а не в ГДЕ. Это не стилистика: так платформа считает остатки только по нужному складу.
Чем язык запросов 1С отличается от SQL
Тот, кто знает SQL, прочитает запрос 1С сразу. Но писать как в SQL не получится: у языка другая модель данных.
| Что | SQL | Язык запросов 1С |
|---|---|---|
| Изменение данных | INSERT, UPDATE, DELETE | Нет, только чтение. Запись — через объекты встроенного языка |
| Имена таблиц | Физические таблицы СУБД | Объекты метаданных: Документ.Счет, Справочник.Контрагенты |
| Связи | Явные JOIN | Есть ещё разыменование через точку: Документ.Контрагент.ИНН |
| Остатки и обороты | Считаете сами | Виртуальные таблицы Остатки, Обороты, СрезПоследних |
| Итоги | Через ROLLUP и аналоги | Предложение ИТОГИ ПО |
| Язык ключевых слов | Английский | Русский или английский |
| СУБД | Конкретная | Одинаковый текст для файловой базы, MS SQL Server, PostgreSQL |
| Права | На уровне СУБД | Учитываются роли и RLS 1С |
Разыменование через точку
Самое заметное отличие. Запись Реализация.Контрагент.ГоловнойКонтрагент.ИНН в SQL потребовала бы двух соединений. В 1С платформа строит их сама.
Удобно, но коварно: каждая точка — это скрытое соединение. Если поле составного типа (может ссылаться на несколько видов документов), платформа соединит его со всеми возможными таблицами.
Виртуальные таблицы
У регистров накопления есть таблицы Остатки, Обороты, ОстаткиИОбороты. У регистров сведений — СрезПоследних и СрезПервых. У регистров бухгалтерии — ещё и обороты между счетами. Это главный инструмент учётных запросов, и в SQL его аналога нет.
Почему нельзя писать прямые SQL-запросы
Структура таблиц в СУБД служебная: имена вида _Document123, _Fld456. Они меняются при изменении конфигурации. Прямые запросы к базе в обход платформы игнорируют роли и управляемые блокировки, а сама такая работа не поддерживается и не рекомендуется разработчиком платформы. Поэтому всё делают через язык запросов.
Как изучить язык запросов 1С с нуля
Путь, который работает для большинства начинающих, выглядит так.
- Поставьте учебную версию платформы с демонстрационной базой. Учебная версия бесплатна и позволяет открыть Конфигуратор .
- Освойте конструктор запроса. В модуле Конфигуратора вызовите контекстное меню и выберите «Конструктор запроса». Накликайте выборку и посмотрите, какой текст он собрал.
- Пишите в консоли запросов. Результат видно сразу, не нужно писать код вывода.
- Разберите виртуальные таблицы регистров. Возьмите регистр остатков и получите остаток на дату, обороты за месяц, остатки и обороты вместе.
- Перейдите к пакетам и временным таблицам. Перепишите запрос с вложенным запросом через
ПОМЕСТИТЬ. - Читайте запросы типовых конфигураций. Модули проведения документов в БП 3.0 и УТ 11 — хороший учебник на реальных задачах.
Задачи для практики
Теорию лучше сразу закреплять на демобазе. Вот пять задач по возрастанию сложности:
- 🟢 Вывести все элементы справочника номенклатуры из одной группы с подчинёнными (
В ИЕРАРХИИ). - 🟢 Посчитать сумму продаж по каждому контрагенту за квартал (
СГРУППИРОВАТЬ ПО). - 🟡 Получить остаток товаров на складе на начало месяца (виртуальная таблица
Остатки). - 🟡 Показать актуальные цены номенклатуры на дату (
СрезПоследнихрегистра цен). - 🔴 Найти документы, у которых сумма шапки не равна сумме строк табличной части (временные таблицы и соединение).
Если последнюю задачу вы решаете без подсказок, базу языка запросов вы освоили.
Сертификат «1С:Специалист» по платформе включает задачи на запросы. Готовиться к нему по учебникам издательства 1С — хороший способ закрыть пробелы.
Оптимизация запросов в 1С: что ускоряет на практике
Медленный отчёт или долгое проведение почти всегда упирается в запрос. Вот приёмы, которые дают эффект.
Параметры виртуальных таблиц вместо ГДЕ
Условие в ГДЕ применяется после того, как виртуальная таблица уже посчитана по всем данным. Условие в скобках Остатки(&Дата, Склад = &Склад) ограничивает расчёт сразу. На больших регистрах разница бывает в десятки раз.
Без запросов в цикле
Классика: обойти табличную часть и для каждой строки выполнить запрос. Сто строк — сто обращений к базе. Правильно собрать все значения в параметр-массив и выполнить один запрос с условием В (&Список). Или передать таблицу значений во временную таблицу.
Осторожно с разыменованием
- 🎯 Для составных полей используйте
ВЫРАЗИТЬ(Регистратор КАК Документ.Реализация), чтобы платформа не соединяла все виды документов. - 🧷 Не тяните через точку длинные цепочки в условиях соединения.
- 📦 Если реквизит нужен в нескольких местах, получите его один раз во временную таблицу.
Временные таблицы вместо вложенных запросов
Соединение с вложенным запросом СУБД нередко выполняет неоптимально. Положите подзапрос во временную таблицу, при большом объёме проиндексируйте по полю соединения — план станет предсказуемым.
Остальное
- ⛔ Избегайте
ИЛИв условиях соединения — оно мешает использовать индексы. Часто помогает разбить запрос на два черезОБЪЕДИНИТЬ ВСЕ. - 🔢 Не выбирайте лишние поля, особенно
ПРЕДСТАВЛЕНИЕссылок в больших выборках. - 📈 Где искать узкие места: замер производительности в Конфигураторе при отладке и технологический журнал на сервере.
Частые ошибки в запросах и как их избежать
Ещё две ошибки, которые не дают сообщений, но портят результат:
- 🧱 Текст запроса склеен из строк с данными. Значения подставляют конкатенацией вместо параметров. Запрос ломается на кавычках в наименованиях, а платформа не может переиспользовать план. Всегда передавайте значения через
УстановитьПараметр. - 📅 Граница периода по дате без времени. Условие
Дата <= &Конец, где&Конец— 31.03 00:00:00, теряет весь последний день. ПередавайтеКонецДня(Дата)или используйтеКОНЕЦПЕРИОДА(&Конец, ДЕНЬ).