Разработка и Конфигурация · 9 мин
Как проверить, число или нет, в 1С
Способы проверить, является ли значение числом в 1С: ТипЗначения, СтроковыеФункцииКлиентСервер, преобразование типов. Примеры кода, ошибки и советы.
При разработке и доработке конфигураций 1С регулярно возникает задача: убедиться, что переменная, реквизит или введённое пользователем значение действительно является числом. Это нужно перед расчётами, сравнениями, записью в регистры и при загрузке данных из файлов, где все значения изначально приходят строками.
Встроенный язык 1С не имеет единой функции наподобие «ЭтоЧисло», поэтому проверку выполняют несколькими способами: через определение типа значения, через попытку преобразования строки с использованием ОписаниеТипов, либо через готовые функции из Библиотеки стандартных подсистем. Выбор зависит от того, что именно нужно проверить — тип уже существующего значения или строку, которая должна содержать число.
Ниже разобраны основные методы с примерами кода, типичные ошибки и границы применения каждого подхода. Примеры написаны на встроенном языке 1С и подходят для платформы 8.3 в клиентском и серверном контексте.
Какие бывают ситуации проверки
Прежде чем выбрать метод, важно понять, что именно вы проверяете. Ситуаций две, и они принципиально различаются. Первая — у вас уже есть значение в переменной, и нужно узнать, числового ли оно типа. Это типично для реквизитов составного типа, колонок таблицы значений, результатов запросов. Вторая — у вас есть строка, например введённая пользователем или прочитанная из CSV-файла, и нужно понять, можно ли её интерпретировать как число.
Для первой ситуации достаточно сравнения типов, для второй потребуется либо анализ содержимого строки, либо контролируемое преобразование. Смешивать эти подходы нельзя: проверка типа строки «123» покажет, что это строка, хотя по смыслу она число.
Проверка типа значения через ТипЗнч
Базовый способ — функция ТипЗнч(), которая возвращает тип переданного значения. Результат сравнивается с типом «Число», полученным через конструктор Тип().
Если ТипЗнч(Значение) = Тип("Число") Тогда
Сообщить("Это число");
Иначе
Сообщить("Это не число");
КонецЕсли;
Такой код корректно работает для любых значений, включая Неопределено, NULL и ссылки. Если переменная содержит строку «100», проверка вернёт Ложь — и это правильно, потому что тип у неё строковый.
Для составных типов, например реквизита, который может хранить и число, и строку, проверка через ТипЗнч — единственный надёжный способ понять, что лежит в конкретном экземпляре. Учитывайте, что значение NULL из запроса и Неопределено — это не числа, и обрабатывать их нужно отдельно, иначе последующие арифметические операции вызовут ошибку.
Проверка строки на число через БСП
Если конфигурация построена на Библиотеке стандартных подсистем (БСП), в общем модуле СтроковыеФункцииКлиентСервер есть готовые функции. Чаще всего используют ТолькоЦифрыВСтроке(), которая проверяет, состоит ли строка исключительно из цифр.
Если СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(ВходнаяСтрока) Тогда
ЧисловоеЗначение = Число(ВходнаяСтрока);
КонецЕсли;
У функции есть второй параметр — учитывать ли лидирующие нули и пробелы, поведение зависит от версии БСП, поэтому перед использованием посмотрите сигнатуру в своей конфигурации. Важное ограничение: функция не распознаёт отрицательные числа и дробную часть, так как минус и разделитель — не цифры.
Если нужно проверить строку с возможным минусом и десятичным разделителем, потребуется собственная проверка или преобразование через ОписаниеТипов, описанное ниже.
Проверка через преобразование типов
Универсальный способ проверить, можно ли строку интерпретировать как число, — попытаться привести её к числовому типу через ОписаниеТипов. Метод ПривестиЗначение() не вызывает исключение при неудаче, а возвращает значение по умолчанию (ноль), что позволяет построить безопасную проверку.
Функция СтрокаЯвляетсяЧислом(ВходнаяСтрока)
ОписаниеЧисла = Новый ОписаниеТипов("Число");
Приведенное = ОписаниеЧисла.ПривестиЗначение(ВходнаяСтрока);
// Проверяем, что обратное преобразование совпадает с исходной строкой
Возврат СокрЛП(ВходнаяСтрока) = Формат(Приведенное, "ЧГ=");
КонецФункции
Альтернативный вариант — прямое преобразование Число(Строка) внутри конструкции Попытка/Исключение. Если строка не содержит число, возникнет исключение, которое можно перехватить и вернуть Ложь. Этот способ проще, но исключения работают медленнее при массовой обработке данных в цикле.
Попытка
Результат = Число(ВходнаяСтрока);
Исключение
Результат = Неопределено; // строка не является числом
КонецПопытки;
- 1Уберите лишние пробелы функцией СокрЛП()
- 2Замените запятую на точку, если ожидается дробное число из пользовательского ввода
- 3Попробуйте привести значение через ОписаниеТипов или Число() в Попытка/Исключение
- 4Сравните результат с ожиданиями: ноль из пустой строки и ноль реальный различайте
- 5Проверьте граничные случаи: пустая строка, минус, разделитель, буквы
Проверка числа в запросе
Иногда проверить тип нужно не в коде, а прямо в запросе — например, когда колонка результата имеет составной тип. В языке запросов 1С нет функции определения типа напрямую, но можно использовать выражение ВЫБОР с проверкой через ВЫРАЗИТЬ или сравнение с типом через ТИПЗНАЧЕНИЯ.
ВЫБРАТЬ
ВЫБОР
КОГДА ТИПЗНАЧЕНИЯ(Таблица.Значение) = ТИП(ЧИСЛО)
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК ЭтоЧисло
ИЗ ...
Функция ТИПЗНАЧЕНИЯ доступна в запросах начиная с платформы 8.1 и работает для полей составного типа. Для полей с однозначным типом такая проверка избыточна — тип известен из метаданных.
Типичные ошибки при проверке
Самая коварная проблема — пустая строка. Выражение Число("") возвращает 0 без исключения, поэтому проверка «если преобразовалось без ошибки, значит число» для пустой строки даст ложноположительный результат. Всегда проверяйте строку на пустоту до преобразования, если ноль для вас — осмысленное значение.
Вторая частая ошибка — региональные настройки при пользовательском вводе. В интерактивных полях ввода 1С сама обрабатывает разделитель согласно настройкам, но при программном разборе строки из файла разделитель нужно нормализовать вручную: СтрЗаменить(Строка, ",", ".").
Проверка результата и контрольные точки
Как проверить результат
Возвращает число 123
Исключение — проверьте, не строка ли с пробелами или буквами
Равен Тип("Число")
Возвращает Строка — реквизит составного типа или заполнен строкой
После замены запятой на точку — 12.5
Исключение или ноль — разделитель не нормализован
Обрабатывается отдельной веткой до преобразования
Молча превращается в 0 и попадает в расчёты
После внедрения проверки протестируйте её на граничных наборах данных: пустая строка, строка из пробелов, очень большое число, число с минусом, число с разделителем, строка с буквами. Каждый случай должен давать предсказуемый результат, а не исключение в рабочей базе.
Для массовой загрузки данных полезно собирать статистику нераспознанных значений в отдельный отчёт или журнал, а не просто пропускать их. Так вы увидите системные проблемы в исходных данных, например неправильный формат выгрузки из сторонней системы.
Что важно запомнить
Для готового значения проверяйте тип через ТипЗнч(Значение) = Тип("Число"). Для строки — приводите через ОписаниеТипов или Число() в Попытка/Исключение, предварительно нормализовав разделитель и отсеяв пустые строки. NULL и Неопределено обрабатывайте отдельно до арифметики.
Частые вопросы
Есть ли в 1С готовая функция «ЭтоЧисло»?
Встроенной функции с таким именем в языке нет. В БСП есть СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(), но она работает только со строками из цифр и не подходит для отрицательных и дробных чисел. Для полноценной проверки пишут собственную функцию на основе ОписаниеТипов или Попытка/Исключение.
Почему Число("123") иногда выдаёт ошибку?
Чаще всего в строке есть неразрывные пробелы, символы валюты или непечатаемые знаки, скопированные из Excel или веб-страницы. Обычный СокрЛП не удаляет неразрывный пробел — используйте СтрЗаменить с символом с кодом 160 или регулярную очистку перед преобразованием.
Как проверить число в тонком клиенте без БСП?
ТипЗнч и ОписаниеТипов доступны на клиенте без ограничений, поэтому оба метода работают. Попытка/Исключение также поддерживается. Если конфигурация без БСП, напишите свою функцию проверки в общем модуле с признаком «Клиент» и «Сервер».
Чем отличается NULL от Неопределено при проверке?
NULL возникает только в результатах запросов, например при левом соединении без совпадения. Неопределено — значение переменной по умолчанию в коде. Оба не являются числами, но проверяются по-разному: NULL — через «ЕСТЬ NULL» в запросе или сравнение с NULL в коде, Неопределено — прямым сравнением.
Как проверить, что число целое, а не дробное?
Сначала убедитесь, что значение числового типа, затем сравните его с результатом функции Цел(Значение). Если они равны, дробной части нет. Альтернатива — проверка остатка от деления на 1 через оператор %.
Можно ли проверить тип колонки таблицы значений заранее?
Да, через коллекцию Колонки таблицы значений: у каждой колонки есть свойство ТипЗначения. Метод СодержитТип(Тип("Число")) покажет, допускает ли колонка числовые значения, что полезно при динамическом построении таблиц.