При разработке отчетов и проведении документов в среде 1С:Предприятие разработчики часто сталкиваются с необходимостью получения актуальных данных на определенный момент времени. Самым популярным инструментом для этого выступает виртуальная таблица СрезПоследних периодического регистра сведений. Однако некорректное использование условий в таких запросах может приводить к тому, что рабочий код внезапно возвращает пустой результат. Давайте подробно разберем, почему так происходит, и как правильно оптимизировать этот механизм на примере конфигурации Бухгалтерия предприятия 2.5.
Рассмотрим исходный запрос, который был представлен в обсуждении:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ОтветственныеЛицаОрганизацийСрезПоследних.ФизическоеЛицо КАК ФизическоеЛицо
|ИЗ
| РегистрСведений.ОтветственныеЛицаОрганизаций.СрезПоследних КАК ОтветственныеЛицаОрганизацийСрезПоследних
|ГДЕ
| ОтветственныеЛицаОрганизацийСрезПоследних.Период = &Период
| И ОтветственныеЛицаОрганизацийСрезПоследних.СтруктурнаяЕдиница = &СтруктурнаяЕдиница
| И ОтветственныеЛицаОрганизацийСрезПоследних.ОтветственноеЛицо = &ОтветственноеЛицо";
На первый взгляд, синтаксических ошибок здесь нет (после удаления случайной цифры «4»). Однако данный запрос либо вернет пустой результат, либо отработает крайне неэффективно. Причина кроется в фундаментальном различии между фильтрацией данных в секции ГДЕ и использованием параметров самой виртуальной таблицы.
Давайте по шагам проанализируем, почему этот запрос не работает так, как ожидает разработчик.
Когда мы обращаемся к виртуальной таблице СрезПоследних без указания параметров в скобках, платформа 1С транслирует это действие в SQL-запрос по следующим правилам:
ГДЕ. То есть пытается применить условие Период = &Период к уже готовому срезу на текущую дату.Посмотрим на простом примере:
В регистре сведений есть запись о назначении руководителя от 01.01.2026. Мы проводим документ от 15.01.2026 и передаем эту дату в параметр &Период.
20.01.2026). Самая актуальная запись на сегодня — это запись от 01.01.2026. Она попадает в выборку.ГДЕ: система сравнивает дату записи 01.01.2026 с датой документа 15.01.2026.01.01.2026 = 15.01.2026 возвращает Ложь.Даже если бы дата документа чудесным образом в точности совпала с датой установки ответственного лица в регистре, условие Период = &Период в секции ГДЕ практически гарантированно вернет пустое значение. Дело в точности хранения времени:
01.01.2026 00:00:00) или к началу секунды проведения приказа.01.01.2026 14:35:22).Оператор равенства в секции ГДЕ требует стопроцентного совпадения времени до секунды. Разница даже в одну секунду приведет к отсеиванию нужной строки. В то же время параметры виртуальной таблицы работают по принципу «меньше или равно» (<= &Период), что позволяет корректно захватывать последнюю актуальную запись на указанный момент времени.
Помимо логической ошибки получения пустых данных, использование секции ГДЕ для виртуальных таблиц наносит сильный удар по производительности информационной базы. Рассмотрим, почему это критично для СУБД (особенно под управлением PostgreSQL или MS SQL Server):
Для исправления работы запроса необходимо перенести все отборы из секции ГДЕ непосредственно в параметры виртуальной таблицы СрезПоследних.
Также в конфигурациях семейства Бухгалтерия предприятия 2.0 / 2.5 важно учитывать следующие нюансы:
Организации, так и на ПодразделенияОрганизаций. Убедитесь, что тип передаваемого параметра в точности соответствует типу значения в регистре.ЕСТЬNULL.Разберем правильный и полностью оптимизированный вариант программного кода:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЕСТЬNULL(ОтветственныеЛицаОрганизацийСрезПоследних.ФизическоеЛицо, ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)) КАК ФизическоеЛицо
|ИЗ
| РегистрСведений.ОтветственныеЛицаОрганизаций.СрезПоследних(
| &Период,
| СтруктурнаяЕдиница = &СтруктурнаяЕдиница
| И ОтветственноеЛицо = &ОтветственноеЛицо
| ) КАК ОтветственныеЛицаОрганизацийСрезПоследних";
Запрос.УстановитьПараметр("Период", СсылкаНаОбъект.Дата);
Запрос.УстановитьПараметр("СтруктурнаяЕдиница", СсылкаНаОбъект.Организация);
Запрос.УстановитьПараметр("ОтветственноеЛицо", Перечисления.ОтветственныеЛицаОрганизаций.Руководитель);
РезультатЗапроса = Запрос.Выполнить();
СрезПоследних(...). Теперь СУБД выберет срез только для одной конкретной организации и должности.&Период перенесен в параметры среза. Платформа корректно получит последнюю запись на дату документа (по условию «меньше или равно»), игнорируя несовпадение секунд.ЕСТЬNULL, которая гарантирует, что если руководитель не найден, программа вернет пустую ссылку справочника физлиц, а не значение Неопределено или NULL, что предотвратит возможные ошибки при дальнейшей обработке данных.Используйте этот подход во всех ваших запросах к периодическим регистрам сведений, чтобы обеспечить стабильную работу, корректность данных и высокую скорость выполнения операций в системе 1С:Предприятие.