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

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

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

Анализ проблемы МоментаВремени

В платформе 1С МоментВремени является уникальным идентификатором, состоящим из даты и ссылки на документ. Если у вас несколько документов имеют одинаковую дату и время, система все равно различает их по ссылке. Но при построении отчета нам нужно не просто формальное различие, а логическое — мы хотим видеть состояние системы после выполнения всех операций в рамках этой секунды.

Решение через использование временных таблиц и самосоединение

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

Для начала, поместим данные из виртуальной таблицы во временную таблицу ОсновнаяЗаГод:


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

Вычисление порядкового номера записи

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


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

Здесь важно отметить: если НомерСтроки равен 0 (или минимальному значению в группе), это означает, что нет записей с более поздним МоментВремени. Следовательно, это и есть наша «последняя» запись.

Финальная выборка данных

На последнем этапе мы соединяем полученный результат с исходными данными, чтобы вытянуть нужные нам суммы:


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

Альтернативные подходы и советы

  1. Оптимизация архитектуры: Если отчеты по депозитам строятся часто, рассмотрите возможность создания регистра сведений, который будет хранить актуальные остатки. Это избавит вас от необходимости пересчитывать ОстаткиИОбороты «на лету».
  2. Оконные функции: Если вы используете современные версии платформы 1С, вместо тяжелого соединения Т1 и Т2 применяйте оконные функции ROW_NUMBER(). Это значительно повысит производительность при большом объеме данных.
  3. Порядок сортировки: При возникновении ситуаций с абсолютно идентичным временем (например, при загрузке данных), используйте Ссылка документа как дополнительный критерий сортировки.

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

← На главную