Как получить последний статус объекта и почему регистр накопления для этого не подходит?

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

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

Ограничения платформы: почему регистр накопления не подходит

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

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

Оптимальное решение: Периодический регистр сведений

Выясним, как правильно реализовать задачу на уровне метаданных. Для хранения истории изменения состояний объектов необходимо использовать периодический регистр сведений (например, подчиненный регистратору или с периодичностью в пределах секунды).

Именно периодичность дает доступ к главной платформенной виртуальной таблице для подобных задач — СрезПоследних. При построении отчета ваш запрос должен обращаться именно к ней.

Рассмотрим важное правило оптимизации: чтобы отчет работал быстро, фильтр по нужному статусу следует передавать в параметры самой виртуальной таблицы (в параметр условия), а не использовать отбор в секции ГДЕ. Это кардинально снизит нагрузку на базу данных при выполнении запроса, так как СУБД отфильтрует данные до формирования итоговой выборки.

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

Альтернативный вариант 1: Запрос к физической таблице движений

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

  1. Обращаемся к физической таблице оборотного регистра и группируем данные по нашему измерению (например, по конкретной сим-карте), вычисляя МАКСИМУМ(Период). Для исключения коллизий, когда в одну секунду записано несколько статусов, надежнее получать МАКСИМУМ(МоментВремени) или использовать автосгенерированный внутренний идентификатор записи, если он доступен в контексте запроса.
  2. Помещаем этот результат во временную таблицу.
  3. Выполняем внутреннее соединение этой временной таблицы с исходной физической таблицей регистра по нашему объекту и найденному максимальному периоду/моменту времени. Так мы получаем всю строку движения целиком, включая статус, актуальный на этот момент.
  4. Накладываем фильтр на полученный статус.

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

Альтернативный вариант 2: Реквизит справочника для текущих статусов

Посмотрим на задачу под другим углом. Если бизнес-логика не требует получения статуса "на дату в прошлом" (то есть историчность изменений не важна), а нужен только актуальный текущий статус на данную секунду, оптимальнее всего добавить реквизит ТекущийСтатус непосредственно в сам справочник (в нашем примере — справочник сим-карт).

В этом случае при проведении документов-регистраторов мы просто перезаписываем значение этого реквизита в элементе справочника. Это обеспечит самую высокую скорость работы любых отчетов, так как полностью исключит необходимость обращения к таблицам регистров и расчет срезов последних записей.

← На главную