Движения документа в накопительном регистре 1С: отчёты, запросы и код

· 9 мин

Содержание

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

Сразу уточним термин, иначе запрос вернёт не то. Остатки — это накопленное состояние на дату, и они не принадлежат одному документу. А вот движения и обороты по регистратору получить можно: это приход и расход, которые конкретный документ записал в регистр. Дальше разберём все рабочие способы — от стандартного отчёта до запроса и встроенного языка — и покажем, где новички ошибаются.

Что такое остатки, обороты и регистратор в регистре накопления

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

  • 🟢 Остатки — хранят состояние: сколько сейчас на складе. Доступны виртуальные таблицы Остатки, Обороты, ОстаткиИОбороты.
  • 🔵 Обороты — хранят только движения за период, остатка как такового нет. Виртуальная таблица одна — Обороты.

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

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

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

Как посмотреть движения по регистратору без программирования

Если задача разовая — не пишите запрос, хватит стандартных инструментов.

Способ 1. Движения из карточки документа. Откройте документ и найдите в верхней командной панели команду показа движений (в типовых конфигурациях на «Такси» она лежит в меню Ещё или на отдельной кнопке отчёта по движениям). Откроется список регистров, которые затронул документ, и записанные в каждый из них строки. Это самый быстрый ответ на вопрос «что этот документ сделал с остатками».

Способ 2. Универсальный отчёт. Подходит, когда нужно собрать движения сразу по нескольким документам или отобрать по другим полям. Путь в типовых конфигурациях: Отчёты → Универсальный отчёт (в разных конфигурациях раздел меню может называться по-разному, сам отчёт — стандартный).

Порядок настройки:

  1. В шапке выберите тип источника — Регистр накопления — и нужный регистр (например, ТоварыНаСкладах).
  2. Таблицу укажите Основная (не «Остатки» и не «Обороты») — только в ней есть регистратор.
  3. Откройте настройки и добавьте в Отборы поле Регистратор, задайте условие «Равно» и выберите документ.
  4. В строки/колонки вытащите измерения и ресурсы: номенклатуру, склад, количество, вид движения.
  5. Сформируйте отчёт.

В таблицах «Остатки» и «Обороты» универсального отчёта поля Регистратор не будет — его хранит только основная таблица. Если регистратор не появился в списке полей, вы выбрали не ту таблицу.

Запрос к движениям регистра с отбором по регистратору

Самый точный способ — запрос. Собрать и проверить его удобно в обработке Консоль запросов (внешняя обработка, её открывают через Файл → Открыть) или в конструкторе запроса в Конфигураторе.

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

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

В параметр &Регистратор передают ссылку на документ. Поле ВидДвижения для регистра вида «Остатки» принимает два значения — ВидДвиженияНакопления.Приход и ВидДвиженияНакопления.Расход; по нему видно, что документ добавил, а что списал.

Если нужны движения всех документов одного вида за период, отбор меняют на тип и дату:

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

Так вы получите, насколько каждый документ сдвинул остаток за период: плюс — чистый приход, минус — чистый расход.

Обороты по регистратору: приход, расход и детализация

У виртуальной таблицы Обороты есть параметр Периодичность, и одно из его значений — Регистратор. С ним таблица добавляет поле регистратора и группирует обороты по документам. Это штатный способ получить «обороты по регистратору» без ручной группировки основной таблицы:

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

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

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

Сравним, когда что брать:

Что нужноОткуда братьПоле регистратора
Движения одного документаОсновная таблица, отбор Регистратор = &Докесть
Обороты всех документов за периодОбороты(…, Регистратор, )есть
Остаток на датуОстатки(&Дата, …)❌ нет, остаток не по документу
Остаток и оборот вместеОстаткиИОбороты(…)❌ нет

Если от вас хотят «остаток склада на момент документа», берут Остатки с параметром «Период» = момент времени документа (МоментВремени() или граница по регистратору). Но это остаток склада, а не остаток «по регистратору» — документ в выборке не фигурирует.

Детализация: номер строки, активность и момент времени

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

  • 🔢 НомерСтроки — порядок записей внутри одного регистратора. По нему восстанавливают, в какой последовательности документ писал движения, и сопоставляют строки регистра со строками табличной части документа.
  • ✅ Активность — флаг, участвует ли запись в расчёте остатков. Непроведённый или помеченный документ может оставить неактивные движения. Если «остаток не сходится», проверьте Активность = ИСТИНА в отборе — неактивные строки в остатки не попадают, но в основной таблице лежат.
  • ⏱ Период — дата и время движения. У большинства документов совпадает с датой документа, но у ручных операций и корректировок может отличаться.

Пример отбора только активных движений документа с сортировкой по строкам:

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

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

Диагностика: выберите симптом

Получение движений документа во встроенном языке 1С

В коде движения уже проведённого документа читают через набор записей. Это удобно в обработках проведения, проверках и обменах:

НаборДвижений = Документ.Движения.ТоварыНаСкладах;
НаборДвижений.Прочитать();

Для Каждого Строка Из НаборДвижений Цикл
    Сообщить(СтрШаблон("%1 — %2: %3",
        Строка.ВидДвижения,
        Строка.Номенклатура,
        Строка.Количество));
КонецЦикла;

Здесь Документ — объект документа (ДокументОбъект), а Движения.ТоварыНаСкладах — набор записей регистра. Метод Прочитать() поднимает записи из базы; без него набор будет пустым, если движения не формировались в этой же транзакции. Число в сообщение подставляем через СтрШаблон — он сам приводит типы, вручную склеивать число со строкой не нужно.

Когда документа на руках нет, а есть только ссылка, берут запрос по основной таблице (код из раздела выше) и выполняют его через объект Запрос:

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

Пока Выборка.Следующий() Цикл
    // обработка Выборка.Номенклатура, Выборка.Количество
КонецЦикла;

Оба подхода дают одно и то же, но набор записей работает по объекту документа, а запрос — по ссылке и в контексте любого кода.

Производительность: как не затормозить на больших базах

На базе с миллионами движений важно, по какому полю идёт отбор.

  • 📌 Отбор по регистратору — быстрый. Регистратор входит в индекс основной таблицы, поэтому выборка движений одного документа отрабатывает мгновенно даже на большом регистре.
  • 📌 Обороты с периодичностью Регистратор за широкий период — тяжёлые. Система разворачивает обороты по каждому документу. Всегда ограничивайте период и, если можно, добавляйте условие по измерению (склад, номенклатура) в четвёртый параметр виртуальной таблицы.
  • 📌 Не выбирайте лишние поля. ВЫБРАТЬ * и неиспользуемые ресурсы заставляют читать больше данных. Берите только нужные колонки.
  • 📌 Условие — в параметры виртуальной таблицы, а не в ГДЕ. Отбор, записанный в последний параметр Обороты(…, …, Регистратор, Склад = &Склад), применяется до агрегации и работает быстрее, чем ГДЕ поверх развёрнутой таблицы.

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

Что именно вам нужно получить по документу?

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

Почему запрос к таблице «Остатки» с отбором по регистратору ничего не возвращает?
Потому что в виртуальной таблице Остатки поля Регистратор нет. Остаток — это накопленное состояние, не привязанное к документу. Движения документа берут из основной таблицы или из Обороты с периодичностью Регистратор.
Чем отличается основная таблица регистра от виртуальной?
Основная (физическая) таблица хранит все записи с полями Период, Регистратор, ВидДвижения. Виртуальные (Остатки, Обороты, ОстаткиИОбороты) рассчитываются на лету и регистратора, как правило, не содержат — исключение только обороты с периодичностью Регистратор.
Как получить одновременно приход, расход и регистратор?
Используйте виртуальную таблицу Обороты(&Начало, &Конец, Регистратор, ) — она отдаёт КоличествоПриход, КоличествоРасход, КоличествоОборот в разрезе документов.
Можно ли узнать остаток на момент конкретного документа?
Да, но это остаток склада, а не «по регистратору». Передайте в параметр «Период» таблицы Остатки момент времени документа. Сам документ в результат не попадёт — вы получите состояние регистра на эту секунду.
Где посмотреть движения документа, не открывая Конфигуратор?
Откройте документ в режиме Предприятие и вызовите показ движений из командной панели (в типовых конфигурациях команда лежит в меню Ещё), либо постройте Универсальный отчёт по основной таблице регистра с отбором по регистратору.