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