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