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

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

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

Почему стандартный СрезПоследних не всегда подходит?

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

Метод 1: Использование временных таблиц для поиска максимума

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

Рассмотрим пошаговую реализацию:

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

Пример реализации запроса:


ВЫБРАТЬ 
    ПриказыОЗачисленииСтудента.Студент, 
    МАКСИМУМ(ПриказыОЗачисленииСтудента.Регистратор.ДатаПриказа) КАК МаксДатаПриказа
ПОМЕСТИТЬ ВТ_ПоследниеДаты
ИЗ 
    РегистрСведений.ПриказыОЗачисленииСтудента КАК ПриказыОЗачисленииСтудента
СГРУППИРОВАТЬ ПО 
    ПриказыОЗачисленииСтудента.Студент;

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

Метод 2: Работа через МоментВремени

Если записей с одинаковой датой несколько, нам поможет использование поля МоментВремени. Этот метод позволяет однозначно идентифицировать запись регистра.


ВЫБРАТЬ 
    Т1.Студент, 
    МАКСИМУМ(Т1.МоментВремени) КАК МаксМомент
ПОМЕСТИТЬ ВТ_Ключи
ИЗ 
    РегистрСведений.ПриказыОЗачисленииСтудента КАК Т1
СГРУППИРОВАТЬ ПО 
    Т1.Студент;

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

Важные рекомендации по архитектуре данных

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

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

← На главную