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