Остатки, Обороты, ОстаткиИОбороты

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

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

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

Остаток отвечает на вопрос «сколько есть на момент времени». Оборот — «сколько прошло за период». Остаток — это фотография на дату; оборот — это видео за интервал.

Зачем это нужно на практике

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

Вид регистра: остатки и обороты

Не у каждого регистра накопления есть все три таблицы. Регистры бывают двух видов:

  • Регистр остатков (например, ТоварыНаСкладах) — имеет все три виртуальные таблицы: Остатки, Обороты, ОстаткиИОбороты. Логично: у товара есть и текущий остаток, и движение.
  • Регистр оборотов (например, Продажи) — имеет только Обороты. У продаж нет «остатка»: продажа — это событие, оно не «лежит на складе».

Остатки: сколько есть на дату

Виртуальная таблица РегистрНакопления.ТоварыНаСкладах.Остатки(<Период>, <Отбор>) возвращает сальдо ресурсов на указанный момент. Ресурсы в ней получают суффикс Остаток: у ресурса Количество поле будет называться КоличествоОстаток.

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

Если Период не указать — Остатки() — вернётся остаток на текущий момент. Именно так строится отчёт «остатки на складе прямо сейчас».

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

Запрос.УстановитьПараметр("НаДату", КонецДня(ТекущаяДата()));
Запрос.УстановитьПараметр("Склад", ОсновнойСклад);

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(Выборка.Номенклатура.Наименование + ": " + Выборка.Количество);
КонецЦикла;

Результат:

Смартфон Alpha: 14
Ноутбук Beta: 3
Мышь Gamma: 220

Условие КоличествоОстаток > 0 здесь уместно в ГДЕ — оно отсекает нулевые остатки уже после расчёта итога (по остатку фильтруют именно так, отбор по измерениям — в параметрах таблицы).

Обороты: сколько прошло за период

Виртуальная таблица РегистрНакопления.Продажи.Обороты(<НачалоПериода>, <КонецПериода>, <Периодичность>, <Отбор>) суммирует движения за интервал. У Оборотов уже два параметра периода — начало и конец. Ресурсы получают суффикс Оборот: КоличествоКоличествоОборот, СуммаСуммаОборот.

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

Это отчёт «что продавалось за март»: сколько штук ушло и на какую сумму. Обороты нельзя заменить остатками — остаток покажет лишь то, что лежит, а не то, что прошло.

Периодичность оборотов

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

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

Без периодичности (пустой параметр) обороты сворачиваются в одну итоговую строку на всю комбинацию измерений за весь интервал.

ОстаткиИОбороты: всё в одной строке

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

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

Одним запросом — вся динамика: было, пришло, ушло, стало. Проверить себя легко: НачальныйОстаток + Приход − Расход = КонечныйОстаток.

Как это работает

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

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

Частые ошибки

  • Считать остаток через сумму движений вручную. Новички пишут запрос к «основной» таблице движений регистра и складывают приход с расходом сами. Это медленно и мимо итогов. Для остатка есть таблица Остатки — используйте её.
  • Путать суффиксы ресурсов. В Остатках поле называется КоличествоОстаток, в Оборотах — КоличествоОборот, в ОстаткахИОборотах — КоличествоНачальныйОстаток/КоличествоКонечныйОстаток и т. д. Просто Количество в виртуальной таблице нет — конструктор запроса подскажет доступные поля.
  • Искать Остатки у регистра оборотов. У регистра вида «обороты» (Продажи, Выручка) таблиц Остатки и ОстаткиИОбороты нет — только Обороты. Это не баг: у продажи нет остатка.
  • Один параметр периода у Оборотов. У Остатков период один (момент), у Оборотов — два (начало и конец). Передать в Обороты только одну дату — типичная ошибка новичка.
  • Границы периода без учёта времени. КонецМесяца в 1С возвращает последнюю секунду месяца (23:59:59), а НачалоМесяца — 00:00:00 первого дня. Если брать «конец периода» как '20240331' (то есть 00:00:00), потеряете движения за весь последний день. Пользуйтесь функциями НачалоМесяца()/КонецМесяца().

Итоги

  • Регистр накопления отдаёт данные тремя виртуальными таблицами: Остатки, Обороты, ОстаткиИОбороты.
  • Остатки — «сколько есть на момент» (один параметр — Период); Обороты — «сколько прошло за интервал» (два параметра — начало и конец).
  • ОстаткиИОбороты — начальный остаток, приход, расход и конечный остаток в одной строке.
  • Ресурсы получают суффиксы: ...Остаток, ...Оборот, ...НачальныйОстаток, ...КонечныйОстаток.
  • Регистр оборотов (Продажи) имеет только Обороты; остатки у него отсутствуют по смыслу.
Проверьте себя
1. Нужен отчёт «сколько денег поступило в кассу за март». Какую виртуальную таблицу регистра накопления брать?
AОстатки — она покажет движение за март
BОбороты — она суммирует движения (поступления) за период
CСрезПоследних — она вернёт последнее поступление
DНикакую: движения за период из регистра получить нельзя
2. Чем отличается набор параметров периода у таблиц Остатки и Обороты?
AУ обеих один параметр — дата
BУ Остатков один параметр (момент/Период), у Оборотов два — начало и конец периода
CУ Остатков два параметра, у Оборотов один
DНи у одной параметров периода нет