В практике разработки на платформе 1С:Предприятие часто возникает задача: получить не просто самую последнюю запись (что легко решается с помощью виртуальной таблицы СрезПоследних), а именно несколько последних записей (например, последние 3 замера) для каждого объекта (измерения). Сложность заключается в том, что стандартная конструкция ВЫБРАТЬ ПЕРВЫЕ N работает для всего результата запроса целиком, а не для каждой группы отдельно.
В этой статье мы подробно разберем несколько способов решения этой задачи, проанализируем их эффективность и выясним, как обойти ограничения периодичности регистра «День».
Этот метод считается классическим для языка запросов 1С, в котором отсутствуют оконные функции типа ROW_NUMBER(). Мы проанализируем ситуацию, где для каждой записи основной таблицы мы будем «подсчитывать» количество записей, которые произошли позже нее.
Разберем логику: если для конкретной записи в этом же регистре по тому же буру найдется менее 3-х записей с более поздней датой, значит, эта запись входит в тройку последних. Посмотрим на пример реализации такого запроса, который поможет составить Консоль кода + ИИ-помощник (GigaChat) с учётом метаданных конфигурации:
ВЫБРАТЬ
РС.Период КАК Период,
РС.Бур КАК Бур,
РС.Прохождение КАК Прохождение
ИЗ
РегистрСведений.ПрохождениеБуров КАК РС
ГДЕ
(ВЫБРАТЬ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ РС_Б.Период)
ИЗ
РегистрСведений.ПрохождениеБуров КАК РС_Б
ГДЕ
РС_Б.Бур = РС.Бур
И РС_Б.Период > РС.Период) < 3
УПОРЯДОЧИТЬ ПО
Бур,
Период УБЫВ
Важные нюансы метода:
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ РС_Б.Период) < 3 цифра 3 означает количество последних записей. Если нужно 5 записей — меняем на 5.Если ваша задача — вывести данные в отчет, то писать сложный запрос вовсе не обязательно (как показывает Простой пример отчета СКД с выводом другого внешнего отчета в один табличный документ на УФ). Платформа 1С предоставляет встроенный механизм ограничения количества записей в группировках. Рассмотрим, как это настроить:
Бур.Топ.Период (направление — Убывание).Проанализируем результат: СКД автоматически применит алгоритм выборки первых N строк для каждого значения измерения Бур.
Выясним причину, по которой обычное сравнение по периоду может работать некорректно. Если у регистра сведений установлена периодичность День, то в одну и ту же дату может быть введено несколько документов. В этом случае поле Период у них будет одинаковым, и запрос не сможет однозначно определить, какая запись «свежее».
Чтобы решить эту проблему, мы должны использовать Момент Времени или комбинацию полей Регистратор и НомерСтроки (изучить свойства которых поможет Информер по метаданным). Рассмотрим пример правильного условия связи для обеспечения уникальности:
ГДЕ
РС1.Период < РС2.Период
ИЛИ (РС1.Период = РС2.Период И РС1.Регистратор.МоментВремени < РС2.Регистратор.МоментВремени)
Такой подход «разрезает» записи с одинаковой датой, выстраивая их в строгую очередь на основе времени регистрации документа в системе.
Если нам нужно гарантированно и быстро получить ровно 2 или 3 записи, и мы хотим избежать вложенных запросов в условии ГДЕ, можно использовать последовательное объединение временных таблиц. Разберем по шагам:
СрезПоследних) и помещаем во временную таблицу ВТ_Макс1.ВТ_Макс1. Результат кладем в ВТ_Макс2.ВТ_Макс3.ОБЪЕДИНИТЬ ВСЕ) данные из трех таблиц и соединяем их с основной таблицей регистра для получения ресурсов (например, прохождения бура).Посмотрим, как выглядит выборка второй «максимальной» даты:
ВЫБРАТЬ
РС.Бур,
МАКСИМУМ(РС.Период) КАК Период
ИЗ
РегистрСведений.ПрохождениеБуров КАК РС
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Макс1 КАК ВТ_Макс1
ПО РС.Бур = ВТ_Макс1.Бур
И РС.Период = ВТ_Макс1.Период
ГДЕ
ВТ_Макс1.Бур ЕСТЬ NULL
СГРУППИРОВАТЬ ПО
РС.Бур
Проанализировав все способы, мы можем дать следующие советы:
Регистратор для уточнения порядка, иначе результат запроса может меняться случайным образом при каждом запуске.Используя эти методы, мы сможем эффективно решать задачи по анализу истории изменений в регистрах 1С, получая актуальные срезы данных в нужных разрезах.