К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как определить, строка или число, в 1С

Как в 1С определить, является ли значение строкой или числом: ТипЗначения, ОписаниеТипов, проверка содержимого строки, примеры кода и типичные ошибки.

Задача определить, является ли значение строкой или числом, возникает в 1С постоянно: при обработке данных из файлов, проверке реквизитов составного типа, валидации пользовательского ввода и конвертации данных между системами. Встроенный язык 1С даёт несколько инструментов для этого — от функции ТипЗначения() до самостоятельного разбора содержимого строки посимвольно.

Важно различать две разные задачи. Первая — определить тип значения, который уже хранится в переменной или реквизите: это делается напрямую через метаданные типа. Вторая — понять, можно ли содержимое строки интерпретировать как число: здесь тип переменной всегда «Строка», и проверять нужно сам текст. Оба сценария разобраны ниже с готовыми примерами кода.

Ошибки при определении типа приводят к типичным проблемам: сортировка чисел как строк («10» раньше «2»), падение запросов при сравнении несовместимых типов, некорректная конвертация с потерей данных. Правильная проверка до выполнения операций избавляет от большинства таких сбоев.

Проверка типа значения через ТипЗначения()

Базовый способ узнать тип переменной или реквизита — функция ТипЗначения(Значение). Она возвращает объект типа «Тип», который сравнивают с нужным типом через функцию Тип():

Если ТипЗнч(Значение) = Тип("Число") Тогда

// работаем как с числом

ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда

// работаем как со строкой

КонецЕсли;

Обратите внимание: встроенная функция называется ТипЗнч() — это сокращённый синоним ТипЗначения(), оба варианта работают одинаково. В качестве параметра Тип() передаётся строковое имя типа: «Число», «Строка», «Дата», «Булево», а для ссылочных типов — имя объекта метаданных, например Тип("СправочникСсылка.Номенклатура").

Такой подход корректно работает с реквизитами составного типа. Если поле объекта может хранить и строку, и число, проверка ТипЗнч() покажет фактический тип текущего значения, а не состав возможных типов реквизита.

Как узнать допустимые типы реквизита объекта

Иногда нужно понять не тип конкретного значения, а какие типы вообще допускает реквизит. Для этого используют метаданные: у объекта метаданных реквизита есть свойство Тип — объект «ОписаниеТипов».

ОписаниеТиповРеквизита = Метаданные.Документы.РеализацияТоваровУслуг.Реквизиты.Комментарий.Тип;

Если ОписаниеТиповРеквизита.СодержитТип(Тип("Строка")) Тогда

// реквизит может хранить строку

КонецЕсли;

Метод СодержитТип() возвращает Истина, если указанный тип входит в список допустимых. Дополнительно у описания типов доступны квалификаторы: для строки — длина и допустимая длина (фиксированная или переменная), для числа — разрядность и разрядность дробной части. Это полезно при универсальных обработках, которые работают с произвольными объектами конфигурации.

Как проверить, что строка содержит число

Самая частая практическая задача: есть строка (из файла, от пользователя, из веб-сервиса), и нужно понять, является ли её содержимое числом. Простое преобразование Число("123") не подходит для проверки: для некорректной строки оно вызовет исключение, а для строки с нечисловыми символами в некоторых случаях вернёт 0 или выдаст ошибку в зависимости от содержимого.

Способ через ОписаниеТипов

Надёжный вариант без исключений — приведение значения через ОписаниеТипов:

ОписаниеЧисла = Новый ОписаниеТипов("Число");

Результат = ОписаниеЧисла.ПривестиЗначение(ПроверяемаяСтрока);

Если Результат = 0 И СокрЛП(ПроверяемаяСтрока) <> "0" Тогда

// строка не является числом либо приведение не удалось

КонецЕсли;

Метод ПривестиЗначение() не вызывает исключение: при невозможности приведения он возвращает значение по умолчанию для типа (для числа — 0). Недостаток очевиден: строка «0» и нечисловая строка дадут одинаковый результат, поэтому требуется дополнительная проверка, как в примере выше.

Способ через посимвольный разбор

Когда нужен строгий контроль формата (например, допускаются только цифры и одна точка), строку разбирают посимвольно:

Функция ЭтоЧисло(Стр)

Стр = СокрЛП(Стр);

Если Стр = "" Тогда

Возврат Ложь;

КонецЕсли;

Допустимые = "0123456789.,-";

Для Поз = 1 По СтрДлина(Стр) Цикл

Если СтрНайти(Допустимые, Сред(Стр, Поз, 1)) = 0 Тогда

Возврат Ложь;

КонецЕсли;

КонецЦикла;

Возврат Истина;

КонецФункции

Такой подход позволяет задать собственные правила: запретить минус, разрешить только запятую как разделитель, ограничить количество знаков после разделителя. Во многих конфигурациях есть готовые функции проверки в общих модулях (например, в БСП — функции работы со строками), стоит сначала поискать существующую реализацию, чтобы не дублировать код.

Порядок проверки строки на число
  1. 1
    Уберите пробелы функцией СокрЛП() — они частая причина ложных срабатываний
  2. 2
    Проверьте строку на пустоту: пустая строка не число
  3. 3
    Проверьте допустимые символы посимвольно или через ПривестиЗначение()
  4. 4
    При успехе выполните преобразование Число() и проверьте результат на контрольном примере

Проверка типа в запросах 1С

В языке запросов функции ТипЗнч() нет, но есть свои механизмы. Оператор ВЫРАЗИТЬ(... КАК Число(15,2)) приводит значение к указанному типу, а проверка типа значения выполняется через конструкцию ТИПЗНАЧЕНИЯ(Поле) = ТИП(Число) — так можно фильтровать записи с составными реквизитами.

ВЫБРАТЬ

ВЫБОР

КОГДА ТИПЗНАЧЕНИЯ(Таблица.Значение) = ТИП(ЧИСЛО)

ТОГДА "Число"

КОГДА ТИПЗНАЧЕНИЯ(Таблица.Значение) = ТИП(СТРОКА)

ТОГДА "Строка"

ИНАЧЕ "Другое"

КОНЕЦ КАК ТипЗначения

ИЗ ...

При сравнении полей разных типов в условии запроса платформа может вернуть ошибку несовместимости типов. Поэтому поля составного типа перед сравнением приводят через ВЫРАЗИТЬ — это и защита от ошибки, и способ явно задать правила сравнения.

Тонкости преобразования и региональные настройки

Разделитель дробной части — источник большинства проблем. Функция Число() во встроенном языке ожидает точку как разделитель, а данные из Excel, CSV или пользовательского ввода часто содержат запятую. Перед преобразованием строку нормализуют:

Стр = СтрЗаменить(СокрЛП(СтрокаИзФайла), ",", ".");

Результат = Число(Стр);

Дополнительные подводные камни: неразрывные пробелы как разделители разрядов («1 000 000»), символы валют, экспоненциальная запись из внешних систем. Перед преобразованием такие строки очищают: убирают пробелы через СтрЗаменить(Стр, " ", "") и символ неразрывного пробела (Символ(160) или Символы.НПП), отсекают посторонние суффиксы.

Типичные ошибки
01
Проверка Число(Строка) = 0 как признак нечисла: строка «0» даёт тот же результат, проверка ненадёжна
02
Забытый СокрЛП(): строка с пробелом «123 » не проходит строгую посимвольную проверку
03
Сравнение строки и числа в запросе без ВЫРАЗИТЬ: ошибка несовместимости типов или пустой результат
04
Игнорирование разделителя: запятая вместо точки приводит к исключению при Число()
05
Проверка типа реквизита вместо типа значения: составной реквизит хранит конкретный тип, который и нужно анализировать

Практический выбор способа проверки

Выбор инструмента зависит от того, что именно проверяется. Для значения в переменной или реквизите достаточно ТипЗнч() — это быстро и однозначно. Для строки из внешнего источника нужна проверка содержимого: ПривестиЗначение() с контролем нуля подходит для простых случаев, посимвольный разбор — для строгих форматов.

Маршрут решения

Как выбрать способ

Нужно узнать тип переменной или значения реквизитаИспользуйте ТипЗнч(Значение) = Тип("Число") или Тип("Строка")
Нужно понять, какие типы допускает реквизит конфигурацииОбратитесь к метаданным: Реквизит.Тип.СодержитТип()
Нужно проверить, что строка из файла или ввода — числоНормализуйте строку и примените ОписаниеТипов.ПривестиЗначение() или посимвольную проверку
Проверка выполняется в запросеИспользуйте ТИПЗНАЧЕНИЯ(Поле) = ТИП(ЧИСЛО) и ВЫРАЗИТЬ для приведения

После любой проверки полезно выполнить контрольное преобразование на известных примерах: «0», «0,5», «-12», «1 000», «abc». Если функция корректно отличает числа от нечисел на этом наборе, она готова к использованию в рабочем коде.

Итог

Что важно запомнить

Тип значения определяется через ТипЗнч(), допустимые типы реквизита — через метаданные и ОписаниеТипов, а числовое содержимое строки — через ПривестиЗначение() или посимвольный разбор с предварительной нормализацией разделителей и пробелов.

Частые вопросы

Чем ТипЗнч() отличается от ТипЗначения()?

Ничем по сути: это два имени одной функции встроенного языка. ТипЗнч() — краткий синоним, оба варианта возвращают объект «Тип» и взаимозаменяемы в любом коде.

Почему Число("12,5") вызывает ошибку, а Число("12.5") работает?

Функция Число() ожидает точку как разделитель дробной части независимо от региональных настроек сеанса. Строку с запятой нужно предварительно обработать через СтрЗаменить().

Как проверить тип значения в запросе, если поле составного типа?

Используйте конструкцию ТИПЗНАЧЕНИЯ(Поле) = ТИП(ЧИСЛО) в условии или в ВЫБОР...КОГДА. Для приведения поля к конкретному типу применяйте ВЫРАЗИТЬ(Поле КАК Число(15,2)).

ПривестиЗначение() вернул 0 — значит, строка не число?

Не обязательно: метод возвращает 0 и для строки «0», и для нечисловой строки. Дополнительно сравните исходную строку с «0» после СокрЛП() или используйте посимвольную проверку.

Как проверить строку на целое число без дробной части?

Посимвольной проверкой с допустимым набором только из цифр и, при необходимости, знака минус в первой позиции. Альтернатива — привести строку к числу и сравнить результат с Цел(Результат): совпадение означает целое значение.

Есть ли готовые функции проверки в типовых конфигурациях?

В конфигурациях на базе Библиотеки стандартных подсистем есть общие модули для работы со строками и типами. Перед написанием собственной функции проверьте существующие модули конфигурации — это уменьшает дублирование кода.