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

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

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

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

Виртуальные таблицы — это конструкции языка запросов 1С, которые не хранятся в базе данных как отдельные объекты, а формируются платформой «на лету» из физических таблиц регистров. Они позволяют получать производные данные: остатки на дату, обороты за период, срезы последних значений — без написания сложных выборок и группировок вручную.

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

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

Что такое виртуальная таблица и как она устроена

Физически в базе данных 1С хранятся таблицы документов, справочников и регистров. Например, регистр накопления «ОстаткиТоваров» хранит записи движений: каждый документ добавляет строки с приходом или расходом. Чтобы узнать текущий остаток номенклатуры, нужно сгруппировать все движения и сложить количества с учётом знака. Виртуальная таблица ОстаткиТовары.Остатки делает эту работу автоматически: платформа строит запрос, который рассчитывает итоги «на лету» или берёт их из служебной таблицы итогов, если итоги по регистру хранятся.

Ключевые свойства виртуальных таблиц:

  • не занимают место в базе как самостоятельные объекты;
  • доступны только в языке запросов, напрямую в коде к ним обратиться нельзя;
  • состав полей и набор параметров определяются типом регистра и его настройками;
  • результат зависит от переданных параметров: периода, условия отбора, признака среза.

Важно понимать, что «виртуальность» не означает бесплатность. За каждым обращением стоит реальный запрос к СУБД, иногда с соединением нескольких физических таблиц. Поэтому виртуальные таблицы требуют такого же внимания к производительности, как и обычные.

Какие виды виртуальных таблиц существуют

Набор виртуальных таблиц зависит от типа объекта метаданных. У справочников и документов их нет — они появляются у регистров и некоторых других объектов.

ОбъектВиртуальные таблицыЧто возвращают
Регистр накопления (остатки)Остатки, Обороты, ОстаткиИОборотыИтоги по измерениям на дату или за период
Регистр накопления (обороты)ОборотыСуммарные движения за период
Регистр сведенийСрезПервых, СрезПоследнихЗначения ресурсов на указанный момент
Регистр бухгалтерииОстатки, Обороты, ОстаткиИОбороты, ОборотыДтКтСальдо и обороты по счетам, субконто
Регистр расчётаДанныеГрафика, ФактическийПериодДействияДанные с учётом графика и периодов действия
Последовательность документовГраницыГраницу актуальности последовательности
ЗадачиЗадачиПоИсполнителюЗадачи с отбором по исполнителю

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

Состав результата у каждой таблицы свой. Например, Остатки возвращает измерения регистра и поля вида <Ресурс>Остаток, а Обороты — поля Приход, Расход, Оборот (для ресурса «Количество» это будут КоличествоПриход, КоличествоРасход, КоличествоОборот).

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

Обращение записывается через полное имя: РегистрНакопления.ИмяРегистра.ИмяТаблицы. Параметры указываются в круглых скобках после имени таблицы. Пример запроса остатков по складу:

ВЫБРАТЬ

Остатки.Номенклатура,

Остатки.КоличествоОстаток

ИЗ

РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, Склад = &Склад) КАК Остатки

Первый параметр Остатки — дата, на которую рассчитываются итоги. Второй — условие отбора, записываемое прямо в параметрах, а не в секции ГДЕ. Это принципиально важно: условие в параметрах применяется до расчёта итогов, а условие в ГДЕ — после, что резко увеличивает объём обрабатываемых данных.

bsl
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Срез.Номенклатура, Срез.Цена
|ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ТипЦен = &ТипЦен) КАК Срез";
Запрос.УстановитьПараметр("Период", ТекущаяДатаСеанса());
Запрос.УстановитьПараметр("ТипЦен", ТипЦенЗакупки);
Результат = Запрос.Выполнить().Выгрузить();

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

Когда виртуальные таблицы незаменимы, а когда лучше без них

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

Однако есть ситуации, где обращение к виртуальной таблице избыточно или вредно:

  • нужен просто список движений документа — берите физическую таблицу регистра с отбором по регистратору;
  • нужны данные без итогов, например проверка наличия записей — виртуальная таблица выполнит лишний расчёт;
  • в запросе уже есть соединение с виртуальной таблицей, а ту же выборку можно получить одной группировкой по движениям.
Маршрут решения

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

Нужны остатки на конкретную датуИспользуйте Остатки(&Дата, Условие) с обязательной датой и отбором
Нужны приход и расход за период в разрезе документовИспользуйте Обороты(&Начало, &Конец, Регистратор, Условие)
Нужна актуальная цена или курс на датуИспользуйте СрезПоследних(&Дата, Условие) регистра сведений
Нужен просто перечень движений одного документаОбратитесь к физической таблице регистра с отбором по Регистратор
Нужны и остатки на начало, и обороты, и остатки на конецИспользуйте ОстаткиИОбороты вместо двух отдельных таблиц

Параметры виртуальных таблиц и типичные тонкости

У каждой виртуальной таблицы свой фиксированный набор параметров, и пропускать их нужно аккуратно. Если параметр не нужен, его можно опустить, но порядковые позиции сохраняются через запятые: Обороты(, , Месяц, ). Незаполненная дата для Остатки означает расчёт на текущий момент, что не всегда соответствует ожиданиям отчёта.

Отдельные тонкости по видам таблиц:

  • СрезПоследних по умолчанию не включает записи на саму дату среза, если дата указана без времени границы «включительно» — поведение управляется тем, что передаётся в параметр (момент времени, дата с признаком включения);
  • ОборотыДтКт регистра бухгалтерии требует аккуратной работы с отборами по счетам дебета и кредита — это разные позиции параметров;
  • для ОстаткиИОбороты можно задать метод дополнения периодов, чтобы получить строки даже там, где движений не было.

Производительность: почему запрос с виртуальной таблицей «тормозит»

Самая частая причина медленных запросов — обращение к виртуальной таблице без параметров отбора. Запрос Остатки(, ) заставляет платформу рассчитать итоги по всем измерениям регистра, а уже потом соединять результат с остальными таблицами. На больших регистрах это секунды и десятки секунд вместо миллисекунд.

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

Типичные ошибки
01
Отбор в ГДЕ вместо параметров таблицы — итоги считаются по всему регистру, запрос замедляется в разы
02
Два обращения к Остатки и Обороты вместо одной таблицы ОстаткиИОбороты — двойной расчёт итогов
03
Соединение двух виртуальных таблиц без предварительной фильтрации — перемножение промежуточных результатов
04
Получение СрезПоследних без отбора по измерениям — срез строится по всем записям регистра сведений
05
Использование виртуальной таблицы там, где достаточно физической — лишний расчёт итогов без пользы

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

Порядок действий при медленном запросе
  1. 1
    Откройте консоль запросов и выполните запрос с замером времени
  2. 2
    Проверьте, переданы ли дата и условия отбора в параметры виртуальной таблицы
  3. 3
    Перенесите отборы по измерениям из секции ГДЕ в параметры таблицы
  4. 4
    Замените пары Остатки + Обороты на одну таблицу ОстаткиИОбороты
  5. 5
    При необходимости введите временную таблицу ключей и фильтруйте через неё
  6. 6
    Повторно замерьте время и сравните с исходным результатом

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

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

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

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

Остаток по тестовой позиции
Норма

Совпадает с типовым отчётом по регистру на ту же дату

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

Расходится — проверьте дату параметра и условие отбора

Поведение на границе периода
Норма

Документ на дату среза учитывается согласно заданной границе

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

Запись пропадает или дублируется — уточните включение границы

Время выполнения
Норма

Запрос с параметрами отбора выполняется заметно быстрее, чем без них

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

Время не меняется — отборы не попали в параметры таблицы

Состав полей результата
Норма

Присутствуют ожидаемые поля Остаток/Приход/Расход

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

Нужного поля нет — выбран не тот тип виртуальной таблицы

Ограничения и безопасные границы самостоятельной работы

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

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

При отладке удобно временно вывести виртуальную таблицу целиком в консоли запросов с жёстким отбором по одной позиции. Так видно реальный состав полей и значения, что быстрее, чем искать ошибку в большом многосекционном запросе.
ПЗ
Практическое замечание

Часто задаваемые вопросы

Чем виртуальная таблица отличается от временной таблицы?

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

Можно ли обратиться к виртуальной таблице из кода без запроса?

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

Почему СрезПоследних не возвращает запись, которая точно есть в регистре?

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

Что быстрее: ОстаткиИОбороты или два отдельных обращения к Остатки и Обороты?

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

Можно ли в параметрах виртуальной таблицы использовать список значений?

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

Отражаются ли виртуальные таблицы в физической структуре базы данных?

Нет, в СУБД нет объектов, соответствующих виртуальным таблицам напрямую. Платформа при выполнении запроса транслирует обращение к ним в SQL-код над физическими таблицами движений и служебными таблицами итогов, если хранение итогов для регистра включено.

Итог

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

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