Как правильно установить дату в запросе 1С и оптимизировать условия

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

Работа с запросами — это фундамент разработки на платформе 1С:Предприятие. Одной из наиболее частых задач является передача внешних данных (параметров) в текст запроса, а также обработка пустых значений или отсутствующих записей (NULL). В этой статье мы подробно разберем, как передавать параметры даты, почему функция ЕСТЬNULL эффективнее конструкции ВЫБОР, и как избежать типичных ошибок при работе с типами данных в полях запроса.

Передача параметра в запрос

Рассмотрим ситуацию, когда в тексте запроса используется переменная, обозначенная символом амперсанда (например, &ДатаСреза). Для того чтобы запрос «понял», какое значение подставить вместо этого маркера, необходимо использовать метод объекта Запрос. Разберем по шагам, как это реализуется в коде на встроенном языке:

Для установки значения параметра мы используем метод УстановитьПараметр. Этот метод принимает два аргумента: имя параметра в виде строки (без амперсанда) и само значение.


// Создаем объект запрос
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ВТ.Номенклатура,
    |    &ДатаСреза КАК ДатаОтчета
    |ИЗ
    |    ВТДанные КАК ВТ";

// Устанавливаем значение параметра
НужнаяДата = ТекущаяДата(); 
Запрос.УстановитьПараметр("ДатаСреза", НужнаяДата);

// Выполняем запрос
РезультатЗапроса = Запрос.Выполнить();

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

Оптимизация проверки на NULL: ЕСТЬNULL против ВЫБОР

Проанализируем фрагмент кода из исходного вопроса. Автор использует конструкцию ВЫБОР для проверки остатка на NULL. Давайте посмотрим, как это выглядит:


ВЫБОР
    КОГДА ВТСпецодеждаВНаличии.КоличествоОстаток ЕСТЬ NULL 
        ТОГДА 0
    ИНАЧЕ ВТСпецодеждаВНаличии.КоличествоОстаток
КОНЕЦ

Хотя этот код функционально верен, он избыточен. В языке запросов 1С предусмотрена специальная функция ЕСТЬNULL, которая делает ровно то же самое, но гораздо лаконичнее и быстрее. Рассмотрим, почему ее стоит использовать:

  1. Производительность: На уровне СУБД (SQL Server или PostgreSQL) функция ЕСТЬNULL транслируется в нативные функции (например, ISNULL или COALESCE), что позволяет оптимизатору базы данных более эффективно строить план выполнения запроса.
  2. Читаемость: Код становится компактнее, что особенно важно в больших и вложенных запросах.

Давайте перепишем исходный фрагмент с использованием функции ЕСТЬ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 позволяют создавать чистый, быстрый и надежный код, который легко поддерживать и масштабировать.

← На главную