Разработка и Конфигурация · 12 мин
Как в 1С написать запрос: руководство для начинающих
Как написать запрос в 1С: синтаксис языка запросов, конструктор запроса, параметры, виртуальные таблицы, типичные ошибки и примеры кода для новичков.
Язык запросов 1С — основной инструмент получения данных из информационной базы. Он похож на SQL, но работает не с физическими таблицами базы, а с объектами конфигурации: справочниками, документами, регистрами. Чтобы написать рабочий запрос, достаточно понимать структуру конструкции ВЫБРАТЬ–ИЗ–ГДЕ и уметь пользоваться встроенным конструктором запросов.
Запросы применяются везде: в отчётах, обработках, модулях документов, при заполнении табличных частей. Ошибка в запросе редко ломает базу, но легко приводит к неверным цифрам в отчётах и медленной работе системы. Поэтому важно не только написать запрос, но и проверить результат на тестовых данных.
Ниже разобран полный цикл: от создания простейшего запроса в консоли до использования параметров, соединений таблиц и виртуальных таблиц регистров. Все примеры приведены на встроенном языке 1С и подходят для управляемых и обычных форм.
Что нужно знать о языке запросов 1С перед началом
Язык запросов 1С — декларативный: вы описываете, какие данные нужны, а платформа сама решает, как их извлечь. Запрос только читает данные; изменить что-то в базе через запрос нельзя, для записи используются объекты (СправочникОбъект, ДокументОбъект и т.д.).
Имена таблиц в запросе — это имена объектов метаданных: Справочник.Номенклатура, Документ.РеализацияТоваровУслуг, РегистрНакопления.ТоварыНаСкладах. Внутри запроса используются русские ключевые слова (ВЫБРАТЬ, ИЗ, ГДЕ, СГРУППИРОВАТЬ ПО), но допускаются и английские аналоги (SELECT, FROM, WHERE).
Поле со звёздочкой (ВЫБРАТЬ *) работает, но в рабочем коде его лучше избегать: запрос вытащит все поля таблицы, включая ненужные, что замедлит выполнение и увеличит трафик между сервером 1С и СУБД.
Как написать первый запрос: минимальный пример
Простейший запрос выбирает записи из справочника. В модуле он выглядит так:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Номенклатура,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Наименование);
КонецЦикла;
Разберём ключевые элементы. Псевдоним таблицы (КАК Номенклатура после ИЗ) позволяет коротко ссылаться на поля. Псевдонимы полей (КАК Наименование) определяют имена колонок в результате — по ним вы обращаетесь к данным в цикле выборки.
Метод Выполнить() отправляет запрос на исполнение, Выбрать() возвращает выборку для построчного обхода, а Выгрузить() — таблицу значений, которую удобно сортировать, сворачивать и выводить на форму. Для больших результатов предпочтительнее выборка — она не загружает всё в память сразу.
Как собрать запрос конструктором без ручного набора
Конструктор запроса избавляет от необходимости помнить синтаксис. Он вызывается из контекстного меню в модуле: правый клик внутри строки с текстом запроса → «Конструктор запроса». Если текста ещё нет, конструктор создаст заготовку.
Порядок работы в конструкторе: на закладке «Таблицы и поля» выберите источник (например, справочник Номенклатура), перенесите нужные поля в список выборки. На закладке «Условия» задайте отборы, на закладке «Группировка» — итоги, на закладке «Объединения/Псевдонимы» — имена полей результата. После нажатия «ОК» конструктор сформирует готовый текст.
Конструктор удобен и для изучения: соберите запрос мышкой, а потом посмотрите, какой текст он сгенерировал. Так быстрее запоминаются конструкции ЛЕВОЕ СОЕДИНЕНИЕ, СГРУППИРОВАТЬ ПО и обращения к виртуальным таблицам.
Как использовать параметры и отборы
Отбор данных задаётся секцией ГДЕ. Жёстко вписывать значения в текст запроса — плохая практика: при изменении условия придётся править строку, а конкатенация строк открывает путь к ошибкам с типами. Вместо этого используются параметры — имена с символом «&».
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Номенклатура КАК Номенклатура,
| СУММА(Товары.Количество) КАК Количество
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
| И Товары.Ссылка.Проведен
|СГРУППИРОВАТЬ ПО
| Товары.Номенклатура";
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДата()));
Параметры задаются строго через УстановитьПараметр() до вызова Выполнить(). Если параметр объявлен в тексте, но не установлен — платформа выдаст ошибку «Переменная не определена». В параметры можно передавать ссылки, даты, числа, строки, массивы и списки значений (для условия В) и даже пустые ссылки.
Для отбора по списку значений используйте оператор В: ГДЕ Номенклатура В (&СписокНоменклатуры), а в параметр передайте массив или список значений. Это работает быстрее, чем цепочка условий ИЛИ.
Как соединять таблицы и работать с виртуальными таблицами
Соединения нужны, когда данные лежат в разных объектах: например, документ и регистр, справочник и регистр сведений с ценами. Чаще всего используется ЛЕВОЕ СОЕДИНЕНИЕ — оно сохраняет все строки левой таблицы, даже если справа совпадений нет.
ВЫБРАТЬ
Номенклатура.Ссылка КАК Товар,
Остатки.КоличествоОстаток КАК Остаток
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки
ПО Номенклатура.Ссылка = Остатки.Номенклатура
Обратите внимание на синтаксис виртуальной таблицы Остатки(&Период, Склад = &Склад): первый параметр — период, на который считаются остатки, второй — условие отбора. Отбор внутри параметров виртуальной таблицы работает значительно быстрее, чем тот же отбор в секции ГДЕ, потому что платформа сначала сужает выборку, а потом соединяет.
Если при левом соединении совпадений не нашлось, поля правой таблицы вернут NULL. Для подстановки значения по умолчанию используйте ЕСТЬNULL: ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток. Без этого арифметика с NULL даст NULL и испортит итоги.
Как проверить результат запроса
Совпадает с числом записей, видимых в списке объекта при том же отборе
Строк больше — вероятно дублирование из-за соединения; меньше — лишнее условие в ГДЕ
Совпадают со штатным отчётом конфигурации по тем же данным
Расхождения — проверьте период виртуальной таблицы и отбор по проведённым документам
Заполнены или заменены через ЕСТЬNULL
NULL там, где ожидалось число или строка
Где отлаживать запрос: консоль запросов
Писать запрос вслепую в модуле и проверять его через Сообщить() — долгий путь. Стандартный инструмент разработчика — консоль запросов: внешняя обработка, которая позволяет вставить текст запроса, задать параметры и сразу увидеть результат в виде таблицы. Консоль входит в состав типовых инструментов разработчика и многих конфигураций, также доступна как отдельная обработка.
Типовой сценарий отладки: скопировать текст запроса из модуля в консоль, заполнить параметры теми же значениями, что и в коде, выполнить и проверить выборку. Если результат неверный — менять запрос в консоли до получения правильных данных и только потом переносить обратно в модуль.
Консоль показывает и реальные значения параметров, что помогает найти классическую ошибку: параметр передан с неправильным типом (например, строка вместо ссылки) и условие ГДЕ молча ничего не отбирает.
При переносе запроса из консоли в модуль не забывайте, что в коде текст — это строковый литерал: кавычки внутри текста удваиваются, а многострочный текст удобнее оформлять через вертикальную черту | в начале каждой строки.
Типичные ошибки и ограничения
Даже синтаксически верный запрос может работать плохо. Самая частая причина медленных запросов — обращение к полям через несколько точек и отбор по виртуальной таблице в секции ГДЕ вместо параметров. Вторая по частоте проблема — соединение по неиндексированным полям или по выражениям.
Запрос в цикле — отдельный антипаттерн: если вы выполняете запрос для каждой строки таблицы, замените его одним запросом с отбором по списку значений (В) и соединением с временной таблицей. Это сокращает число обращений к СУБД с тысяч до одного.
Часто задаваемые вопросы
Чем запрос отличается от обхода данных через методы объектов?
Запрос выбирает нужные данные одним обращением к СУБД и только читает их. Обход через объекты (например, Выбрать() у менеджера справочника) загружает каждый объект целиком в память. Для чтения и анализа данных запрос всегда предпочтительнее; объектный метод нужен только для изменения данных.
Как вывести результат запроса в табличный документ или на форму?
Для табличного документа результат выгружают методом Выгрузить() и построчно выводят через макет. Для формы таблицу значений помещают в реквизит формы типа «ТаблицаЗначений» — тогда она отобразится в связанном элементе «Таблица формы». Для сложных отчётов правильнее использовать СКД, где запрос ложится в основу набора данных.
Что такое временные таблицы и когда они нужны?
Временная таблица — промежуточный результат, помещённый в менеджер временных таблиц (конструкция ПОМЕСТИТЬ ИмяТаблицы). Она нужна, когда один и тот же отбор используется в нескольких частях пакетного запроса: вы один раз отбираете данные во временную таблицу, а затем соединяетесь с ней. Это упрощает текст и часто ускоряет выполнение.
Почему запрос возвращает пустой результат, хотя данные в базе есть?
Чаще всего причина в параметрах: передан неверный тип (строка вместо ссылки), не та дата (например, без учёта времени — документы позже 00:00:00 отсекаются) или лишнее условие в ГДЕ. Проверьте запрос в консоли с теми же параметрами и поочерёдно убирайте условия, чтобы найти срабатывающее.
Можно ли в запросе получить данные за период с итогами по месяцам?
Да, для регистров накопления используется виртуальная таблица Обороты с указанием периодичности: Обороты(&Начало, &Конец, Месяц, ). В результате появится поле Период, по которому можно группировать и строить отчёты с разбивкой по месяцам, неделям или дням.
Где посмотреть синтаксис языка запросов в самой программе?
В конфигураторе есть встроенный синтакс-помощник: меню «Справка» → «Синтакс-помощник», раздел «Встроенный язык» → «Работа с запросами». Там описаны все конструкции языка запросов, агрегатные функции и работа с объектом Запрос. Это основной справочник, доступный без интернета.
Что важно запомнить
Запрос в 1С состоит из текста на языке запросов, параметров и вызова Выполнить(). Собирайте текст конструктором, передавайте значения только через УстановитьПараметр, отборы по регистрам задавайте в параметрах виртуальных таблиц, результат проверяйте в консоли запросов на копии базы.