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