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

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

1С: как в запросе указать регистратор документа

Как указать регистратор документа в запросе 1С: отбор по регистратору, получение регистратора из движений, соединение с таблицей документов и типичные ошибки.

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

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

Ниже разобраны основные приёмы: фильтрация по регистратору, вывод реквизитов документа, сравнение типов регистратора, использование виртуальных таблиц и проверка результата запроса.

Отбор движений по регистратору

Самая частая задача — получить движения конкретного документа. Для этого в запросе к физической таблице регистра добавляется условие по полю Регистратор:

ВЫБРАТЬ

ТоварыНаСкладах.Номенклатура,

ТоварыНаСкладах.Количество

ИЗ

РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

ГДЕ

ТоварыНаСкладах.Регистратор = &Регистратор

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

Запрос.УстановитьПараметр("Регистратор", ДокументСсылка);

Важно, чтобы тип параметра совпадал с типом значения в поле: если передать в параметр строку или структуру вместо ссылки, запрос вернёт пустой результат без сообщения об ошибке. Перед установкой параметра полезно убедиться, что переменная содержит именно ссылку (например, через ТипЗнч() при отладке).

Получение реквизитов документа через регистратор

Когда в отчёте по движениям нужно показать номер или дату документа, реквизиты получают «через точку» от поля Регистратор:

ВЫБРАТЬ

Продажи.Регистратор КАК Документ,

Продажи.Регистратор.Номер КАК НомерДокумента,

Продажи.Регистратор.Дата КАК ДатаДокумента

ИЗ

РегистрНакопления.Продажи КАК Продажи

Здесь есть ограничение: поле Регистратор имеет составной тип, и платформа неявно соединяет запись со всеми таблицами документов, которые могут быть регистраторами этого регистра. Если регистраторов несколько десятков типов, запрос заметно замедляется.

Более управляемый вариант — явное соединение с таблицей конкретного вида документа:

ВЫБРАТЬ

Продажи.Номенклатура,

Продажи.Количество,

РеализацияТоваров.Контрагент

ИЗ

РегистрНакопления.Продажи КАК Продажи

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК РеализацияТоваров

ПО Продажи.Регистратор = РеализацияТоваров.Ссылка

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

Отбор по типу регистратора

Если движения регистра формируют несколько видов документов, а нужны движения только одного вида, применяют функцию ТИПЗНАЧЕНИЯ() или оператор ВЫРАЗИТЬ:

ВЫБРАТЬ

Остатки.Регистратор,

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

ИЗ

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

ГДЕ

ТИПЗНАЧЕНИЯ(Остатки.Регистратор) = ТИП(Документ.ПриходнаяНакладная)

Альтернатива — приведение типа с последующим сравнением на неравенство NULL:

ГДЕ

НЕ ВЫРАЗИТЬ(Остатки.Регистратор КАК Документ.ПриходнаяНакладная) ЕСТЬ NULL

Оба варианта рабочие, но проверка через ТИПЗНАЧЕНИЯ обычно читается проще. Если такой отбор нужен постоянно и выполняется по большой таблице, надёжнее соединение с таблицей документа — оно использует индекс по ссылке, а не проверку типа каждой строки.

Сравнение вариантов

ГДЕ Регистратор = &Регистратор

Подходит для отбора движений одного документа. Самый быстрый вариант, использует индекс.

Регистратор.Реквизит через точку

Удобно для быстрого вывода номера и даты, но при составном типе создаёт неявные соединения со всеми видами регистраторов.

Соединение с Документ.Вид

Оптимально, когда нужны реквизиты конкретного вида документа и отбор по типу одновременно.

ТИПЗНАЧЕНИЯ(Регистратор)

Подходит для фильтрации по типу без соединения, но не использует индекс и медленнее на больших таблицах.

Регистратор в виртуальных таблицах

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

ВЫБРАТЬ

Обороты.Регистратор,

Обороты.Номенклатура,

Обороты.КоличествоОборот

ИЗ

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

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

Типичные ошибки
01
Попытка выбрать Регистратор из виртуальной таблицы Остатки — поля там нет, запрос не выполнится; используйте физическую таблицу или Обороты с периодичностью Регистратор.
02
Передача в параметр значения другого типа (строка, Неопределено) вместо ссылки — запрос молча возвращает пустой результат.
03
Сравнение Регистратор = &Параметр, где параметр — массив, вместо условия Регистратор В (&Список) — для списка документов нужен оператор В.
04
Обращение Регистратор.Реквизит при десятках типов регистраторов — неявные соединения резко замедляют запрос.

Отбор по списку регистраторов и по реквизиту документа

Когда нужно получить движения сразу нескольких документов, параметр передаётся списком значений или массивом, а условие строится через оператор В:

ГДЕ

Движения.Регистратор В (&СписокДокументов)

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

ВЫБРАТЬ

Движения.Номенклатура,

Движения.Количество,

Реализация.Ссылка КАК Документ

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи КАК Движения

ПО Движения.Регистратор = Реализация.Ссылка

ГДЕ

Реализация.Контрагент = &Контрагент

Такой порядок позволяет серверу сначала сузить выборку по индексированным полям документа и только потом подтягивать движения, что заметно быстрее, чем фильтрация движений через разыменование Регистратор.Контрагент.

Проверка результата и отладка

Проверять запросы с регистратором удобно в консоли запросов на копии базы или в режиме предприятия на тестовом документе. Контрольные признаки корректной работы: количество строк совпадает с числом движений документа (его можно увидеть через «Ещё → Движения документа» в форме документа), реквизиты регистратора заполнены и соответствуют документу.

Если запрос вернул пустой результат, проверьте по порядку: проведён ли документ и есть ли у него движения по этому регистру; того ли типа параметр (ссылка, а не строковое представление); верно ли указано имя регистра — документ может делать движения по другому регистру с похожим названием.

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

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

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

Число строк результата
Норма

Совпадает с количеством движений документа в форме «Движения документа»

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

Пусто или строк больше, чем движений — проверяйте параметр и условия

Реквизиты регистратора
Норма

Номер, дата и другие поля соответствуют документу

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

Поля пустые — соединение не сработало или документ другого вида

Типы документов в выборке
Норма

Присутствуют только нужные виды документов

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

Лишние виды — добавьте отбор по ТИПЗНАЧЕНИЯ или внутреннее соединение

Частые вопросы

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

Напрямую поле Регистратор в параметрах виртуальных таблиц недоступно. Для таблицы Обороты можно задать периодичность «Регистратор», тогда поле появится в результате. Для отбора движений документа используйте физическую таблицу регистра с условием ГДЕ Регистратор = &Регистратор.

Почему условие Регистратор = &Регистратор возвращает пустой результат?

Наиболее вероятные причины: параметр передан не ссылкой (например, строкой или Неопределено), документ не проведён либо не формирует движений по данному регистру. Проверьте тип параметра через ТипЗнч() и наличие движений в форме документа.

Как вывести номер документа-регистратора в отчёте?

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

Чем отличается Регистратор от ДокументСсылка в запросе?

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

Как отобрать движения только приходных накладных, если регистраторов несколько видов?

Используйте условие ТИПЗНАЧЕНИЯ(Регистратор) = ТИП(Документ.ПриходнаяНакладная) либо внутреннее соединение с таблицей Документ.ПриходнаяНакладная по равенству Регистратор = Ссылка. Второй вариант обычно быстрее на больших таблицах.

Можно ли по регистратору получить движения документа по всем регистрам сразу?

Одним запросом — только через объединение (ОБЪЕДИНИТЬ ВСЕ) запросов к каждому нужному регистру с условием по регистратору. Универсального механизма «все движения документа» в языке запросов нет; встроенными средствами список регистров документа виден в форме «Движения документа».

Итог

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

Регистратор — ссылка на документ в таблице движений регистра. Для отбора используйте ГДЕ Регистратор = &Регистратор со ссылкой в параметре, для реквизитов документа — соединение с таблицей документа, для фильтрации по виду — ТИПЗНАЧЕНИЯ. Избегайте обращений Регистратор.Реквизит при большом числе типов регистраторов и всегда проверяйте результат на тестовом документе.