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