Разработка и Конфигурация · 14 мин
Виртуальные таблицы в 1С: назначение, виды и практическое применение
Что такое виртуальные таблицы в запросах 1С, какие типы бывают, когда их применять, как ставить отборы и избегать ошибок производительности.
Виртуальная таблица в 1С — это не реально существующая таблица базы данных, а вычисляемый набор данных, который платформа формирует на лету на основе физических таблиц регистров. Когда разработчик пишет запрос к регистру накопления или регистру сведений, он может обратиться либо к физической таблице движений, либо к виртуальной таблице — например, «Остатки», «Обороты» или «СрезПоследних». Платформа сама построит итоговый SQL-запрос и вернёт уже агрегированные данные.
Главная причина существования виртуальных таблиц — скорость разработки и читаемость кода. Без них для получения остатка товара на складе пришлось бы вручную суммировать все приходные и расходные движения, группировать по номенклатуре и складу. Виртуальная таблица «Остатки» делает это одной строкой запроса. При этом важно понимать: виртуальная таблица — это не «бесплатная» оптимизация. Неправильное её использование, прежде всего отбор в соединении вместо параметров, способно замедлить запрос в десятки раз.
Материал рассчитан на разработчиков и внедренцев, которые пишут запросы в конфигураторе или консоли запросов. Рассмотрены типы виртуальных таблиц, параметры, типовые ошибки и способы проверить, что запрос работает быстро и возвращает корректные данные.
Что такое виртуальная таблица и как она работает
Физически в базе данных регистр накопления хранится как таблица движений и, для регистров остатков, таблица итогов. Виртуальная таблица — это программный «фасад»: платформа при обращении к ней формирует запрос к этим физическим таблицам, применяет агрегацию и отборы и возвращает результат. Например, обращение РегистрНакопления.ТоварыНаСкладах.Остатки превращается в чтение таблицы итогов с фильтрацией по периоду и измерениям.
Ключевое следствие: виртуальная таблица не существует постоянно и не хранит данные отдельно. Каждое обращение к ней — это вычисление. Если в одном запросе трижды обратиться к одной и той же виртуальной таблице с разными параметрами, платформа выполнит три вычисления. Поэтому повторные обращения к одним и тем же итогам внутри сложного запроса — частая причина медленной работы.
Ещё одно важное свойство — состав полей виртуальной таблицы отличается от физической. У таблицы «Остатки» нет полей «ВидДвижения», «Регистратор», «Период» как у движений, зато есть поле вида «КоличествоОстаток». У таблицы «Обороты» появляются поля «КоличествоПриход», «КоличествоРасход», «КоличествоОборот». Перед написанием запроса полезно открыть в конструкторе запроса список доступных полей конкретной виртуальной таблицы.
Основные виды виртуальных таблиц и их назначение
Набор доступных виртуальных таблиц зависит от типа регистра. У регистров накопления с видом «Остатки» есть таблицы «Остатки», «Обороты» и «ОстаткиИОбороты». У регистров накопления с видом «Обороты» — только «Обороты». У регистров сведений — «СрезПервых» и «СрезПоследних», у регистров расчёта — таблицы фактического периода действия и данных графика, у регистров бухгалтерии — «Остатки», «Обороты», «ОстаткиИОбороты», «ОборотыДтКт».
Таблица «Остатки» возвращает значения ресурсов на заданный момент времени в разрезе измерений. «Обороты» — суммы прихода и расхода за период. «ОстаткиИОбороты» объединяет оба показателя: начальный остаток, приход, расход и конечный остаток за период с заданной периодичностью (день, месяц и т.д.). Это основной источник данных для отчётов вида «ведомость по товарам».
«СрезПоследних» у регистра сведений возвращает актуальные значения ресурсов на указанную дату — например, текущую цену номенклатуры или действующий курс валюты. «СрезПервых» работает зеркально: первое значение после указанной даты. У регистров бухгалтерии таблица «ОборотыДтКт» показывает корреспонденции счетов — обороты между дебетом одного счёта и кредитом другого, что незаменимо для анализа проводок.
| Виртуальная таблица | Тип регистра | Что возвращает |
|---|---|---|
| Остатки | Накопления (остатки), бухгалтерии | Значения ресурсов на момент времени |
| Обороты | Накопления, бухгалтерии | Суммы прихода и расхода за период |
| ОстаткиИОбороты | Накопления (остатки), бухгалтерии | Начальный остаток, обороты, конечный остаток |
| СрезПервых / СрезПоследних | Сведений (периодический) | Значения ресурсов на дату |
| ОборотыДтКт | Бухгалтерии | Обороты между счетами дебета и кредита |
Параметры виртуальных таблиц: почему это критично для скорости
У каждой виртуальной таблицы есть параметры, которые указываются в скобках после её имени: период, условие отбора, список счетов или субконто. Например: РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаОстатков, Склад = &Склад). Параметры применяются платформой на этапе вычисления таблицы, то есть до того, как данные попадут в основной запрос.
Если вместо параметра написать отбор в секции ГДЕ основного запроса, платформа сначала вычислит виртуальную таблицу целиком — по всем складам, всем номенклатурным позициям, всем организациям — и только потом отфильтрует результат. На небольшой базе разница незаметна, на базе с миллионами движений запрос может выполняться в десятки раз дольше и занимать лишнюю память на сервере СУБД.
Практическое правило формулируется просто: всё, что можно передать в параметры виртуальной таблицы, должно передаваться в параметры. В секции ГДЕ остаются только те условия, которые невозможно выразить параметрами, — например, сравнение полей двух таблиц или сложные логические конструкции с ИЛИ по разным полям.
Типовые сценарии использования
Получение остатков на дату для отчёта
Самая частая задача — показать остатки товаров, денег или взаиморасчётов на выбранную пользователем дату. Запрос обращается к таблице «Остатки» с параметром периода. Если нужна детализация по документам расчётов или партиям, эти измерения просто включаются в выборку — платформа учтёт их при чтении итогов, если итоги по этим измерениям хранятся.
Срез последних цен или курсов
Для подстановки актуальной цены в документ или отчёт используется «СрезПоследних» периодического регистра сведений. Важно передавать в параметры не только дату среза, но и условие по измерениям (например, список номенклатуры), иначе платформа вычислит срез по всей таблице. При соединении среза с таблицей товаров соединение выполняется по измерениям регистра.
Анализ движений за период с остатками на начало и конец
Отчёты вида «оборотно-сальдовая ведомость» или «карточка склада» строятся на таблице «ОстаткиИОбороты». Параметр «Периодичность» позволяет получить данные в разрезе дней или месяцев одним запросом, без циклов и множественных обращений к базе. Это существенно быстрее, чем вычислять остаток на каждую дату отдельным запросом.
- 1Определите, какие данные нужны: момент времени (Остатки, СрезПоследних) или период (Обороты, ОстаткиИОбороты)
- 2Откройте конструктор запроса и посмотрите доступные поля и параметры выбранной виртуальной таблицы
- 3Задайте параметры: период, условия по измерениям, счета или субконто — всё, что можно отфильтровать заранее
- 4Добавьте соединения с другими таблицами только после виртуальной таблицы с параметрами
- 5Выполните запрос в консоли на реальной базе и замерьте время выполнения
Типичные ошибки и их последствия
Первая и самая распространённая ошибка — отбор в соединении или в ГДЕ вместо параметров. Вторая — соединение двух виртуальных таблиц между собой без предварительной фильтрации: платформа вычисляет обе целиком, а затем соединяет большие промежуточные результаты. Правильный подход — ограничить каждую виртуальную таблицу параметрами до минимально необходимого набора строк.
Третья ошибка — использование виртуальной таблицы там, где нужны сами движения. Если отчёт должен показать документы-регистраторы, время проведения или вид движения, обращаться нужно к физической таблице регистра, а не к «Оборотам». Попытка «вытащить» регистратор из виртуальной таблицы либо невозможна, либо приводит к неочевидным результатам.
Четвёртая ошибка касается «СрезаПоследних» без указания даты: если параметр периода не задан, срез выполняется на максимальную дату, что часто не соответствует логике отчёта за прошлый период и дополнительно нагружает базу. Всегда явно передавайте дату среза.
Производительность: итоги, индексы и ограничения
Скорость таблицы «Остатки» напрямую зависит от хранения итогов регистра. Если итоги включены и актуальны, чтение остатков выполняется быстро. Если итоги отключены или рассчитаны не на текущий период, платформа вынуждена суммировать движения, и запрос замедляется. Проверить состояние итогов можно в режиме «Управление итогами» в конфигураторе или типовой обработкой администрирования.
Для таблицы «Обороты» ситуация иная: отдельных хранимых итогов оборотов по произвольным периодам нет, поэтому запрос оборотов за длинный период с детализацией по регистраторам всегда читает движения. Здесь особенно важно ограничивать период и состав измерений параметрами.
Ещё одно ограничение: виртуальные таблицы нельзя использовать в запросах к внешним источникам данных и в некоторых контекстах (например, в планах обмена с определёнными настройками). Также в запросах с компоновкой данных параметры виртуальных таблиц должны быть согласованы с параметрами СКД — иначе пользовательский отбор в отчёте не будет влиять на вычисление таблицы.
Как проверить результат
Запрос выполняется за приемлемое время на полном объёме данных
Запрос «висит» или время растёт непропорционально фильтрам — вероятно, отбор стоит не в параметрах
Остаток из запроса совпадает с типовым отчётом по регистру на ту же дату
Расхождения — проверьте дату с границей, отборы и актуальность итогов
Чтение идёт по таблице итогов с индексным поиском
Полное сканирование таблицы движений при запросе остатков
Когда виртуальная таблица не нужна: альтернативы
Если требуется список конкретных документов, изменивших регистр, или анализ по времени проведения с точностью до секунды — используйте физическую таблицу регистра. Если нужны итоги, которые платформа не вычисляет (например, средневзвешенная цена за период с особыми правилами), придётся группировать движения вручную или вычислять показатель в коде.
Для сложных отчётов часто оптимальна комбинация: виртуальная таблица с жёсткими параметрами помещается во временную таблицу, а дальнейшие соединения и вычисления выполняются уже с ней. Менеджер временных таблиц позволяет переиспользовать результат в нескольких запросах пакета, не вычисляя итоги повторно.
Как выбрать источник данных
Проверка корректности и отладка запроса
Базовый приём проверки — сверка с типовым отчётом. Если ваш запрос к «Остаткам» возвращает 150 единиц товара, а типовой отчёт «Остатки товаров» на ту же дату показывает 148, ищите причину в границе даты (остатки «на начало дня» и «на конец дня» отличаются), в отборах или в неактуальных итогах. Помните, что при передаче даты без времени остатки вычисляются на начало этой даты.
Для отладки производительности используйте консоль запросов с замером времени, а на серверных базах — технологический журнал с событием DBMSSQL или инструменты профилирования СУБД. Признак проблемы — длительное чтение таблицы движений там, где ожидалось чтение итогов. Также полезно проверить запрос на копии рабочей базы, а не на маленькой тестовой: на ней ошибки производительности просто не видны.
Что важно запомнить
Виртуальные таблицы — вычисляемые платформой итоги регистров: остатки, обороты, срезы. Они ускоряют разработку, но требуют дисциплины: все отборы передавайте через параметры, не соединяйте виртуальные таблицы без фильтрации, следите за актуальностью итогов и проверяйте результат сверкой с типовым отчётом.
Частые вопросы
Чем виртуальная таблица отличается от временной таблицы?
Виртуальная таблица вычисляется платформой из данных регистра при каждом обращении к ней в запросе. Временная таблица — это материализованный результат вашего запроса, помещённый в менеджер временных таблиц и существующий, пока живо соединение. Виртуальную таблицу нельзя создать самостоятельно — её состав и логика зашиты в платформу, а временную вы формируете сами.
Почему запрос к «Остаткам» работает медленно, хотя итоги включены?
Частые причины: отбор стоит в секции ГДЕ, а не в параметрах; итоги рассчитаны не на текущий период; запрашиваются остатки на дату внутри нерассчитанного диапазона; в запросе несколько соединений с виртуальной таблицей. Проверьте период рассчитанных итогов и перенесите все условия по измерениям в параметры таблицы.
Можно ли получить регистратор из таблицы «Обороты»?
Да, но с оговоркой: у таблицы «Обороты» есть параметр периодичности, и если указать периодичность «Регистратор» или «Авто» с выборкой поля Регистратор, обороты будут сгруппированы по документам. Однако это заставляет платформу читать таблицу движений, а не итоги. Если нужны именно документы, часто эффективнее запрос к физической таблице регистра.
Что вернёт «СрезПоследних», если на указанную дату записей нет?
Срез возвращает ближайшую запись с периодом меньше или равным указанной дате. Если такой записи для конкретной комбинации измерений вообще не существует, эта комбинация просто не попадёт в результат — строки с пустыми значениями не формируются. При соединении с таблицей товаров это даёт «дырки», которые обрабатывают через ЛЕВОЕ СОЕДИНЕНИЕ и функцию ЕСТЬNULL.
Как правильно передать список значений в условие виртуальной таблицы?
Передайте в параметр массив или список значений и используйте конструкцию В, например: Номенклатура В (&СписокНоменклатуры). Для больших списков надёжнее поместить значения во временную таблицу и связать условие через В (ВЫБРАТЬ ... ИЗ ВременнаяТаблица) — это устойчивее к ограничениям СУБД на длину списка параметров.
Работают ли виртуальные таблицы в СКД так же, как в обычных запросах?
Да, механизм тот же, но есть нюанс: отборы, которые пользователь задаёт в настройках отчёта СКД, применяются к итоговому набору данных, а не к параметрам виртуальной таблицы. Чтобы пользовательский отбор влиял на вычисление таблицы, свяжите его с параметрами через настройки компоновки или зафиксируйте критичные отборы (период, организация) непосредственно в параметрах виртуальной таблицы в тексте запроса набора данных.