Получение регистратора из виртуальной таблицы Обороты в 1С

Узнайте простой способ вытащить документ-регистратор из виртуальной таблицы оборотов. Примеры кода и хитрости для 1С-разработчиков!

Бесплатная консультация юриста

+7 (800) 302-87-29

Реклама jurik.ru

Работа с регистрами накопления — одна из базовых задач разработчика на платформе 1С:Предприятие. Часто возникает необходимость не просто получить суммы оборотов или остатков, но и определить, каким именно документом (регистратором) были сделаны соответствующие записи. В данной статье подробно разберем, как построить запрос для получения регистратора из виртуальной таблицы оборотов, какие существуют нюансы и альтернативные подходы.

Теоретические основы: Регистратор и виртуальные таблицы

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

Платформа предоставляет доступ к данным регистров через виртуальные таблицы:

  • Остатки (Балансы) — состояние на момент времени.
  • Обороты (Turnovers) — движение за период (Приход, Расход, Оборот).
  • Движения (Records) — «сырые» записи регистра без агрегации.

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

Синтаксис запроса к виртуальной таблице Обороты

Для обращения к виртуальной таблице оборотов используется следующий синтаксис в языке запросов:

РЕГИСТРНАКОПЛЕНИЯ.<ИмяРегистра>.ОБОРОТЫ(
 <Периодичность>, 
 <ГраницыПериода>, 
 <УсловиеОтбораПоИзмерениям>, 
 <СписокИзмеренийДляГруппировки>
)

Параметры:

  1. Периодичность (Секунда, Минута, Час, День, Неделя, Месяц, Квартал, Полгода, Год, ГраницаПериода) — определяет гранулярность срезов времени.
  2. ГраницыПериода — начало и конец периода (например, &НачалоПериода, &КонецПериода).
  3. УсловиеОтбораПоИзмерениям — строка с условием WHERE для измерений (например, Номенклатура = &Номенклатура).
  4. СписокИзмеренийДляГруппировки, перечень полей (измерений, ресурсов, а также Регистратор, Период, НомерСтроки), по которым будет происходить группировка.

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

Самая частая задача: «Найти документ, который списал/пришел определенный товар на складе за период».

Пример 1: Базовый запрос с группировкой по Регистратору

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

Разбор ключевых моментов:

  • Параметр 4 (СписокИзмеренийДляГруппировки): Мы явно указали Регистратор, Период. Это заставляет платформу не агрегировать все движения в одну строку за период, а разбить их по каждому регистратору и дате документа.
  • Поле Период: В виртуальной таблице Обороты поле Период представляет собой начало интервала периодичности (или дату регистратора, если периодичность = Секунда/ГраницаПериода). Для точной привязки к документу лучше использовать периодичность Секунда или ГраницаПериода.
  • Агрегатные функции: Поскольку мы группируем по Регистратору, ресурсы (КоличествоПриход, КоличествоРасход) нужно оборачивать в СУММА (хотя в рамках одного регистратора и измерений строка обычно одна).

Пример 2: Получение «последнего» регистратора (Топ-1)

Если нужно узнать, какой документ последним двигал товар (например, для определения последней цены закупки):

ВЫБРАТЬ ПЕРВЫЕ 1
 ТоварыНаСкладахОбороты.Регистратор,
 ТоварыНаСкладахОбороты.Период,
 ТоварыНаСкладахОбороты.КоличествоПриход,
 ТоварыНаСкладахОбороты.СтоимостьПриход
ИЗ
 РегистрНакопления.ТоварыНаСкладах.ОБОРОТЫ(
 ГраницаПериода, 
 &НачалоПериода, &КонецПериода, 
 Номенклатура = &Номенклатура, 
 Регистратор, Период
 ) КАК ТоварыНаСкладахОбороты
УПОРЯДОЧИТЬ ПО
 ТоварыНаСкладахОбороты.Период УБЫВ

Здесь использована периодичность ГраницаПериода — это самый эффективный способ получить строки, привязанные к конкретным моментам времени (датам документов), без лишних срезов по дням/месяцам.

Альтернативный (и часто более правильный) подход: Виртуальная таблица Движения

Если задача, получить подробные строки документа (все номенклатуру из конкретного документа, цены, характеристики, серии), использование таблицы Обороты с группировкой по Регистратору может быть избыточным и медленным (платформа все равно агрегирует данные перед выдачей).

Для этих целей идеально подходит виртуальная таблица Движения (Records):

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

Сравнение подходов

Характеристика Обороты (с группировкой по Регистратору) Движения (Records)
Цель Анализ итогов по документам за период (сколько пришло/ушло в каждом доке) Получение полного состава строк конкретного документа(ов)
Производительность Требует агрегации (может быть медленно на больших регистрах) Чтение «сырых» записей по индексу (очень быстро)
Доступные поля Только измерения, ресурсы, Регистратор, Период, НомерСтроки Все реквизиты регистра (в т.ч. Характеристика, Серия, Цена, Партия и т.д.)
Фильтр по документу Через условие отбора по измерениям + группировка Прямой отбор Регистратор = &Ссылка (мгновенно)

Типичные ошибки и нюансы

Ошибка 1: Забыли добавить Регистратор в 4-й параметр

Если в списке группировки (4-й параметр) не указать Регистратор, поле Регистратор в выборке будет недоступно (NULL) или запрос вернет ошибку, так как платформа не знает, что нужно сохранять это измерение при агрегации.

Ошибка 2: Использование периодичности «День»/«Месяц» для поиска документа

При периодичности «День» поле Период вернет 00:00:00 текущего дня. Если за день было несколько документов, они сольются в одну строку, и Регистратор станет неопределенным (или вернет первый попавшийся). Всегда используйте «Секунда» или «ГраницаПериода» для привязки к конкретному документу.

Ошибка 3: Попытка получить реквизиты регистратора (Номер, Дата, Контрагент) прямо из Оборотов

В виртуальной таблице Обороты доступен только сам объект-ссылка Регистратор. Чтобы получить его реквизиты, нужно сделать JOIN (СОЕДИНЕНИЕ) с таблицей документов или использовать точечную навигацию в СКД/Объекте запроса:

ВЫБРАТЬ
 ТоварыНаСкладахОбороты.Регистратор.Номер КАК НомерДок,
 ТоварыНаСкладахОбороты.Регистратор.Дата КАК ДатаДок,
 ТоварыНаСкладахОбороты.Регистратор.Контрагент КАК Контрагент
 // ... остальные поля
ИЗ ...

Программное выполнение запроса (Пример на встроенном языке)

Процедура ПолучитьРегистраторовОборотов(Номенклатура, Склад, НачалоПериода, КонецПериода)
 
 Запрос = Новый Запрос;
 Запрос.Текст = 
 "ВЫБРАТЬ
 | ТоварыНаСкладахОбороты.Регистратор,
 | ТоварыНаСкладахОбороты.Период,
 | СУММА(ТоварыНаСкладахОбороты.КоличествоПриход) КАК Приход,
 | СУММА(ТоварыНаСкладахОбороты.КоличествоРасход) КАК Расход
 |ИЗ
 | РегистрНакопления.ТоварыНаСкладах.ОБОРОТЫ(
 | ГраницаПериода, 
 | &НачалоПериода, &КонецПериода, 
 | Номенклатура = &Номенклатура И Склад = &Склад, 
 | Регистратор, Период
 | ) КАК ТоварыНаСкладахОбороты
 |СГРУППИРОВАТЬ ПО
 | ТоварыНаСкладахОбороты.Регистратор,
 | ТоварыНаСкладахОбороты.Период
 |УПОРЯДОЧИТЬ ПО
 | ТоварыНаСкладахОбороты.Период УБЫВ";
 
 Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
 Запрос.УстановитьПараметр("Склад", Склад);
 Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
 Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
 
 Результат = Запрос.Выполнить;
 Выборка = Результат.Выбрать;
 
 Пока Выборка.Следующий Цикл
 // Выборка.Регистратор ౼ это Ссылка на документ (ДокументСсылка.РеализацияТоваровУслуг и т.д;)
 Сообщить("Док: " + Выборка.Регистратор + " от " + Формат(Выборка.Период, "ДФ=dd.MM.yyyy ЧЧ:мм:сс") + 
 " Приход: " + Выборка.Приход + " Расход: " + Выборка.Расход);
 КонецЦикла;
 
КонецПроцедуры

Производительность и индексы

  • Индексы регистра: Платформа автоматически создает индексы по измерениям. Указание условий отбора по измерениям (3-й параметр) позволяет использовать индексный поиск (Index Seek) вместо полного сканирования (Table Scan).
  • Периодичность ГраницаПериода: Начиная с версий 8.3.15+, это рекомендуемый режим для получения движений без лишней агрегации по времени. Он работает быстрее, чем «Секунда», так как не требует нормализации времени до секунд.
  • Избегайте лишних полей: В 4-м параметре перечисляйте только те поля, которые реально нужны для группировки. Каждое лишнее измерение увеличивает размер временной таблицы и время выполнения.

Резюме

  1. Для получения регистратора из оборотов обязательно добавьте Регистратор (и желательно Период) в четвертый параметр виртуальной таблицы ОБОРОТЫ.
  2. Используйте периодичность ГраницаПериода или Секунда, чтобы строки не сливались по дням/месяцам.
  3. Применяйте агрегатные функции (СУММА) к ресурсам (Приход/Расход), так как происходит группировка.
  4. Если нужны все строки документа (характеристики, серии, цены) — используйте виртуальную таблицу ДВИЖЕНИЯ с отбором по Регистратор = &Ссылка. Это быстрее и функциональнее.
  5. Для доступа к реквизитам документа (Номер, Дата, Контрагент) используйте точечную навигацию (Регистратор.Номер) или LEFT JOIN с таблицей документов.

Грамотное использование виртуальных таблиц — залог быстрых и надежных отчетов и обработок в 1С:Предприятие 8.3.