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