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

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

1С: как получить остатки по регистратору

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

Задача получить остатки регистра накопления по конкретному регистратору возникает, когда нужно узнать, какое количество или сумма числилась за документом на момент его проведения, либо проверить, что документ «закрыл» позицию полностью. Типичные сценарии — контроль списания партий, проверка остатков по заказу покупателя, анализ расчётов по конкретному документу реализации.

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

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

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

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

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

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

Самый универсальный вариант — обратиться к физической таблице регистра и сгруппировать записи нужного документа. Например, для регистра «ТоварыНаСкладах»:

ВЫБРАТЬ

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

Движения.Склад КАК Склад,

СУММА(ВЫБОР

КОГДА Движения.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)

ТОГДА Движения.Количество

ИНАЧЕ -Движения.Количество

КОНЕЦ) КАК Остаток

ИЗ

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

ГДЕ

Движения.Регистратор = &Регистратор

СГРУППИРОВАТЬ ПО

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

Движения.Склад

Такой запрос возвращает именно «вклад» документа в остатки: сколько каждая строка документа добавила или убавила. Если документ делал только расходные движения, значения будут отрицательными — это нормально, знак отражает направление движения.

Для регистров с ресурсом «Сумма» добавьте аналогичную сумму по второму ресурсу. Если нужны не только остатки по самому документу, но и состояние позиции после его проведения, этот запрос комбинируют с виртуальной таблицей остатков на дату документа.

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

Способ 2: виртуальная таблица «Остатки» с отбором по измерению-документу

Если регистр построен так, что документ является измерением (заказ в «ЗаказыКлиентов», документ расчётов в «РасчетыСКонтрагентамиПоДокументам», партия в партионном учёте), задача решается штатно:

ВЫБРАТЬ

Остатки.ЗаказКлиента,

Остатки.Номенклатура,

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

ИЗ

РегистрНакопления.ЗаказыКлиентов.Остатки(, ЗаказКлиента = &Документ) КАК Остатки

Первый параметр виртуальной таблицы — период остатков (пусто — текущие), второй — условие отбора по измерениям. Отбор накладывается на уровне СУБД до выборки данных, поэтому такой запрос работает быстро даже на больших регистрах.

Чтобы получить остатки на момент проведения конкретного документа, передайте в первый параметр границу: &МоментВремени, где значение — Новый Граница(Документ.МоментВремени(), ВидГраницы.Включая) или дата документа. Это позволяет увидеть, что оставалось «за» документом сразу после или до его проведения.

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

Таблица движений + отбор по Регистратору

Подходит всегда; показывает вклад документа в остатки, но не итоговый остаток позиции

Виртуальная таблица Остатки с отбором по измерению

Быстро и просто, но работает только если документ является измерением регистра

Остатки на момент времени документа

Показывает состояние до/после проведения; требует аккуратной работы с границами

Способ 3: остатки на дату конкретного регистратора

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

ВЫБРАТЬ

Остатки.Номенклатура,

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

ИЗ

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

В коде границу формируют из момента времени документа:

Запрос.УстановитьПараметр("Граница",

Новый Граница(ДокументОбъект.МоментВремени(), ВидГраницы.Исключая));

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

Получение остатков по регистратору через «ОстаткиИОбороты»

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

ВЫБРАТЬ

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

Таб.КоличествоНачальныйОстаток,

Таб.КоличествоПриход,

Таб.КоличествоРасход,

Таб.КоличествоКонечныйОстаток

ИЗ

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

&Начало, &Конец, Регистратор, , Номенклатура = &Номенклатура) КАК Таб

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

Проверка результата и типичные ошибки

После получения данных сверьте их с отчётом «Ведомость по товарам на складах» или универсальным отчётом по регистру за тот же период и с теми же отборами. Совпадение итогов — признак корректного запроса. Расхождение обычно объясняется одной из причин ниже.

Типичные ошибки
01
Отбор «Регистратор = &Документ» в параметре виртуальной таблицы Остатки — поле недопустимо, запрос падает с ошибкой
02
Игнорирование вида движения при суммировании таблицы движений — приход и расход складываются, итог завышен
03
Граница «Включая» вместо «Исключая» при контроле остатков — документ контролирует сам себя, отрицательные остатки проходят
04
Отбор по ссылке документа, когда в измерении хранится другой тип (например, заказ как бизнес-процесс или уточнённый тип) — пустой результат
05
Забытые итоги: регистр с отключёнными итогами или нерассчитанными итогами даёт медленные или неожиданные результаты виртуальных таблиц

Отдельно проверяйте тип параметра: если передаёте список документов, используйте оператор «В (&Список)» и массив ссылок, а не строковое представление. Сравнение ссылки со строкой молча вернёт пустую выборку.

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

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

Сумма по запросу vs отчёт по регистру
Норма

Итоги совпадают с точностью до знака направления движения

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

Расхождение — проверьте вид движения и отборы

Пустая выборка при существующих движениях
Норма

Документ действительно не делал движений по этому регистру

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

Движения есть в карточке документа — проверьте тип параметра и имя регистра

Остатки на момент документа
Норма

Значения совпадают с отчётом на ту же дату и время

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

Сдвиг на величину движений документа — неверный режим границы

Когда стоит привлечь разработчика

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

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

Итог

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

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

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

Почему в виртуальной таблице «Остатки» нельзя отобрать по регистратору?

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

Как получить остатки сразу по нескольким документам?

Передайте массив ссылок в параметр и используйте условие «Регистратор В (&СписокДокументов)» в запросе к таблице движений с группировкой по полю «Регистратор» и измерениям. Для виртуальных таблиц с измерением-документом работает тот же оператор «В».

Чем отличается результат по таблице движений от виртуальной таблицы «Остатки»?

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

Как учесть, что документ мог быть отменён или перепроведён?

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

Можно ли получить остатки по регистратору в отчёте на СКД без кода?

Да. В наборе данных СКД напишите тот же запрос к таблице движений с отбором по регистратору, а ссылку на документ вынесите в параметр отчёта. Для измерений-документов достаточно стандартной виртуальной таблицы «Остатки» с отбором в настройках отчёта.