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