Разработка и Конфигурация · 12 мин
Как сравнить два значения в 1С: полное руководство с примерами
Как сравнить два значения в 1С: операторы =, <>, , сравнение строк, чисел, дат и ссылок. Примеры кода на встроенном языке, типичные ошибки и ответы на вопросы.
Сравнение двух значений — одна из самых частых операций во встроенном языке 1С:Предприятие. Она встречается везде: в проверках заполнения реквизитов, в условиях запросов, при обработке данных и построении отчётов. При этом у неопытных разработчиков сравнение нередко даёт неожиданные результаты: строки «равны», а условие не срабатывает, или сравнение падает с ошибкой из-за несовместимости типов.
Причина почти всегда одна — не учтён тип сравниваемых значений или особенности сравнения конкретного типа данных. Число сравнивается не так, как строка, а ссылка на справочник — не так, как дата. В этой статье разобраны все основные сценарии: операторы сравнения, работа с числами, строками, датами, ссылками и значением Неопределено, а также типичные ошибки и способы их избежать.
Материал подойдёт как начинающим разработчикам 1С, так и тем, кто пишет условия в схемах компоновки данных, отборах динамических списков и расширениях. Все примеры кода применимы к платформе 1С:Предприятие 8.3.
Операторы сравнения во встроенном языке 1С
Во встроенном языке 1С доступен стандартный набор операторов сравнения: равно (=), не равно (<>), больше (>), меньше (<), больше или равно (>=), меньше или равно (<=). Все они возвращают значение типа Булево — Истина или Ложь, которое обычно используется в конструкциях Если ... Тогда и Пока ... Цикл.
Важная особенность: для присваивания и для сравнения в 1С используется один и тот же символ =. Контекст определяется автоматически — в условии это сравнение, в начале оператора — присваивание. Ошибки «перепутал = и ==», знакомой разработчикам на C-подобных языках, здесь не существует.
А = 10;
Б = 20;
Если А = Б Тогда
Сообщить("Значения равны");
ИначеЕсли А < Б Тогда
Сообщить("А меньше Б");
Иначе
Сообщить("А больше Б");
КонецЕсли;Операторы «больше» и «меньше» работают не со всеми типами. Их можно применять к числам, датам и строкам (сравнение строк — лексикографическое, по алфавиту). Для ссылочных типов — справочников, документов, перечислений — доступны только равенство и неравенство: понятия «больше» или «меньше» для ссылки не определены.
Сравнение чисел и дат
Числа сравниваются напрямую и обычно не вызывают проблем. Единственный нюанс — вычисления с дробными значениями. Если число получено в результате деления или округления, перед сравнением на точное равенство стоит убедиться, что точность представления не исказит результат. В спорных случаях сравнивайте не равенство, а попадание разницы в допустимый диапазон.
Даты в 1С сравниваются теми же операторами, причём сравнение идёт с точностью до секунды. Это частый источник ошибок: если один реквизит содержит дату с временем (например, момент проведения документа), а второй — только дату, условие равенства не выполнится, хотя визуально даты совпадают.
// Сравнение дат без учёта времени
Если НачалоДня(ДатаДокумента) = НачалоДня(ТекущаяДатаСеанса()) Тогда
Сообщить("Документ создан сегодня");
КонецЕсли;
// Проверка попадания в период
Если ДатаОтгрузки >= НачалоПериода И ДатаОтгрузки <= КонецДня(КонецПериода) Тогда
// дата внутри периода
КонецЕсли;Для приведения даты к началу или концу суток используйте функции НачалоДня() и КонецДня(). Также полезны НачалоМесяца(), КонецМесяца() и аналогичные функции при сравнении периодов в отчётах и регламентных операциях.
Сравнение строк: регистр, пробелы и длина
Строки в операторах сравнения 1С сравниваются без учёта регистра: условие "Петров" = "ПЕТРОВ" вернёт Истина. Однако пробелы и специальные символы учитываются полностью. Строка "Иванов " с пробелом на конце не равна строке "Иванов" — это одна из самых массовых причин «неработающих» условий при обработке данных, загруженных из Excel или внешних систем.
Перед сравнением строк, пришедших извне, рекомендуется нормализовать их функцией СокрЛП(), которая убирает незначащие пробелы слева и справа. Если нужно сравнение с учётом регистра, используйте функцию СтрСравнить() — она возвращает -1, 0 или 1 и позволяет задать учёт регистра явно.
// Надёжное сравнение строк из внешнего источника
Если СокрЛП(НаименованиеИзФайла) = СокрЛП(Номенклатура.Наименование) Тогда
// совпадение найдено
КонецЕсли;
// Сравнение с учётом регистра
Если СтрСравнить(Строка1, Строка2, Истина) = 0 Тогда
// строки идентичны с точностью до регистра
КонецЕсли;Для проверки вхождения подстроки операторы сравнения не подходят — используйте СтрНайти(), которая возвращает позицию вхождения или 0, если подстрока не найдена. Проверка СтрНайти(Текст, "счёт") > 0 заменяет отсутствующий во встроенном языке оператор «содержит».
Сравнение ссылок, Неопределено и NULL
Ссылки на объекты базы данных — элементы справочников, документы — сравниваются только операторами = и <>. Сравнивается уникальный идентификатор ссылки, поэтому две ссылки на один и тот же объект всегда равны, даже если получены разными способами. Сравнивать ссылку со строкой или GUID в виде текста нельзя — результат будет некорректным.
Особого внимания требуют пустые и незаполненные значения. Значение Неопределено означает отсутствие значения вообще, пустая ссылка — существующий, но незаполненный реквизит ссылочного типа. Это разные состояния, и сравнивать их нужно по-разному: для Неопределено — прямым сравнением, для ссылок — функцией ЗначениеЗаполнено() или сравнением с пустой ссылкой.
// Проверка на Неопределено
Если Результат = Неопределено Тогда
// значение не присвоено
КонецЕсли;
// Проверка заполненности ссылки
Если ЗначениеЗаполнено(Документ.Контрагент) Тогда
// контрагент указан
КонецЕсли;
// Сравнение с пустой ссылкой
Если СтрокаТЧ.Номенклатура = Справочники.Номенклатура.ПустаяСсылка() Тогда
// реквизит не заполнен
КонецЕсли;Значение NULL встречается только в результатах запросов — например, при левом соединении без найденной пары. В коде его проверяют через Значение = NULL не получится надёжно: правильный способ в запросе — ЕСТЬ NULL или функция ЕСТЬNULL(), а в выборке — сравнение Выборка.Поле = NULL, которое платформа обрабатывает корректно.
Сравнение значений разных типов и приведение типов
Платформа 1С строго относится к сравнению несовместимых типов: попытка сравнить число со строкой или дату с булевым значением в ряде случаев вызывает ошибку исполнения, в других — неочевидный результат. Поэтому перед сравнением значений, тип которых не гарантирован (например, данных из произвольного реквизита составного типа или из файла), выполняйте проверку типа.
Для определения типа используется связка ТипЗнч() и Тип(). Для преобразования — функции Число(), Строка(), Дата(). Учтите, что Число("abc") вызовет ошибку, поэтому преобразование строк из внешних источников лучше оборачивать в Попытка ... Исключение.
Как выбрать способ сравнения
Сравнение в запросах и СКД
В языке запросов 1С действуют те же операторы сравнения, плюс специальные конструкции: В для проверки вхождения в список, ПОДОБНО для сравнения строки с шаблоном, МЕЖДУ ... И ... для проверки попадания в диапазон. Эти операторы часто заменяют цепочки условий и делают запрос читабельнее.
ВЫБРАТЬ
Товары.Ссылка
ИЗ
Справочник.Номенклатура КАК Товары
ГДЕ
Товары.Наименование ПОДОБНО "%кабель%"
И Товары.ВидНоменклатуры В (&Виды)
И Товары.Код МЕЖДУ "000001" И "000100"В схемах компоновки данных для отборов доступны виды сравнения: равно, не равно, в списке, в группе из списка, содержит, не содержит и другие. Вид «Содержит» для строк работает аналогично ПОДОБНО с символами % по краям. При программной установке отбора в СКД вид сравнения задаётся через ВидСравненияКомпоновкиДанных.
Отдельно отметьте сравнение дат в запросах: конец периода передавайте как границу с включением (КонецПериода(&Дата, День)) или используйте условие «меньше начала следующего дня». Сравнение «меньше или равно дате без времени» отсекает все записи за этот день, кроме полуночи.
Проверка результата и отладка сравнений
Если условие ведёт себя неожиданно, первым шагом выведите сравниваемые значения и их типы. Команда Сообщить("" + ТипЗнч(Знч1) + " = [" + Знч1 + "], " + ТипЗнч(Знч2) + " = [" + Знч2 + "]") сразу покажет расхождение типов или скрытые пробелы в строках. В конфигураторе удобнее использовать точку останова и табло: выражение Знч1 = Знч2 можно вычислить прямо во время отладки.
Как проверить корректность сравнения
Типы совпадают или совместимы (число с числом, дата с датой)
Сравниваются строка с числом или дата со строкой без приведения
Перед сравнением применён СокрЛП()
В значениях видны или предполагаются пробелы, переносы строк
Обе даты приведены к НачалоДня() или обе содержат время
Одна дата с временем, другая без — равенство никогда не наступит
NULL обработан через ЕСТЬNULL или проверен в выборке
Значение NULL сравнивается с пустой ссылкой — условие не сработает
Для сложных условий с несколькими сравнениями разбивайте проверку на части и логируйте результат каждой. Это быстрее, чем искать, какое именно из пяти условий в одном Если вернуло Ложь.
Что важно запомнить
Сравнение в 1С выполняется операторами =, <>, >, < — но корректность результата зависит от типов. Строки очищайте СокрЛП(), даты приводите к НачалоДня(), ссылки сравнивайте только на равенство, NULL и Неопределено проверяйте специальными способами. При сомнениях сначала выведите типы значений через ТипЗнч() — это решает большинство загадок с несрабатывающими условиями.
Частые вопросы о сравнении значений в 1С
Почему условие «Строка1 = Строка2» не срабатывает, хотя значения визуально одинаковые?
Чаще всего в одной из строк есть пробелы в конце или начале, неразрывные пробелы либо невидимые символы из файла. Примените СокрЛП() к обеим строкам. Если не помогло — сравните длины строк через СтрДлина(): разница покажет наличие скрытых символов.
Можно ли сравнить ссылку со строкой, содержащей её GUID?
Напрямую — нет, такое сравнение некорректно. Нужно сначала получить ссылку из строки, например через метод менеджера справочника ПолучитьСсылку() с объектом УникальныйИдентификатор, созданным из строки, и только потом сравнивать две ссылки оператором =.
Как сравнить две даты без учёта времени?
Приведите обе даты к началу дня: НачалоДня(Дата1) = НачалоДня(Дата2). Для проверки попадания в день используйте диапазон от НачалоДня() до КонецДня() нужной даты.
Чем отличается Неопределено от пустой ссылки?
Неопределено — это отсутствие значения как таковое, оно возникает у необъявленных переменных и реквизитов составного типа без установленного значения. Пустая ссылка — конкретное значение ссылочного типа, означающее «объект не выбран». Проверяются они по-разному: Неопределено — прямым сравнением, пустая ссылка — через ЗначениеЗаполнено() или сравнение с ПустаяСсылка().
Учитывается ли регистр при сравнении строк оператором = ?
Нет, операторы сравнения строк во встроенном языке регистронезависимы: "Абв" = "АБВ" вернёт Истина. Если нужно сравнение с учётом регистра, используйте функцию СтрСравнить() с соответствующим параметром.
Как проверить, что значение из запроса равно NULL?
В тексте запроса используйте конструкцию «Поле ЕСТЬ NULL» или замените NULL функцией ЕСТЬNULL(Поле, ЗначениеПоУмолчанию). В коде при обходе выборки допустимо сравнение Выборка.Поле = NULL — платформа обрабатывает его корректно, в отличие от смешения NULL с другими типами.