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