Оператор «не равно» в 1С: как его записать и где он ломается
Содержание
Знак «не равно» в 1С ставится двумя символами подряд: <> — сначала «меньше», потом «больше», без пробела. Частая ошибка — набрать !=, как в C, JavaScript или PHP. Платформа 1С:Предприятие 8.3 такого оператора не знает и выдаёт синтаксическую ошибку при проверке модуля.
Запись <> одинакова везде: во встроенном языке, в тексте запроса и в выражениях системы компоновки данных (СКД). Различается не символ, а поведение: в запросе условие <> молча отбрасывает строки с NULL, а в СКД «не равно» чаще выбирают из списка видов сравнения, а не пишут руками.
Как набрать знак «не равно» на клавиатуре и чем он отличается от ≠
Символы < и > есть только в английской раскладке. В русской на этих клавишах буквы «Б» и «Ю».
- Переключите раскладку на английскую (
Alt+ShiftилиWin+Пробел). - Нажмите
Shift+ клавишу с «Б» — получится<. - Нажмите
Shift+ клавишу с «Ю» — получится>. - Вернитесь в русскую раскладку, если дальше идёт текст на русском.
Математический значок ≠ в коде 1С не работает
. Это один символ Юникода, а не оператор языка. Его можно вставить в текст табличного документа, в макет печатной формы или в комментарий, но не в условие.
| Запись | Где работает | Результат в коде 1С |
|---|---|---|
<> | встроенный язык, запросы, СКД | оператор «не равно» |
!= | — | синтаксическая ошибка |
≠ | только как текст | синтаксическая ошибка в условии |
НЕ А = Б | встроенный язык, запросы | то же, что А <> Б |
Если в Конфигураторе часто переключаете раскладку, включите в настройках редактора модулей автозамену или пользуйтесь шаблонами текста. Но сам оператор короткий, и большинство разработчиков просто набирают его на английской раскладке.
«Не равно» во встроенном языке 1С
Во встроенном языке <> возвращает Истина или Ложь. Его используют в условиях Если, Пока, в тернарном операторе ?() и при присваивании булевых значений.
Если Документ.Организация <> ОрганизацияПоУмолчанию Тогда
Сообщить("Документ оформлен на другую организацию");
КонецЕсли;
ЕстьРасхождение = (СуммаПоДокументу <> СуммаПоОплате);
Текст = ?(Остаток <> 0, "Есть остаток", "Остатка нет");
Оператор применим к значениям любого типа: числам, строкам, датам, булевым, ссылкам, Неопределено и Null. Если сравниваются значения разных типов, ошибки не будет — результат <> просто равен Истина.
Результат1 = (1 <> "1"); // Истина: число и строка — разные типы
Результат2 = (Неопределено <> 0); // Истина
Результат3 = (Null <> Неопределено); // Истина
Пара НЕ и = даёт тот же результат, что и <>. Но со скобками такую запись читать легче, и не нужно помнить приоритет операций:
Если НЕ (Статус = Перечисления.СтатусыЗаказов.Закрыт) Тогда
// то же самое, что Статус <> Перечисления.СтатусыЗаказов.Закрыт
КонецЕсли;
Несколько условий «не равно» сразу
Ошибка новичков — проверять «не равно ни одному из» через ИЛИ:
// Неправильно: условие истинно ВСЕГДА
Если Вид <> "Аванс" ИЛИ Вид <> "Предоплата" Тогда
// Правильно: ни то, ни другое
Если Вид <> "Аванс" И Вид <> "Предоплата" Тогда
Любое значение не равно хотя бы одному из двух разных вариантов, поэтому первое условие не отсекает ничего. При трёх и более значениях удобнее массив (см. раздел про альтернативы).
Условие «не равно» в запросе 1С
В языке запросов оператор тот же — <>. Его пишут в ГДЕ, ИМЕЮЩИЕ, в условиях соединения и внутри ВЫБОР КОГДА.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка,
| Реализация.Контрагент,
| Реализация.СуммаДокумента
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Контрагент <> &ИсключаемыйКонтрагент
| И Реализация.СуммаДокумента <> 0";
Запрос.УстановитьПараметр("ИсключаемыйКонтрагент", Контрагент);
Сравнение с пустой ссылкой пишут через функцию ЗНАЧЕНИЕ():
|ГДЕ
| Реализация.Договор <> ЗНАЧЕНИЕ(Справочник.ДоговорыКонтрагентов.ПустаяСсылка)
Сравнение с конкретным значением перечисления — так же:
|ГДЕ
| Заказ.Статус <> ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказов.Закрыт)
Главная ловушка: NULL не равен и не «не равен»
Условие Поле <> &Значение в запросе не выбирает строки, где поле равно NULL. Это поведение SQL, на котором работает запрос: сравнение с NULL даёт «неизвестно», и строка в результат не попадает.
NULL появляется чаще, чем кажется:
- 🔗 после
ЛЕВОЕ СОЕДИНЕНИЕ, когда во второй таблице нет пары; - 🧩 при обращении к реквизиту через точку, если ссылка пустая или другого типа;
- 📊 в виртуальных таблицах остатков, когда по измерению нет движений.
Чтобы такие строки не терялись, добавьте явную проверку:
|ГДЕ
| (Цены.Цена <> 0 ИЛИ Цены.Цена ЕСТЬ NULL)
или замените NULL на значение по умолчанию:
|ГДЕ
| ЕСТЬNULL(Цены.Цена, 0) <> 0
Второй вариант короче, но учтите: строки без цены теперь считаются «ценой 0» и отсекутся этим же условием. Выбирайте запись по смыслу задачи.
Для самой проверки на NULL оператор <> не подходит. Пишите Поле ЕСТЬ NULL или НЕ Поле ЕСТЬ NULL.
«Не равно» в СКД и отборах списков
В системе компоновки данных «не равно» встречается в трёх местах.
1. Отбор в настройках отчёта. На вкладке «Настройки» схемы компоновки добавьте поле в отбор и в колонке вида сравнения выберите «Не равно». Пользователь видит этот отбор в форме отчёта и может поменять значение.
2. Условное оформление. Условие оформления строится так же, как отбор: поле, вид сравнения «Не равно», значение. Так, например, красят строки, где статус отличается от «Оплачен».
3. Выражения вычисляемых полей и ресурсов. Здесь пишут руками, синтаксис близок к языку запросов:
ВЫБОР КОГДА СуммаОплаты <> СуммаДокумента ТОГДА "Расхождение" ИНАЧЕ "" КОНЕЦ
Кроме «Не равно», в списке видов сравнения СКД есть и другие отрицания: «Не в списке», «Не в группе», «Не содержит», «Не заполнено». Их стоит выбрать, если сравнение идёт не с одним значением.
Отбор «не равно» программно
Тот же вид сравнения задают из кода — для отчёта или динамического списка на форме:
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Статус");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
ЭлементОтбора.ПравоеЗначение = Перечисления.СтатусыЗаказов.Закрыт;
ЭлементОтбора.Использование = Истина;
В типовых конфигурациях на БСП то же делают одной строкой через ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора, передав последним значимым параметром ВидСравненияКомпоновкиДанных.НеРавно.
Пользователь в режиме 1С:Предприятие ставит такой отбор сам: в форме списка Ещё → Настроить список, вкладка «Отбор», поле и вид сравнения «Не равно».
Отбор СКД «Не равно» по полю, которое в запросе может быть NULL, ведёт себя так же, как <> в запросе: строки с NULL пропадают. Если отчёт «теряет» записи после такого отбора, проверьте соединения в наборе данных.
Как «не равно» работает с разными типами данных
Сам символ один, но результат зависит от типа значений. Сводка по частым случаям:
| Тип | Особенность | Как сравнивать надёжно |
|---|---|---|
| Строка (встроенный язык) | регистр важен: "ООО" <> "ооо" — Истина | ВРег(А) <> ВРег(Б) |
| Строка с пробелами | "Иванов" <> "Иванов " — Истина | СокрЛП(А) <> СокрЛП(Б) |
| Строка неограниченной длины (запрос) | сравнивать напрямую нельзя | ВЫРАЗИТЬ(Поле КАК СТРОКА(150)) <> &Текст |
| Дата | сравнивается вместе со временем | НачалоДня(А) <> НачалоДня(Б) |
| Ссылка | пустая ссылка ≠ Неопределено | ЗначениеЗаполнено(Ссылка) или ПустаяСсылка() |
| Составной тип | значения разных типов всегда «не равны» | сначала проверить ТипЗнч() |
| Число | дробные хранятся в десятичном виде | обычный <>, без допусков |
Строки неограниченной длины в запросах
Реквизит строкового типа без указания длины (например, «Комментарий») в запросе нельзя сравнивать через = или <>: запрос завершится ошибкой. Приведите поле к строке фиксированной длины:
|ГДЕ
| ВЫРАЗИТЬ(Документ.Комментарий КАК СТРОКА(200)) <> """"
Сравниваются только первые 200 символов. Для проверки «комментарий не пустой» этого достаточно.
Даты со временем
Документ от 15.03 в 14:20 и дата 15.03 00:00:00 не равны. Если нужно сравнить именно дни, обрежьте время с обеих сторон:
Если НачалоДня(Документ.Дата) <> НачалоДня(ТекущаяДатаСеанса()) Тогда
Сообщить("Документ не сегодняшний");
КонецЕсли;
Ссылки и пустые значения
Для ссылки есть три разных «ничего»: пустая ссылка, Неопределено и Null. Они не равны друг другу. Поэтому Ссылка <> Неопределено вернёт Истина и для пустой ссылки — условие не защитит от незаполненного реквизита.
Универсальная проверка — ЗначениеЗаполнено(Значение). Но у неё есть подвох: для числа 0 и для Ложь она тоже вернёт Ложь. Для чисел и булевых пишите явное сравнение <> 0 или = Истина.
Другие способы записать отрицание условия
Иногда <> — не лучший выбор. Набор альтернатив:
В запросе:
- 🚫
НЕ В (&СписокЗначений)— значение не входит в список или массив; - 📅
НЕ МЕЖДУ &Начало И &Конец— вне диапазона; - 🔤
НЕ Поле ПОДОБНО "%тест%"— строка не содержит фрагмент; - 🌳
НЕ В ИЕРАРХИИ (&Группа)— элемент не входит в группу справочника; - 🏷️
НЕ Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг— значение составного поля не этого типа; - ⛔
НЕ Поле ЕСТЬ NULL— поле заполнено.
|ГДЕ
| НЕ Реализация.Контрагент В (&ИсключаемыеКонтрагенты)
Параметр ИсключаемыеКонтрагенты передают массивом или списком значений. Если массив пустой, условие НЕ В пропустит все строки — это нормально, но проверьте, что именно этого вы ждёте.
Во встроенном языке:
// Значение не входит в массив
Исключения = Новый Массив;
Исключения.Добавить("Аванс");
Исключения.Добавить("Предоплата");
Исключения.Добавить("Возврат");
Если Исключения.Найти(Вид) = Неопределено Тогда
// Вид не равен ни одному из трёх
КонецЕсли;
Метод НайтиСтроки() у таблицы значений ищет только по равенству. Условия «не равно» в нём нет. Есть два выхода: пройти таблицу циклом и сравнить через <> или поместить таблицу во временную таблицу запроса и отфильтровать в ГДЕ.
Отобранные = Таблица.СкопироватьКолонки();
Для Каждого Строка Из Таблица Цикл
Если Строка.Склад <> ОсновнойСклад Тогда
ЗаполнитьЗначенияСвойств(Отобранные.Добавить(), Строка);
КонецЕсли;
КонецЦикла;
Для больших таблиц (десятки тысяч строк) вариант с запросом обычно быстрее и читается проще.
Почему условие «не равно» не срабатывает: разбор частых ошибок
Отдельно о неразрывном пробеле. Он попадает в справочники при копировании из Word и почты. На экране его не отличить от обычного, а СокрЛП() его не убирает. Если сравнение строк ведёт себя странно, замените его явно: СтрЗаменить(Текст, Символы.НПП, " ").