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