Поле Регистратор в запросах к регистрам 1С
Содержание
Регистратор лежит в таблице движений самого регистра: обращаетесь к ней как РегистрНакопления.ИмяРегистра и берёте поле Регистратор. В виртуальных таблицах остатков этого поля нет — оно появляется только в таблице записей и в оборотах с периодичностью по регистратору.
Регистратор — это ссылка на документ, который сделал запись в регистре. Почти всегда это составной тип: один регистр пишут несколько видов документов. Поэтому получить прикладные реквизиты документа «через точку» напрямую нельзя — нужны ВЫРАЗИТЬ и оператор ССЫЛКА. Ниже — где поле доступно, как по нему фильтровать и группировать и как не посадить запрос на десяток лишних соединений.
Разница между подходами важна на объёмных регистрах. Прямое обращение к составному регистратору собирает соединения со всеми таблицами-документами, а приведение типа оставляет ровно одно. На регистре, который пишут десять видов документов, это разница между десятью LEFT JOIN и одним.
Что такое регистратор и в каких регистрах он есть
Регистратор — служебное поле, в котором хранится ссылка на документ-источник движения. По нему платформа понимает, какую запись удалить при перепроведении и какие движения показать в структуре подчинённости.
Поле есть не везде:
- 🔹 Регистры накопления — регистратор обязателен всегда, движения делает только документ.
- 🔹 Регистры бухгалтерии — так же, записи формирует документ-регистратор.
- 🔹 Регистры сведений — только если в свойствах регистра
Режим записи=Подчинение регистратору. У независимых регистров сведений регистратора нет, там запись ведётся вручную или обработкой. - 🔹 Регистры расчёта — регистратор есть, движения привязаны к документу начисления.
Рядом с регистратором в таблице записей всегда лежит НомерСтроки — вместе они образуют уникальный ключ строки движения. У периодических регистров добавляется Период.
Как выбрать регистратор: базовый синтаксис
Обращаетесь к основной (физической) таблице регистра — без суффикса виртуальной таблицы. Поле Регистратор доступно в списке колонок напрямую.
ВЫБРАТЬ
ТоварыНаСкладах.Регистратор КАК Регистратор,
ТоварыНаСкладах.Период КАК Период,
ТоварыНаСкладах.Номенклатура КАК Номенклатура,
ТоварыНаСкладах.Количество КАК Количество,
ТоварыНаСкладах.ВидДвижения КАК ВидДвижения
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
Для регистра бухгалтерии таблица движений называется так же — РегистрБухгалтерии.Хозрасчетный, поле Регистратор на месте. Для регистра сведений с подчинением регистратору:
ВЫБРАТЬ
ЦеныНоменклатуры.Регистратор КАК Регистратор,
ЦеныНоменклатуры.Период КАК Период,
ЦеныНоменклатуры.Номенклатура КАК Номенклатура,
ЦеныНоменклатуры.Цена КАК Цена
ИЗ
РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
Рядом с регистратором доступно поле НомерСтроки — порядковый номер строки движения внутри набора записей документа. НомерСтроки движения не обязан совпадать с номером строки табличной части документа: записи в регистр добавляются программно в обработке проведения, и порядок может отличаться. Поэтому связывать движения с табличной частью документа по НомерСтроки напрямую нельзя — для этого в движение записывают отдельное измерение-ключ.
Если в конструкторе запроса (Запрос → Конструктор запроса или Ctrl+Q в модуле) в списке полей регистра нет Регистратор, значит вы выбрали виртуальную таблицу остатков либо регистр сведений без подчинения. Переключитесь на основную таблицу регистра.
В каких таблицах регистратора нет
Главная ловушка новичка — искать регистратор в остатках. В агрегированных таблицах его физически быть не может: остаток складывается из движений многих документов, одной ссылки там нет.
Где регистратор есть и где его нет:
| Таблица | Регистратор | Пояснение |
|---|---|---|
| Основная таблица записей | ✅ есть | строка движения привязана к документу |
.Остатки | ❌ нет | агрегат на момент времени |
.Обороты без периодичности | ❌ нет | сумма за период |
.Обороты(, , Регистратор, ) | ✅ есть | обороты в разрезе документов |
.ОстаткиИОбороты с периодичностью Регистратор | ✅ появляется в оборотной части | |
.СрезПоследних / .СрезПервых | ✅ есть (если регистр подчинён регистратору) | возвращает документ последней записи |
Чтобы получить обороты по каждому документу, укажите периодичность третьим параметром виртуальной таблицы оборотов:
ВЫБРАТЬ
Обороты.Регистратор КАК Регистратор,
Обороты.Номенклатура КАК Номенклатура,
Обороты.КоличествоОборот КАК КоличествоОборот
ИЗ
РегистрНакопления.ТоварыНаСкладах.Обороты(, , Регистратор, ) КАК Обороты
Параметры оборотов идут в порядке (НачалоПериода, КонецПериода, Периодичность, Условие). Пустые позиции оставляете запятыми, периодичность задаёте словом Регистратор.
РегистрНакопления.Имя. Поле Регистратор и НомерСтроки доступны сразу..Обороты(, , Регистратор, )..СрезПоследних() — вернёт регистратор последней записи, если регистр подчинён документу.Регистратор в регистрах бухгалтерии и расчёта
Логика одинаковая во всех типах регистров, но имена таблиц и соседние поля отличаются.
Регистр бухгалтерии. Основная таблица движений РегистрБухгалтерии.Хозрасчетный содержит Регистратор, Период, Активность, Сумма, счета и субконто. Регистратор доступен в ней напрямую, а также в виртуальной таблице ДвиженияССубконто:
ВЫБРАТЬ
Проводки.Регистратор КАК Регистратор,
Проводки.СчетДт КАК СчетДт,
Проводки.СчетКт КАК СчетКт,
Проводки.Сумма КАК Сумма
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Проводки
ГДЕ
Проводки.Активность = ИСТИНА
Поле Активность показывает, учитывается ли запись в итогах. Неактивные записи остаются в таблице, но не влияют на остатки — фильтр по Активность = ИСТИНА отсекает их.
Регистр расчёта. Движения привязаны к документу-регистратору, рядом лежат ПериодРегистрации и период действия. Регистратор берут из основной таблицы так же, как в регистре накопления. В виртуальных таблицах данных графика и базы регистратора нет — там результат уже агрегирован.
В конструкторе запроса тип регистра виден по имени таблицы: РегистрНакопления., РегистрБухгалтерии., РегистрСведений., РегистрРасчета.. Поле Регистратор ищите в ветке с именем регистра без суффикса виртуальной таблицы.
Фильтрация и группировка по регистратору
Отобрать движения одного документа — прямое сравнение в ГДЕ. Удобно передавать ссылку параметром запроса:
ВЫБРАТЬ
Движения.Номенклатура КАК Номенклатура,
Движения.Количество КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Движения
ГДЕ
Движения.Регистратор = &Документ
Группировка по регистратору собирает итоги по каждому документу — например, суммарное количество по приходным документам:
ВЫБРАТЬ
Движения.Регистратор КАК Регистратор,
СУММА(Движения.Количество) КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Движения
СГРУППИРОВАТЬ ПО
Движения.Регистратор
Чтобы отобрать только определённый вид документа, не перечисляя ссылки, используйте оператор ССЫЛКА — он проверяет тип значения составного поля:
ВЫБРАТЬ
Движения.Регистратор КАК Регистратор,
Движения.Количество КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Движения
ГДЕ
Движения.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг
ССЫЛКА работает по индексу типа и не тянет данные самого документа — это дешёвая операция.
Как найти документы, сделавшие записи в регистре
Отдельная частая задача — узнать, какие документы вообще двигали регистр по конкретному объекту. Например, какими документами менялся остаток по номенклатуре или по счёту. Собирают список уникальных регистраторов:
ВЫБРАТЬ РАЗЛИЧНЫЕ
Движения.Регистратор КАК Регистратор
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Движения
ГДЕ
Движения.Номенклатура = &Номенклатура
И Движения.Период МЕЖДУ &Начало И &Конец
УПОРЯДОЧИТЬ ПО
Движения.Регистратор.Дата
РАЗЛИЧНЫЕ убирает повторы, если документ сделал несколько строк движений. Сортировка по дате регистратора выстраивает документы в хронологии — удобно при разборе расхождений в остатках.
Если список регистраторов нужно сопоставить с данными документов, не тяните реквизиты в этом же запросе через составной тип. Сначала получите ссылки, затем во втором запросе (или в коде) обработайте их по типам. Так вы не нагружаете выборку лишними соединениями.
Регистратор как составной тип: ВЫРАЗИТЬ и ССЫЛКА
Когда регистр пишут несколько видов документов, поле Регистратор имеет составной тип. Написать Движения.Регистратор.Дата формально можно, но платформа соберёт LEFT JOIN ко всем таблицам документов-регистраторов сразу. На десяти видах документов это десять соединений на ровном месте.
Приводите составной тип к конкретному документу через ВЫРАЗИТЬ — тогда соединение будет только с одной таблицей.
ВЫБРАТЬ
ВЫРАЗИТЬ(Движения.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Контрагент КАК Контрагент,
ВЫРАЗИТЬ(Движения.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Склад КАК Склад,
Движения.Количество КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Движения
ГДЕ
Движения.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг
Если видов документов несколько, берут реквизит с одинаковым именем через вложенный выбор по типам. Общий приём: сначала фильтруете движения по ССЫЛКА, потом ВЫРАЗИТЬ достаёт нужный реквизит именно из этой таблицы.
Когда нужен только тип документа (а не конкретный реквизит), пригодятся:
- 🔸
ТИПЗНАЧЕНИЯ(Движения.Регистратор)— вернёт тип, можно сравнивать сТИП(Документ.ПоступлениеТоваровУслуг). - 🔸 оператор
ССЫЛКА— короче и читается лучше в условиях отбора.
Для отчёта удобно вывести тип документа текстом. Это делает ВЫБОР с проверкой через ССЫЛКА — платформа подставит читаемую подпись вместо ссылки:
ВЫБРАТЬ
ВЫБОР
КОГДА Движения.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг ТОГДА "Поступление"
КОГДА Движения.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг ТОГДА "Реализация"
ИНАЧЕ "Прочее"
КОНЕЦ КАК ВидДокумента,
Движения.Количество КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Движения
ВЫРАЗИТЬ(Регистратор КАК Документ.X).Реквизит вернёт NULL для строк, где регистратор — документ другого типа. Либо отфильтруйте такие строки через ССЫЛКА, либо оберните результат в ЕСТЬNULL.
Получение реквизитов документа-регистратора
Частая задача — вывести вместе с движениями дату, номер и контрагента документа. Дата и номер есть у любой ссылки на документ, поэтому их можно брать без приведения типа — у стандартных полей ссылки соединение лёгкое:
ВЫБРАТЬ
Движения.Регистратор КАК Регистратор,
Движения.Регистратор.Дата КАК ДатаДокумента,
Движения.Количество КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Движения
А вот прикладные реквизиты (контрагент, склад, организация) у каждого вида документа свои, поэтому они доступны только после ВЫРАЗИТЬ с указанием конкретного документа. Если реквизит с одним именем есть у всех регистраторов, его собирают из нескольких ВЫРАЗИТЬ через ЕСТЬNULL:
ВЫБРАТЬ
ЕСТЬNULL(
ВЫРАЗИТЬ(Движения.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Организация,
ВЫРАЗИТЬ(Движения.Регистратор КАК Документ.РеализацияТоваровУслуг).Организация
) КАК Организация,
Движения.Количество КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Движения
Так вы соединяетесь ровно с двумя таблицами документов вместо всех возможных.
Оптимизация запросов к регистратору
Регистратор участвует в ключе таблицы движений, поэтому отбор и соединение по нему проходят по индексу и работают быстро. Платформа сама хранит записи регистра упорядоченными по регистратору — выбрать все движения одного документа почти бесплатно. Проблемы начинаются не от самого поля, а от того, как достают данные документа и как обращаются к составному типу.
Что ускоряет запрос:
- Приводите составной тип через
ВЫРАЗИТЬ. Каждое обращение «через точку» к составному регистратору без приведения — это соединение со всеми таблицами-регистраторами. ОдинВЫРАЗИТЬоставляет одно соединение. - Фильтруйте тип через
ССЫЛКАвГДЕ. Это отсекает лишние строки до соединений, а не после. - Передавайте регистратор параметром, а не подзапросом, если документ уже известен в коде.
- Не группируйте по составному регистратору без нужды — группировка по ссылке дешевле, чем по вычисленным реквизитам документа.
- Для оборотов по документам используйте периодичность
Регистраторв виртуальной таблице, а не самостоятельную группировку физической таблицы — платформа посчитает агрегаты оптимальнее.
Проверить реальный план можно через технологический журнал или замер производительности (Отладка → Замер производительности в конфигураторе). Строки с массовыми LEFT JOIN по регистратору — первый кандидат на ВЫРАЗИТЬ.
Отдельно стоит помнить про отборы по дополнительным измерениям. Если вы фильтруете движения не только по регистратору, но и по номенклатуре, складу или счёту, убедитесь, что это измерение проиндексировано в свойствах регистра — иначе платформа читает всю таблицу движений, и выигрыш от ключа по регистратору теряется.
Почему в виртуальной таблице остатков нет поля Регистратор?
Как в запросе отобрать движения только одного вида документа?
ССЫЛКА: ГДЕ Движения.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг. Он проверяет тип составного поля по индексу и не читает сам документ.Можно ли получить реквизит документа прямо через точку от регистратора?
ВЫРАЗИТЬ(Регистратор КАК Документ.Имя).Реквизит, иначе платформа соединится со всеми таблицами регистраторов.Есть ли регистратор у регистра сведений?
Регистратор нет.Как получить обороты в разрезе документов?
Регистратор в виртуальной таблице оборотов: РегистрНакопления.Имя.Обороты(, , Регистратор, ). В результат добавятся поля Регистратор и Период.