Язык запросов в 1С:Предприятие — это мощный инструмент для извлечения и обработки данных, который используется как в конфигурациях для бухгалтеров, так и в разработке сложных отчетов. Однако многие пользователи сталкиваются с трудностями при попытке сформулировать запрос так, чтобы он возвращал именно те данные, которые нужны. Часто проблема кроется не в синтаксисе, а в логике построения запроса: как правильно выразить условие отбора, соединить таблицы или сгруппировать результаты.
В этой статье мы разберем ключевые приемы составления запросов в 1С, которые помогут избежать типичных ошибок. Вы узнаете, как переводить бизнес-требования в SQL-подобный синтаксис 1С, работать с вложенными запросами, использовать операторы СОЕДИНЕНИЕ, ГДЕ и ГРУППИРОВКА, а также оптимизировать производительность. Особое внимание уделим нюансам, которые не очевидны для новичков, но критичны для корректной работы системы.
Основы синтаксиса: как строится запрос в 1С
Язык запросов 1С внешне напоминает SQL, но имеет свои особенности. Базовая структура запроса включает обязательные секции ВЫБРАТЬ (аналог SELECT) и ИЗ (аналог FROM), а также необязательные — ГДЕ, ГРУППИРОВКА, УПОРЯДОЧИТЬ ПО и другие. Например, простейший запрос для выборки всех документов "ПоступлениеТоваров" выглядит так:
ВЫБРАТЬ
ПоступлениеТоваров.Ссылка КАК Ссылка,
ПоступлениеТоваров.Дата КАК Дата
ИЗ
Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
Важно понимать, что в 1С имена таблиц и полей чувствительны к регистру, а псевдонимы (после КАК) обязательны, если имя поля совпадает с ключевым словом языка. Например, поле Тип нужно переименовывать, так как Тип — это зарезервированное слово.
- 📌 Обязательные секции:
ВЫБРАТЬиИЗ— без них запрос не выполнится. - 🔄 Псевдонимы: используйте
КАК, чтобы избежать конфликтов с ключевыми словами. - 📝 Регистр: 1С различает
Датаидата— это разные поля! - 🚫 Запрещенные символы: в именах полей нельзя использовать пробелы, дефисы или специальные символы без кавычек.
Как выразить условия отбора: оператор ГДЕ
Секция ГДЕ позволяет фильтровать данные по заданным критериям. Здесь можно использовать стандартные операторы сравнения (=, >, <), логические операторы (И, ИЛИ, НЕ), а также специальные функции 1С, такие как ЗНАЧЕНИЕ или ТИП. Например, чтобы выбрать поступления за текущий месяц:
ВЫБРАТЬ
ПоступлениеТоваров.Ссылка КАК Ссылка
ИЗ
Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
ГДЕ
ПоступлениеТоваров.Дата >= НАЧАЛОМЕСЯЦА(&ТекущаяДата)
И ПоступлениеТоваров.Дата <= КОНЕЦМЕСЯЦА(&ТекущаяДата)
Особое внимание уделите работе с параметрами. В 1С параметры запроса обозначаются знаком & (например, &ТекущаяДата). Их значения передаются извне при выполнении запроса. Если параметр не передан, запрос завершится ошибкой.
⚠️ Внимание: При сравнении дат используйте функцииНАЧАЛОДНЯ(),КОНЕЦДНЯ()и аналогичные, чтобы избежать проблем с временем. Например, условиеДата = &ТекущаяДатаможет не сработать, если в полеДатахранится время.
| Оператор | Пример использования | Аналог в SQL |
|---|---|---|
= |
ГДЕ Склад = &ВыбранныйСклад |
WHERE |
В() |
ГДЕ Контрагент В (&СписокКонтрагентов) |
IN |
МЕЖДУ |
ГДЕ Сумма МЕЖДУ 1000 И 5000 |
BETWEEN |
ПОДОБНО |
ГДЕ Наименование ПОДОБНО "%тест%" |
LIKE |
Соединение таблиц: СОЕДИНЕНИЕ, ЛЕВОЕ СОЕДИНЕНИЕ и другие типы
В реальных задачах данные часто распределены по нескольким таблицам (например, документы и их табличные части). Для их объединения используются операторы соединения. В 1С поддерживаются следующие типы:
- 🔗
СОЕДИНЕНИЕ(аналогINNER JOIN) — возвращает только совпадающие записи. - 🔲
ЛЕВОЕ СОЕДИНЕНИЕ(аналогLEFT JOIN) — возвращает все записи из левой таблицы и совпадающие из правой. - 🔳
ПОЛНОЕ СОЕДИНЕНИЕ(аналогFULL JOIN) — возвращает все записи из обеих таблиц. - ➕
ПЕРЕКРЕСТНОЕ СОЕДИНЕНИЕ(аналогCROSS JOIN) — возвращает декартово произведение таблиц.
Пример запроса с ЛЕВЫМ СОЕДИНЕНИЕМ, который выбирает все поступления и их строки (даже если строки отсутствуют):
ВЫБРАТЬ
ПоступлениеТоваров.Ссылка КАК Документ,
ПоступлениеТоваровУслуг.Номенклатура КАК Номенклатура,
ПоступлениеТоваровУслуг.Количество КАК Количество
ИЗ
Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровУслуг
ПО ПоступлениеТоваров.Ссылка = ПоступлениеТоваровУслуг.Ссылка
⚠️ Внимание: При соединении таблиц с большим количеством записей ПОЛНОЕ СОЕДИНЕНИЕ может привести к перегрузке сервера. Используйте его только при крайней необходимости.
Убедиться, что поля для соединения имеют одинаковый тип данных|
Проверить индексы на полях соединения для ускорения запроса|
Ограничить выборку условием ГДЕ, если не нужны все записи|
Использовать ЛЕВОЕ СОЕДИНЕНИЕ вместо ПОЛНОГО, если возможны NULL-значения-->
Агрегация данных: ГРУППИРОВКА, СУММА, КОЛИЧЕСТВО
Для анализа данных часто требуется не просто выборка, а группировка с расчетом итогов. В 1С это реализуется с помощью секции ГРУППИРОВКА и агрегатных функций:
- 📊
СУММА()— суммирует значения. - 🔢
КОЛИЧЕСТВО()— считает количество строк (включая NULL). - ⚖️
МАКСИМУМ()/МИНИМУМ()— находит крайние значения. - ✅
КОЛИЧЕСТВО РАЗЛИЧНЫХ()— считает уникальные значения.
Пример запроса, который группирует поступления по складам и рассчитывает итоговые суммы:
ВЫБРАТЬ
ПоступлениеТоваров.Склад КАК Склад,
СУММА(ПоступлениеТоваровУслуг.Сумма) КАК ИтоговаяСумма,
КОЛИЧЕСТВО(ПоступлениеТоваровУслуг.Ссылка) КАК КоличествоСтрок
ИЗ
Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровУслуг
ПО ПоступлениеТоваров.Ссылка = ПоступлениеТоваровУслуг.Ссылка
ГДЕ
ПоступлениеТоваров.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
СГРУППИРОВАТЬ ПО
ПоступлениеТоваров.Склад
Критическая ошибка новичков: попытка выбрать поле, не включенное в ГРУППИРОВКА. В SQL это приведет к ошибке, а в 1С запрос может выполниться, но вернуть некорректные данные.
Вложенные запросы и временные таблицы
Сложные отчеты часто требуют промежуточных расчетов. В 1С для этого используются вложенные запросы (подзапросы) и временные таблицы. Вложенный запрос размещается в секциях ВЫБРАТЬ, ГДЕ или ИЗ и заключается в круглые скобки.
Пример: выборка номенклатуры, которая не продавалась в текущем месяце:
ВЫБРАТЬ
Номенклатура.Наименование КАК Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
НЕ Номенклатура.Ссылка В (
ВЫБРАТЬ РАЗЛИЧНЫЕ
РеализацияТоваровУслуг.Номенклатура
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслуг
ГДЕ
РеализацияТоваровУслуг.Ссылка.Дата >= НАЧАЛОМЕСЯЦА(&ТекущаяДата)
)
Временные таблицы создаются с помощью оператора ПОМЕСТИТЬ и позволяют сохранять промежуточные результаты для дальнейшего использования. Это особенно полезно для многоступенчатых расчетов:
// Создаем временную таблицу с остатками
ПОМЕСТИТЬ ВТ_Остатки
ВЫБРАТЬ
РегистрНакопления.ОстаткиТоваров.Номенклатура КАК Номенклатура,
СУММА(РегистрНакопления.ОстаткиТоваров.КоличествоОстаток) КАК Остаток
ИЗ
РегистрНакопления.ОстаткиТоваров КАК РегистрНакопления.ОстаткиТоваров
ГДЕ
РегистрНакопления.ОстаткиТоваров.Период = &ТекущаяДата
СГРУППИРОВАТЬ ПО
РегистрНакопления.ОстаткиТоваров.Номенклатура
// Используем временную таблицу в основном запросе
ВЫБРАТЬ
ВТ_Остатки.Номенклатура КАК Номенклатура,
ВТ_Остатки.Остаток КАК Остаток
ИЗ
ВТ_Остатки КАК ВТ_Остатки
ГДЕ
ВТ_Остатки.Остаток > 0
Если вложенный запрос возвращает большое количество данных, рассмотрите возможность использования временных таблиц — это ускорит выполнение основного запроса.
Оптимизация запросов: индексы, планы выполнения и типичные ошибки
Медленные запросы — одна из самых распространенных проблем в 1С. Основные причины:
- 🐢 Отсутствие индексов на полях, используемых в условиях
ГДЕилиСОЕДИНЕНИЕ. - 🔄 Избыточные соединения — например, соединение таблиц, когда достаточно подзапроса.
- 📄 Выборка всех полей (
ВЫБРАТЬ *) вместо явного перечисления нужных. - 🔍 Сложные условия в
ГДЕ, которые не могут использовать индексы (например, функции над полями).
Для анализа производительности запроса используйте план выполнения. В конфигураторе 1С его можно получить через меню Отладка → Показать план запроса. План покажет, какие операции наиболее затратные и где можно оптимизировать.
⚠️ Внимание: Если в условииГДЕиспользуется функция над полем (например,ЛЕВ(Наименование, 3) = "АБВ"), индекс по этому полю использоваться не будет. Перепишите условие так, чтобы функция применялась к параметру:Наименование ПОДОБНО "АБВ%".
Как включить отображение плана запроса в пользовательском режиме?
В пользовательском режиме план запроса недоступен по умолчанию. Чтобы его увидеть, нужно:
1. Перейти в конфигуратор.
2. Включить режим "Отладка" (меню "Сервис → Параметры → Запуск 1С:Предприятия").
3. Запустить 1С:Предприятие в режиме отладки и выполнить запрос через отладчик.
Практические примеры: типичные задачи и их решения
Рассмотрим несколько реальных кейсов, с которыми сталкиваются пользователи 1С.
Задача 1: Выбрать клиентов, которые не делали заказы в последние 3 месяца.
ВЫБРАТЬ
Контрагенты.Наименование КАК Клиент
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
НЕ Контрагенты.Ссылка В (
ВЫБРАТЬ РАЗЛИЧНЫЕ
ЗаказыКлиентов.Контрагент
ИЗ
Документ.ЗаказКлиента КАК ЗаказыКлиентов
ГДЕ
ЗаказыКлиентов.Дата >= ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -3)
)
Задача 2: Получить топ-10 самых продаваемых товаров за год.
ВЫБРАТЬ ПЕРВЫЕ 10
РеализацияТоваровУслуг.Номенклатура КАК Номенклатура,
СУММА(РеализацияТоваровУслуг.Количество) КАК Продано
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслуг
ГДЕ
РеализацияТоваровУслуг.Ссылка.Дата >= НАЧАЛОГОДА(&ТекущаяДата)
СГРУППИРОВАТЬ ПО
РеализацияТоваровУслуг.Номенклатура
УПОРЯДОЧИТЬ ПО
Продано УБЫВ
Задача 3: Найти документы с расхождениями между суммой строк и итоговой суммой.
ВЫБРАТЬ
ПоступлениеТоваров.Ссылка КАК Документ,
ПоступлениеТоваров.СуммаДокумента КАК СуммаДокумента,
СУММА(ПоступлениеТоваровУслуг.Сумма) КАК СуммаСтрок
ИЗ
Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровУслуг
ПО ПоступлениеТоваров.Ссылка = ПоступлениеТоваровУслуг.Ссылка
СГРУППИРОВАТЬ ПО
ПоступлениеТоваров.Ссылка,
ПоступлениеТоваров.СуммаДокумента
ИМЕЮЩИЕ
ПоступлениеТоваров.СуммаДокумента <> СУММА(ПоступлениеТоваровУслуг.Сумма)
Для сложных отчетов всегда разбивайте задачу на части: сначала получите промежуточные данные во временные таблицы, а затем объедините их в finale запросе.
FAQ: Ответы на частые вопросы по языку запросов 1С
Как в запросе 1С получить текущую дату без параметров?
Используйте функцию ТЕКУЩАЯДАТА(). Например:
ВЫБРАТЬ ТЕКУЩАЯДАТА() КАК Сегодня
Она возвращает дату и время на момент выполнения запроса. Если нужна только дата без времени, оберните в НАЧАЛОДНЯ().
Почему запрос с ГРУППИРОВКА возвращает неверные итоги?
Наиболее вероятная причина — в выборке есть поля, не включенные в ГРУППИРОВКА. В 1С (в отличие от SQL) такой запрос не выдаст ошибку, но данные будут некорректны. Все поля в ВЫБРАТЬ, кроме агрегатных функций, должны присутствовать в ГРУППИРОВАТЬ ПО.
Как в запросе проверить, принадлежит ли значение списку?
Используйте оператор В(). Например:
ГДЕ Номенклатура.Ссылка В (&СписокТоваров)
Где &СписокТоваров — параметр типа Массив или СписокЗначений, переданный в запрос.
Можно ли в одном запросе обновлять данные?
Нет, язык запросов 1С предназначен только для выборки данных. Для модификации используйте объекты конфигурации (например, ДокументОбъект.Записать()) или специальные механизмы, такие как регистры накопления.
Как ускорить запрос, который долго выполняется?
Попробуйте следующие шаги:
- Проверьте наличие индексов на полях, используемых в
ГДЕиСОЕДИНЕНИЕ. - Замените
ПОЛНОЕ СОЕДИНЕНИЕнаЛЕВОЕ, если возможны NULL-значения. - Разбейте сложный запрос на несколько простых с использованием временных таблиц.
- Исключите ненужные поля из выборки (
ВЫБРАТЬ *).
Если это не помогло, проанализируйте план выполнения запроса.