При написании запросов в 1С разработчики часто сталкиваются с ситуацией, когда конструкция ВЫБОР КОГДА с условием равенства двух полей не отрабатывает так, как ожидается. На первый взгляд коды или значения совпадают, однако ветка ТОГДА пропускается, и запрос возвращает значение из ветки ИНАЧЕ. Проанализируем основные причины этой проблемы и разберем по шагам правильные способы сравнения полей в языке запросов.
Рассмотрим частую ошибку: обращение к реквизиту ссылочного типа через точку, например ПриходныйОрдерНаТоварыТовары.Характеристика.Код. Если в строке табличной части характеристика не указана (содержит пустую ссылку), платформа 1С автоматически выполняет неявное левое соединение (LEFT JOIN) с таблицей справочника характеристик.
Так как записи в справочнике для пустой ссылки нет, результат обращения к коду возвращает значение NULL. В языке запросов 1С результат любого сравнения с NULL (например, NULL = "00001") всегда равен Ложь (неопределенность). В результате условие сравнения никогда не выполнится.
Для предотвращения этой проблемы обработаем возможные NULL с помощью функции ЕСТЬNULL:
ВЫБОР
КОГДА ЕСТЬNULL(ПриходныйОрдерНаТоварыТовары.Характеристика.Код, "") = ЕСТЬNULL(ПриходныйОрдерНаТоварыТовары.Номенклатура.Код, "")
ТОГДА 20
ИНАЧЕ ПриходныйОрдерНаТоварыТовары.Количество
КОНЕЦ КАК Количество
Выясним еще одну важную деталь: Номенклатура и ХарактеристикиНоменклатуры — это два разных справочника. Их коды генерируются независимо и почти никогда не совпадают, если логика системы не предусматривает иное.
Если задача состоит в том, чтобы проверить, принадлежит ли характеристика текущей номенклатуре, необходимо сравнивать не коды реквизитов, а подчиненность объекта через владельца:
ВЫБОР
КОГДА ПриходныйОрдерНаТоварыТовары.Характеристика.Владелец = ПриходныйОрдерНаТоварыТовары.Номенклатура
ТОГДА 20
ИНАЧЕ ПриходныйОрдерНаТоварыТовары.Количество
КОНЕЦ КАК Количество
Если же требуется сравнить код номенклатуры с кодом ее владельца у характеристики, правильным условием будет:
ВЫБОР
КОГДА ПриходныйОрдерНаТоварыТовары.Характеристика.Владелец.Код = ПриходныйОрдерНаТоварыТовары.Номенклатура.Код
ТОГДА 20
ИНАЧЕ ПриходныйОрдерНаТоварыТовары.Количество
КОНЕЦ КАК Количество
Даже если визуально коды выглядят одинаково, причины расхождения могут заключаться в следующем:
Ложь. Чтобы привести строки к одной длине, используем функцию ВЫРАЗИТЬ.Ложь.Пример применения функции ВЫРАЗИТЬ для явного приведения длины строки:
ВЫБОР
КОГДА ВЫРАЗИТЬ(ПриходныйОрдерНаТоварыТовары.Характеристика.Код КАК СТРОКА(10)) = ВЫРАЗИТЬ(ПриходныйОрдерНаТоварыТовары.Номенклатура.Код КАК СТРОКА(10))
ТОГДА 20
ИНАЧЕ ПриходныйОрдерНаТоварыТовары.Количество
КОНЕЦ КАК Количество
Если требуется сравнить значения не в рамках одной строки табличной части, а сопоставить каждую строку со всеми остальными строками документа, обычное выражение ВЫБОР КОГДА в одном запросе не сработает, так как запрос обрабатывает записи построчно.
В этом случае проанализируем архитектуру запроса и задействуем временные таблицы:
ВТ_Товары).ЛЕВОЕ СОЕДИНЕНИЕ или соединение таблицы самой с собой) по необходимому условию связи.Использование временных таблиц позволяет нормализовать исходные данные, заранее заменить NULL на значения по умолчанию и выполнить корректные соединения перед проверкой условий.