Как правильно получить последнюю запись в регистре сведений 1С и почему СрезПоследних возвращает список

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с регистрами сведений в платформе 1С:Предприятие начинающие разработчики часто сталкиваются с ситуацией, когда виртуальная таблица СрезПоследних вместо одной ожидаемой «самой свежей» записи возвращает целую таблицу строк. Разберем подробнее, почему так происходит, как устроена механика среза последних и какими способами можно гарантированно получить последнюю актуальную запись по заданным условиям.

Выясним причину: почему СрезПоследних возвращает несколько строк

Виртуальная таблица СрезПоследних формирует срез не в целом по регистру, а по каждому уникальному сочетанию его измерений. Проанализируем простую аналогию: в регистре сведений «Курсы валют» измерением является Валюта, а ресурсом — Курс. Срез последних на определенную дату вернет актуальный курс для каждой валюты (по одной строке на доллар, евро, юань и т. д.), а не одну-единственную строку с последним введенным в систему курсом.

Если в вашем регистре сведений заданы измерения, например Документ и ВариантОбмена, то без указания жесткого отбора в параметрах виртуальной таблицы запрос вернет срез для каждой пары «Документ + ВариантОбмена». Наложение условия в секции ГДЕ после соединения таблиц лишь отфильтрует уже скомпонованный срез, но не изменит логику построения самого среза последних.

Решение 1. Использование параметров виртуальной таблицы СрезПоследних

Если необходимо получить актуальные данные среза по конкретным значениям измерений, отбор следует передавать напрямую в параметры виртуальной таблицы (второй параметр функции СрезПоследних). Рассмотрим пример запроса, где выбирается срез по конкретному документу и варианту обмена:


ВЫБРАТЬ
	ДокументыЭДСрезПоследних.ИдентификаторЗапроса КАК ИдентификаторЗапроса,
	ДокументыЭДСрезПоследних.Период КАК Период,
	ДокументыЭДСрезПоследних.Документ КАК Документ,
	ДокументыЭДСрезПоследних.ВариантОбмена КАК ВариантОбмена
ИЗ
	РегистрСведений.ДокументыЭД.СрезПоследних(
		&ТекущаяДата,
		ВариантОбмена = ЗНАЧЕНИЕ(Перечисление.ВариантыУниверсальногоОбмена.ВЕТИС)
			И Документ ССЫЛКА Документ.РеализацияТоваровУслуг) КАК ДокументыЭДСрезПоследних

Важно: передача условий в скобках виртуальной таблицы заставляет платформу рассчитывать срез только для тех комбинаций измерений, которые удовлетворяют фильтру. Это существенно повышает скорость работы запроса и исключает выборку лишних данных.

Решение 2. Запрос к физической таблице с ограничением ВЫБРАТЬ ПЕРВЫЕ 1

Если требуется получить абсолютно последнюю созданную запись в регистре сведений (без привязки к уникальности всех комбинаций измерений) или срез выполняется по реквизитам, а не по измерениям, оптимальнее обратиться напрямую к физической таблице регистра. Разберем по шагам, как построить такой запрос:

  1. Указываем конструкцию ВЫБРАТЬ ПЕРВЫЕ 1 для ограничения количества выводимых строк.
  2. В секции ГДЕ задаем необходимые фильтры по периоду и значениям полей.
  3. Сортируем результат с помощью УПОРЯДОЧИТЬ ПО Период УБЫВ.

Посмотрим на практический пример кода запроса:


ВЫБРАТЬ ПЕРВЫЕ 1
	ДокументыЭД.Документ КАК Документ,
	ДокументыЭД.ВариантОбмена КАК ВариантОбмена,
	ДокументыЭД.Файл КАК Файл,
	ДокументыЭД.Статус КАК Статус,
	ДокументыЭД.ИдентификаторЗапроса КАК ИдентификаторЗапроса
ИЗ
	РегистрСведений.ДокументыЭД КАК ДокументыЭД
ГДЕ
	ДокументыЭД.Период <= &НужнаяДата
	И ДокументыЭД.ВариантОбмена = ЗНАЧЕНИЕ(Перечисление.ВариантыУниверсальногоОбмена.ВЕТИС)
	И Документ ССЫЛКА Документ.РеализацияТоваровУслуг
УПОРЯДОЧИТЬ ПО
	ДокументыЭД.Период УБЫВ

Обход результатов запроса во встроенном языке

После выполнения запроса необходимо безопасно извлечь полученное значение ресурса или реквизита. Чтобы избежать ошибок обращений к объектам в случае отсутствия записей, рекомендуется использовать следующий подход:


Запрос = Новый Запрос;
Запрос.Текст = 
	"ВЫБРАТЬ ПЕРВЫЕ 1
	|	ДокументыЭД.ИдентификаторЗапроса КАК ИдентификаторЗапроса
	|ИЗ
	|	РегистрСведений.ДокументыЭД КАК ДокументыЭД
	|ГДЕ
	|	ДокументыЭД.Период <= &НужнаяДата
	|	И ДокументыЭД.ВариантОбмена = &ВариантОбмена
	|УПОРЯДОЧИТЬ ПО
	|	ДокументыЭД.Период УБЫВ";

Запрос.УстановитьПараметр("НужнаяДата", ТекущаяДата());
Запрос.УстановитьПараметр("ВариантОбмена", Перечисления.ВариантыУниверсальногоОбмена.ВЕТИС);

Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
	ИдентификаторЗапроса = Выборка.ИдентификаторЗапроса;
Иначе
	ИдентификаторЗапроса = Неопределено;
КонецЕсли;

Дополнительные профессиональные рекомендации

При решении задач получения последних записей из регистров сведений стоит учитывать несколько важных нюансов платформы 1С:

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