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