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

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

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

Понимание работы виртуальной таблицы остатков

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

Рассмотрим классический пример запроса к регистру накопления:


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

Как правильно указывать период выборки

Для того чтобы получить остатки на конкретную дату, мы должны передать параметр &Период. Существует несколько способов корректного формирования этого значения.

Способ 1: Использование даты

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


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

Способ 2: Использование объекта Граница

Для более точного контроля включения или исключения движений, произошедших в ту же секунду, используйте объект Граница. Это критически важно, если у вас в одну секунду происходит запись нескольких документов, и вам нужно четко определить, учитывать последний из них или нет.

Создание границы выглядит следующим образом:


МоментВремени = Новый Граница(КонецДня(ТекущаяДата()), ВидГраницы.Включая);
Запрос.УстановитьПараметр("КонецПериода", МоментВремени);

Использование ВидГраницы.Включая гарантирует, что все движения, попавшие в указанную секунду, будут включены в расчет остатка. Если же вам нужно получить остаток на начало дня, вы можете использовать НачалоДня(Дата), что эквивалентно 00:00:00.

Почему не стоит искать «Срез последних»

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

Основные советы для эффективной работы:

  1. Всегда указывайте параметр периода в виртуальной таблице Остатки.
  2. Для получения остатков сразу после конкретного документа используйте его МоментВремени — это самый надежный способ избежать ошибок с секундами.
  3. При использовании КонецДня помните о границах: если вам нужны остатки на начало 1 мая, используйте НачалоДня(Дата("20260501")).
  4. Следите за актуальностью итогов регистра, так как виртуальные таблицы опираются именно на них. Если итоги не рассчитаны, запрос будет работать крайне медленно.

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

← На главную