При разработке отчетов и обработок в 1С часто возникает задача получить «самую свежую» запись из регистра сведений. В типовых ситуациях мы используем виртуальную таблицу СрезПоследних. Однако, что делать, если логика «последней записи» определяется не периодом самого регистра, а реквизитом, хранящимся внутри документа-регистратора (например, «Датой приказа»)? Давайте разберемся, как решить эту задачу профессионально и избежать дублирования строк.
СрезПоследних не всегда подходит?Виртуальная таблица СрезПоследних работает строго по полю Период регистра сведений. Если периодичность регистра установлена «По позиции регистратора», то последней записью будет считаться та, у которой дата и время проведения документа максимальны. Если же в бизнесе принято, что запись «последняя», если у нее, например, самая поздняя ДатаПриказа (которая может отличаться от даты самого документа), стандартный механизм вернет не то, что нам нужно. Именно этот конфликт между системным периодом и бизнес-логикой порождает дубли в отчетах.
Самым надежным способом решения является двухэтапный алгоритм. На первом этапе мы находим максимальное значение нужного нам критерия для каждого студента, а на втором — «подтягиваем» остальные данные, соответствующие этому критерию.
Рассмотрим пошаговую реализацию:
Пример реализации запроса:
ВЫБРАТЬ
ПриказыОЗачисленииСтудента.Студент,
МАКСИМУМ(ПриказыОЗачисленииСтудента.Регистратор.ДатаПриказа) КАК МаксДатаПриказа
ПОМЕСТИТЬ ВТ_ПоследниеДаты
ИЗ
РегистрСведений.ПриказыОЗачисленииСтудента КАК ПриказыОЗачисленииСтудента
СГРУППИРОВАТЬ ПО
ПриказыОЗачисленииСтудента.Студент;
ВЫБРАТЬ
ПриказыОЗачисленииСтудента.Студент,
ПриказыОЗачисленииСтудента.Регистратор.ДатаНачалаДействия,
ПриказыОЗачисленииСтудента.Регистратор.ДатаПриказа,
ПриказыОЗачисленииСтудента.Регистратор.НомерПриказа
ИЗ
РегистрСведений.ПриказыОЗачисленииСтудента КАК ПриказыОЗачисленииСтудента
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
ВТ_ПоследниеДаты КАК ВТ
ПО
ПриказыОЗачисленииСтудента.Студент = ВТ.Студент
И ПриказыОЗачисленииСтудента.Регистратор.ДатаПриказа = ВТ.МаксДатаПриказа
МоментВремениЕсли записей с одинаковой датой несколько, нам поможет использование поля МоментВремени. Этот метод позволяет однозначно идентифицировать запись регистра.
ВЫБРАТЬ
Т1.Студент,
МАКСИМУМ(Т1.МоментВремени) КАК МаксМомент
ПОМЕСТИТЬ ВТ_Ключи
ИЗ
РегистрСведений.ПриказыОЗачисленииСтудента КАК Т1
СГРУППИРОВАТЬ ПО
Т1.Студент;
ВЫБРАТЬ
Рег.Студент,
Рег.Регистратор
ИЗ
РегистрСведений.ПриказыОЗачисленииСтудента КАК Рег
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
ВТ_Ключи КАК Ключи
ПО
Рег.Студент = Ключи.Студент
И Рег.МоментВремени = Ключи.МаксМомент
Проанализировав проблему, мы можем выделить несколько критически важных моментов для программиста:
Регистратор.Реквизит внутри запроса существенно замедляет работу. Это происходит потому, что 1С каждый раз обращается к таблице документа. Если данные нужны часто, лучше предусмотреть вынос этих полей (например, ДатаПриказа) непосредственно в измерения или ресурсы регистра сведений при его проектировании.Надеемся, что эти методы помогут вам навести порядок в отчетах и избавиться от лишних записей. Помните, что самый эффективный запрос — это тот, который минимизирует количество соединений и обращений к сторонним таблицам документов.