Добавление полей в запросах 1С: от простого выбора до соединений и подзапросов

· 9 мин

Содержание

Поле добавляют в секцию ВЫБРАТЬ запроса — просто дописывают его имя через запятую после уже перечисленных. Если поле лежит в другой таблице или его нужно вычислить, одной строкой уже не обойтись: подключают соединение, подзапрос или выражение. В языке запросов 1С 8.3 всё это оформляется одними и теми же конструкциями независимо от конфигурации — БП 3.0, ЗУП 3.1, УТ 11 или своя разработка.

Ниже — как добавить поле в запрос во всех типовых случаях: реквизит документа или справочника, вычисляемое значение, агрегат (сумма, количество), данные из регистров через виртуальные таблицы, поля из связанных таблиц через соединение и значение из подзапроса. Текст запроса писать руками необязательно — в Конфигураторе есть конструктор, но понимать структуру всё равно нужно, иначе сложные поля через него не собрать.

Простое поле: дописать реквизит в секцию ВЫБРАТЬ

Самый частый случай — добавить в выборку ещё один реквизит таблицы. Поля перечисляются через запятую, источник данных указывается в секции ИЗ.

ВЫБРАТЬ
    Номенклатура.Ссылка,
    Номенклатура.Наименование,
    Номенклатура.Артикул
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Чтобы добавить, например, единицу измерения, дописываем строку в секцию ВЫБРАТЬ:

ВЫБРАТЬ
    Номенклатура.Ссылка,
    Номенклатура.Наименование,
    Номенклатура.Артикул,
    Номенклатура.ЕдиницаИзмерения
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Несколько правил, которые экономят время:

  • 🔸 После последнего поля запятая не ставится — лишняя запятая перед ИЗ даёт ошибку синтаксиса.
  • 🔸 Обращаться к полю нужно через псевдоним таблицы (Номенклатура.Артикул), заданный после КАК в секции ИЗ.
  • 🔸 Если имя поля или псевдонима содержит пробел либо совпадает с ключевым словом, его не берут в кавычки — просто переименовывают псевдоним.

К реквизиту ссылочного типа можно обращаться «через точку», добавляя поле из связанной таблицы без явного соединения:

ВЫБРАТЬ
    Номенклатура.Наименование,
    Номенклатура.ЕдиницаИзмерения.Наименование КАК ЕдиницаНаименование
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Платформа сама подставит левое соединение со справочником единиц. Это удобно для двух-трёх уровней вложенности, но на больших выборках цепочки «через точку» лучше заменять явным соединением — так предсказуемее план запроса.

Псевдоним через КАК задают, чтобы поле попало в результат под понятным именем — особенно для вычисляемых значений и колонок отчёта на СКД.

Вычисляемые поля и выражения

Вычисляемое поле — это не реквизит, а выражение в секции ВЫБРАТЬ. Арифметика, конкатенация строк, функции работы с датами, условная логика.

ВЫБРАТЬ
    Товары.Номенклатура,
    Товары.Количество,
    Товары.Цена,
    Товары.Количество * Товары.Цена КАК Сумма
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК Товары

Поле Сумма в таблице не хранится — оно считается на лету. Псевдоним здесь обязателен: без КАК платформа не сможет назвать колонку.

Для условий внутри поля используют конструкцию ВЫБОР … КОГДА … ТОГДА … ИНАЧЕ … КОНЕЦ (аналог CASE в SQL):

ВЫБРАТЬ
    Контрагенты.Наименование,
    ВЫБОР
        КОГДА Контрагенты.ЮрФизЛицо = ЗНАЧЕНИЕ(Перечисление.ЮридическоеФизическоеЛицо.ФизическоеЛицо)
            ТОГДА "Физлицо"
        ИНАЧЕ "Организация"
    КОНЕЦ КАК ТипКонтрагента
ИЗ
    Справочник.Контрагенты КАК Контрагенты

Ссылку на конкретный элемент перечисления, предопределённый элемент справочника или пустую ссылку задают функцией ЗНАЧЕНИЕ(...). Сравнивать поле с «текстом» названия нельзя — только со значением нужного типа.

Строковые поля склеивают оператором +, даты обрабатывают функциями НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА, ДОБАВИТЬКДАТЕ, РАЗНОСТЬДАТ. Для чисел пригодятся ВЫРАЗИТЬ(... КАК ЧИСЛО(15,2)), ОКРУГЛ.

Агрегатные поля: сумма, количество, максимум

Когда нужно свернуть строки — получить итог по группе — добавляют агрегатную функцию: СУММА, КОЛИЧЕСТВО, МАКСИМУМ, МИНИМУМ, СРЕДНЕЕ.

ВЫБРАТЬ
    Товары.Номенклатура,
    СУММА(Товары.Количество) КАК Количество,
    СУММА(Товары.Количество * Товары.Цена) КАК Сумма
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК Товары
СГРУППИРОВАТЬ ПО
    Товары.Номенклатура

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

КОЛИЧЕСТВО(*) считает все строки, КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Поле) — только уникальные значения. Это разные числа, и путаница между ними — частая причина расхождений в отчётах.

Поля из регистров через виртуальные таблицы

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

Для регистра накопления:

ВЫБРАТЬ
    Остатки.Номенклатура,
    Остатки.Склад,
    Остатки.КоличествоОстаток
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК Остатки

Имя ресурса в виртуальной таблице остатков получает суффикс Остаток (КоличествоОстаток), в таблице оборотов — Приход, Расход, Оборот. Тип виртуальной таблицы выбирают по задаче:

ТаблицаЧто возвращаетПараметры
Остатки(Период, Условие)остаток на моментпериод расчёта
Обороты(Начало, Конец, Период, Условие)приход/расход за интервалграницы и периодичность
ОстаткиИОбороты(...)остатки на начало/конец плюс оборотыграницы и периодичность

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

Для регистра сведений с периодичностью добавляют поля через срез:

ВЫБРАТЬ
    Цены.Номенклатура,
    Цены.Цена,
    Цены.Валюта
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, ) КАК Цены

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

Поля из связанных таблиц через соединение

Когда поле лежит в другой таблице, которую не достать «через точку» (например, значение из другого документа или регистра), добавляют соединение СОЕДИНЕНИЕ … ПО.

ВЫБРАТЬ
    Заказы.Ссылка,
    Заказы.Контрагент,
    Оплаты.СуммаОплаты
ИЗ
    Документ.ЗаказПокупателя КАК Заказы
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ВзаиморасчётыСКлиентами.Обороты КАК Оплаты
    ПО Оплаты.ЗаказПокупателя = Заказы.Ссылка

Виды соединений:

  • 🔹 ЛЕВОЕ СОЕДИНЕНИЕ — берём все строки левой таблицы; где справа совпадения нет, добавленное поле получит NULL.
  • 🔹 ВНУТРЕННЕЕ СОЕДИНЕНИЕ — только строки, где есть совпадение в обеих таблицах.
  • 🔹 ПРАВОЕ СОЕДИНЕНИЕ — зеркало левого.
  • 🔹 ПОЛНОЕ СОЕДИНЕНИЕ — все строки из обеих таблиц.

В 95% отчётов используют именно левое соединение: нужны все строки основной таблицы, а добавленное поле — дополнение к ним.

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

ВЫБРАТЬ
    Заказы.Ссылка,
    ЕСТЬNULL(Оплаты.СуммаОплаты, 0) КАК Оплачено
ИЗ
    Документ.ЗаказПокупателя КАК Заказы
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ВзаиморасчётыСКлиентами.Обороты КАК Оплаты
    ПО Оплаты.ЗаказПокупателя = Заказы.Ссылка

ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) заменяет пустое значение на ноль, пустую строку или пустую дату — в зависимости от типа.

Поле-значение из подзапроса

Иногда поле нужно получить отдельным запросом внутри запроса. Подзапрос добавляют в трёх местах: как источник в ИЗ, как фильтр в ГДЕ и реже — как скалярное поле.

Чаще всего подзапрос ставят источником и соединяют с ним, предварительно свернув данные:

ВЫБРАТЬ
    Номенклатура.Ссылка,
    ЕСТЬNULL(Продажи.Количество, 0) КАК Продано
ИЗ
    Справочник.Номенклатура КАК Номенклатура
    ЛЕВОЕ СОЕДИНЕНИЕ (
        ВЫБРАТЬ
            Товары.Номенклатура КАК Номенклатура,
            СУММА(Товары.Количество) КАК Количество
        ИЗ
            Документ.РеализацияТоваровУслуг.Товары КАК Товары
        СГРУППИРОВАТЬ ПО
            Товары.Номенклатура
    ) КАК Продажи
    ПО Продажи.Номенклатура = Номенклатура.Ссылка

Так добавляем к каждой номенклатуре поле «продано всего», уже агрегированное внутри подзапроса. В секции ГДЕ подзапрос применяют с оператором В:

ГДЕ
    Номенклатура.Ссылка В (
        ВЫБРАТЬ РАЗЛИЧНЫЕ Товары.Номенклатура
        ИЗ Документ.РеализацияТоваровУслуг.Товары КАК Товары
    )

На повторяющихся расчётах подзапрос лучше вынести в отдельную временную таблицу пакетного запроса (ПОМЕСТИТЬ ВременнаяТаблица) и проиндексировать поле соединения. Тогда платформа посчитает его один раз, а не на каждую строку.

Поля в запросах с итогами и группировкой

Группировка (СГРУППИРОВАТЬ ПО) сворачивает строки, а итоги (ИТОГИ … ПО) добавляют в результат отдельные строки с подытогами — это разные механизмы.

ВЫБРАТЬ
    Товары.Склад,
    Товары.Номенклатура,
    СУММА(Товары.Количество) КАК Количество
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК Товары
СГРУППИРОВАТЬ ПО
    Товары.Склад,
    Товары.Номенклатура
ИТОГИ
    СУММА(Количество)
ПО
    Склад

Секция ИТОГИ добавляет строки с суммой по каждому складу и общий итог. Обращаться к результату с итогами удобнее через обход по группировкам: Выборка = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам).

Если нужно добавить поле, которое участвует только в упорядочивании, его помещают в УПОРЯДОЧИТЬ ПО. При группировке сортировать можно по полям группировки или по агрегатам.

Конструктор запроса в Конфигураторе

Текст запроса необязательно набирать вручную. В модуле ставим курсор внутрь строки с текстом запроса, правой кнопкой мыши вызываем контекстное меню и выбираем Конструктор запроса. Если текста ещё нет — конструктор предложит создать новый.

Чтобы добавить поле через конструктор:

  1. На вкладке Таблицы и поля слева выбираем таблицу-источник.
  2. В средней колонке раскрываем её поля и двойным кликом переносим нужное в правую колонку Поля.
  3. Для вычисляемого поля жмём кнопку добавления произвольного выражения над списком полей и пишем формулу.
  4. Псевдоним задаём на вкладке Объединения/Псевдонимы.

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

Для отладки готового запроса вне модуля используют обработку «Консоль запросов» — внешнюю обработку , которую подключают через Файл → Открыть. Она показывает результат и план, не трогая код конфигурации.

Оптимизация запроса после добавления полей

Каждое новое поле — особенно из соединения или подзапроса — нагружает запрос. Несколько приёмов, которые держат его быстрым:

  • ⚡ Не выбирайте лишнего. ВЫБРАТЬ * в языке запросов не поддерживается, и это к лучшему: перечисляйте только нужные поля.
  • ⚡ Отбор в виртуальных таблицах задавайте параметром, а не в ГДЕ.
  • ⚡ Избегайте соединения с виртуальной таблицей напрямую — сначала поместите её данные во временную таблицу пакетного запроса, затем соединяйте и индексируйте поле связи (ИНДЕКСИРОВАТЬ ПО).
  • ⚡ Не обращайтесь «через точку» на много уровней в больших выборках — заменяйте явным соединением.
  • ⚡ Не соединяйте по полям составного (неопределённого) типа — платформа не использует индекс.
Проверка запроса после добавления поля
Выполнено: 0 / 5

Частые ошибки при добавлении полей

  • ❌ Поле не входит в группировку. Добавили агрегат, но не внесли остальные поля в СГРУППИРОВАТЬ ПО. Решение — перечислить там все неагрегатные поля.
  • ❌ NULL вместо числа. После левого соединения поле пустое, и сумма «съедается». Оборачивайте такие поля в ЕСТЬNULL(Поле, 0).
  • ❌ Остаток не на ту дату. Период передали в ГДЕ, а не в параметр виртуальной таблицы Остатки. Отбор по дате в ГДЕ виртуальная таблица уже не учитывает при расчёте остатка.
  • ❌ Сравнение перечисления со строкой. Поле-перечисление сравнивают с текстом названия. Нужна функция ЗНАЧЕНИЕ(Перечисление.Имя.Значение).
  • ❌ Дубли строк после соединения. Присоединённая таблица содержит несколько записей на одну строку основной — получаем задвоение. Сверните подзапрос агрегатом до соединения.
Проверьте себя
Что обязательно сделать, если в запрос добавили поле СУММА(...)?
Чем заменить NULL в числовом поле после ЛЕВОГО СОЕДИНЕНИЯ?
Где задавать отбор для виртуальной таблицы Остатки?

Частые вопросы

Можно ли добавить поле, которого нет в таблице?
Да — это вычисляемое поле. Пишете выражение прямо в секции ВЫБРАТЬ и задаёте псевдоним через КАК. В таблице такое поле не хранится, оно считается при выполнении запроса.
Почему добавленное поле возвращает NULL?
Чаще всего поле пришло из левого соединения, где для этой строки нет пары. Оберните его в ЕСТЬNULL(Поле, 0) для чисел или ЕСТЬNULL(Поле, "") для строк. Для даты — ЕСТЬNULL(Поле, ДАТАВРЕМЯ(1,1,1)).
Как добавить в запрос поле остатка по складу?
Обратитесь не к самому регистру накопления, а к его виртуальной таблице РегистрНакопления.Имя.Остатки(&Период, Склад = &Склад). Ресурс получит суффикс Остаток, например КоличествоОстаток.
В чём разница между СГРУППИРОВАТЬ ПО и ИТОГИ?
СГРУППИРОВАТЬ ПО сворачивает строки в одну по значению поля. ИТОГИ … ПО оставляет детальные строки и добавляет к ним отдельные строки-подытоги. Их можно использовать вместе.
Как добавить поле из другого документа?
Через соединение ЛЕВОЕ СОЕДИНЕНИЕ Документ.Имя КАК Алиас ПО условие или через подзапрос в секции ИЗ. Напрямую «через точку» доступны только реквизиты ссылочных полей текущей таблицы.