К статье
Практический материал

Разработка и Конфигурация · 11 мин

1С запрос: как выбрать данные как таблицу

Как в запросе 1С выбрать данные как таблицу: конструкция ВЫБРАТЬ, помещение во временную таблицу через ПОМЕСТИТЬ, таблица значений, примеры кода и типичные ошибки.

В языке запросов 1С фраза «выбрать как таблицу» обычно означает одну из трёх задач: получить результат запроса в виде таблицы значений, поместить промежуточные данные во временную таблицу через конструкцию ПОМЕСТИТЬ или использовать вложенный запрос как источник-таблицу. Все три сценария строятся на операторе ВЫБРАТЬ, но различаются тем, куда попадает результат и как он используется дальше.

Базовый синтаксис выглядит так: ВЫБРАТЬ Товары.Ссылка, Товары.Наименование ИЗ Справочник.Номенклатура КАК Товары. Здесь «КАК Товары» — это псевдоним источника, а не создание таблицы. Чтобы реально получить таблицу, нужно либо выполнить запрос и выгрузить результат, либо явно указать ПОМЕСТИТЬ с именем временной таблицы.

Ниже разобраны все рабочие варианты с примерами кода, условиями выбора между ними и типичными ошибками, из-за которых запрос возвращает пустой результат или падает с ошибкой исполнения.

Базовый синтаксис ВЫБРАТЬ и роль псевдонима КАК

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

Пример простейшего запроса:

ВЫБРАТЬ

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

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

ИЗ

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

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

Как получить результат запроса как таблицу значений

Самый частый сценарий — выполнить запрос из встроенного языка и получить таблицу значений для дальнейшей обработки: заполнения табличной части, выгрузки в файл, передачи в СКД. Для этого используется метод Выгрузить() у результата запроса.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Ссылка КАК Товар,

| Товары.Цена КАК Цена

|ИЗ

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

|ГДЕ

| НЕ Товары.ПометкаУдаления";

ТаблицаРезультат = Запрос.Выполнить().Выгрузить();

После выполнения переменная ТаблицаРезультат содержит объект типа ТаблицаЗначений с колонками Товар и Цена. С ней можно работать стандартно: перебирать строки в цикле, искать через Найти() и НайтиСтроки(), сортировать, сворачивать.

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

Выгрузить или Выбрать

Выполнить().Выгрузить()

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

Выполнить().Выбрать()

Возвращает выборку для последовательного однократного обхода. Экономит память, но не позволяет искать строки и возвращаться назад.

Помещение результата во временную таблицу: ВЫБРАТЬ ... ПОМЕСТИТЬ

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

ВЫБРАТЬ

Продажи.Номенклатура КАК Товар,

СУММА(Продажи.Количество) КАК Количество

ПОМЕСТИТЬ ВТ_Продажи

ИЗ

РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи

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

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

;

ВЫБРАТЬ

ВТ.Товар КАК Товар,

ВТ.Количество КАК Количество,

Спр.Артикул КАК Артикул

ИЗ

ВТ_Продажи КАК ВТ

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

ПО ВТ.Товар = Спр.Ссылка

Первый запрос пакета создаёт временную таблицу ВТ_Продажи, второй обращается к ней как к обычному источнику. Чтобы временные таблицы сохранялись между вызовами Запрос.Выполнить(), объекту запроса назначают менеджер временных таблиц:

Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

Временная таблица живёт в пределах своего менеджера и уничтожается явно командой УНИЧТОЖИТЬ ВТ_Продажи либо при закрытии менеджера. Если не уничтожать большие временные таблицы в длинных пакетах, расход памяти сервера растёт.

Порядок создания временной таблицы
  1. 1
    Сформулируйте запрос отбора и добавьте ПОМЕСТИТЬ ИмяТаблицы после списка полей
  2. 2
    Назначьте объекту Запрос менеджер временных таблиц, если таблица нужна между отдельными вызовами Выполнить()
  3. 3
    Используйте имя временной таблицы как источник в следующих запросах пакета
  4. 4
    Проверьте содержимое через консоль запросов или отладку менеджера
  5. 5
    После использования уничтожьте таблицу командой УНИЧТОЖИТЬ

Вложенный запрос и таблица значений как источник данных

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

ВЫБРАТЬ

Вложенный.Товар КАК Товар,

Вложенный.Сумма КАК Сумма

ИЗ

(ВЫБРАТЬ

Реализация.Товар КАК Товар,

СУММА(Реализация.Сумма) КАК Сумма

ИЗ

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

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

Реализация.Товар) КАК Вложенный

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

Запрос.УстановитьПараметр("ТЗ", ТаблицаЗначений);

Запрос.Текст =

"ВЫБРАТЬ

| ТЗ.Товар КАК Товар,

| ТЗ.Цена КАК Цена

|ПОМЕСТИТЬ ВТ_Цены

|ИЗ

| &ТЗ КАК ТЗ";

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

Как проверить, что таблица получена правильно

После выгрузки проверьте количество строк и имена колонок: ТаблицаРезультат.Количество() и обращение к ТаблицаРезультат.Колонки. Пустая таблица без ошибки выполнения — признак того, что условия ГДЕ отсекли все записи или виртуальная таблица получила неверные параметры периода.

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

Контрольные точки

Как проверить результат

Количество строк после Выгрузить()
Норма

Число строк соответствует ожидаемому отбору

Тревожный признак

Ноль строк при заведомо существующих данных — проверьте ГДЕ и параметры виртуальной таблицы

Имена колонок
Норма

Колонки называются по псевдонимам КАК и доступны в коде

Тревожный признак

Служебные имена вида Поле1 — не заданы псевдонимы для выражений

Временная таблица в пакете
Норма

Второй запрос видит ВТ и возвращает данные

Тревожный признак

Ошибка «Таблица не найдена» — не назначен менеджер временных таблиц или ВТ создана в другом вызове

Типичные ошибки и ограничения

Самая частая ошибка — ожидание, что псевдоним КАК после ИЗ создаёт таблицу, к которой можно обратиться из другого запроса. Псевдоним виден только внутри своего запроса; для межзапросной передачи нужен ПОМЕСТИТЬ. Вторая типичная проблема — обращение к временной таблице без назначенного менеджера: каждый вызов Выполнить() без менеджера работает в собственном контексте, и ВТ из предыдущего вызова недоступна.

Ещё одна группа ошибок связана с типами: при передаче таблицы значений параметром колонки без явного типа или с составным типом ломают соединения и сравнения. Также нельзя дважды ПОМЕСТИТЬ таблицу с одним именем в одном пакете без предварительного УНИЧТОЖИТЬ — запрос завершится ошибкой.

Типичные ошибки
01
Использование КАК после ИЗ вместо ПОМЕСТИТЬ — псевдоним не создаёт таблицу, вторая часть пакета её не увидит
02
Обращение к временной таблице без МенеджерВременныхТаблиц — ошибка «Таблица не найдена» при раздельных вызовах Выполнить()
03
Отсутствие псевдонимов у вычисляемых полей — в таблице значений появляются колонки со служебными именами
04
Передача таблицы значений с нетипизированными колонками параметром — соединение не работает или выполняется очень медленно
05
Повторное ПОМЕСТИТЬ с тем же именем без УНИЧТОЖИТЬ — ошибка исполнения запроса

Что выбрать в конкретной ситуации

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

Маршрут решения

Как выбрать действие

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

Во всех вариантах фундамент один — оператор ВЫБРАТЬ. Разница только в том, куда направлен результат: в выборку, в таблицу значений или во временную таблицу пакета. Осознанный выбор приёмника данных — основа читаемых и быстрых запросов.

Итог

Что важно запомнить

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

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

Чем отличается КАК от ПОМЕСТИТЬ в запросе 1С?

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

Как посмотреть содержимое временной таблицы при отладке?

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

Можно ли использовать результат одного запроса как таблицу в другом объекте Запрос?

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

Почему запрос с ПОМЕСТИТЬ возвращает пустой результат при Выполнить()?

Это нормально: запрос с ПОМЕСТИТЬ не возвращает данных наружу, а только создаёт временную таблицу. Чтобы получить строки, добавьте в пакет финальный запрос, читающий из этой ВТ, или выполните отдельный запрос к ней.

Есть ли ограничение на размер таблицы значений, передаваемой параметром?

Жёсткого документированного лимита нет, но на практике большие таблицы увеличивают время компиляции запроса и расход памяти СУБД. При объёмах в десятки тысяч строк стоит замерить производительность и при необходимости обрабатывать данные порциями.

Как удалить временную таблицу, если она больше не нужна?

Выполните в пакете команду УНИЧТОЖИТЬ ИмяТаблицы. Это освобождает ресурсы сервера и позволяет повторно использовать то же имя в дальнейших запросах пакета без ошибки.