Работа с числовыми данными в запросах 1С — одна из самых распространённых задач при разработке отчётов, обработок и интеграций. Однако не всегда исходные данные хранятся в нужном формате: строки с цифрами, даты, булевы значения или даже пустые поля требуют преобразования в числовой тип перед математическими операциями. Ошибки на этом этапе ведут к сбоям в расчётах, искажению отчётности или падению производительности.

В этой статье разберём все способы преобразования данных в число прямо в тексте запроса: от стандартных функций ЧИСЛО() и ВЫРАЗИТЬ() до нюансов работы с NULL, локализацией и оптимизацией. Особое внимание уделим типичным ошибкам, которые допускают даже опытные разработчики, и покажем, как их избежать на практике.

Материал актуален для платформ 1С:Предприятие 8.3 и 8.2, но с учётом особенностей синтаксиса каждой версии. Если вы работаете с унаследованными конфигурациями или мигрируете на новую платформу, здесь найдёте решения для обоих случаев.

📊 Как часто вы сталкиваетесь с преобразованием типов в запросах 1С?
Ежедневно
Несколько раз в неделю
Редко
Никогда

1. Стандартные функции для преобразования в число

Базовый инструмент для преобразования — функция ЧИСЛО(). Она принимает один аргумент (строку, дату или булево значение) и возвращает число, если преобразование возможно. Синтаксис:

ЧИСЛО(Выражение)

Примеры использования:

  • 📌 ЧИСЛО("123.45") → вернёт 123.45 (число с плавающей точкой).
  • 📅 ЧИСЛО(ДАТАВРЕМЯ(2023, 12, 31)) → вернёт количество дней с 1899 года (внутренний формат даты в 1С).
  • ЧИСЛО(ИСТИНА) → вернёт 1, а ЧИСЛО(ЛОЖЬ)0.

Функция ВЫРАЗИТЬ() более универсальна: она позволяет явно указать целевой тип, что полезно для сложных преобразований:

ВЫРАЗИТЬ(Выражение КАК Число(Длина, Точность))

Где Длина — общая длина числа (включая знаки), а Точность — количество знаков после запятой. Например:

ВЫРАЗИТЬ("1234.567" КАК Число(10, 2))

Этот код округлит число до двух знаков после запятой, результат: 1234.57.

💡

Если в строке содержатся нечисловые символы (например, валюта "$100"), функция ЧИСЛО() вернёт ошибку. Используйте СОКРЛП() или СТРЗАМЕНИТЬ() для предварительной очистки данных.

2. Обработка NULL и пустых значений

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

ЧИСЛО(ЕСТЬNULL(ПолеТаблицы, "0"))

Альтернативный вариант — конструкция ВЫБОР КОГДА:


ВЫБОР

КОГДА ПолеТаблицы ЕСТЬ NULL ТОГДА 0

ИНАЧЕ ЧИСЛО(ПолеТаблицы)

КОНЕЦ

Важно! Пустая строка ("") и NULL — разные вещи. Для пустых строк можно использовать:

ЧИСЛО(ВЫБОР КОГДА ДЛСТР(ПолеТаблицы) = 0 ТОГДА "0" ИНАЧЕ ПолеТаблицы КОНЕЦ)
⚠️ Внимание: В некоторых конфигурациях пустые строки могут интерпретироваться как NULL в зависимости от настроек СУБД. Всегда тестируйте запросы на реальных данных!

3. Локализация и разделители

Формат чисел зависит от региональных настроек базы. Например, в российской локализации разделителем дробной части служит запятая (123,45), а в европейской — точка (123.45). Если строка содержит "чужой" разделитель, функция ЧИСЛО() вернёт ошибку.

Решения:

  • 🌍 Замените разделитель перед преобразованием: ЧИСЛО(СТРЗАМЕНИТЬ(Поле, ".", ",")).
  • 📊 Используйте ВЫРАЗИТЬ() с явным указанием формата (работает не во всех версиях платформы).
  • 🔧 Настройте параметры сеанса: УстановитьПараметрСеанса("ЧисловойФормат", "1;.,").

Для универсальных решений (например, при обмене данными между базами с разными локалями) лучше хранить числа в стандартном формате без привязки к разделителям.

Локаль Разделитель целой и дробной части Разделитель тысяч Пример
Русская (RU) , пробел 1 234,56
Английская (EN) . , 1,234.56
Немецкая (DE) , . 1.234,56
Французская (FR) , пробел 1 234,56

4. Преобразование даты в число

В даты хранятся как количество дней с 01.01.0001, но в запросах их часто нужно преобразовать в числовой формат для расчётов. Например, чтобы посчитать разницу между датами в днях:

ЧИСЛО(ДатаОкончания) - ЧИСЛО(ДатаНачала)

Для извлечения отдельных компонент даты (год, месяц, день) используйте функции:

  • 📅 ГОД(Дата), МЕСЯЦ(Дата), ДЕНЬ(Дата) — возвращают числа.
  • ЧАС(ДатаВремя), МИНУТА(ДатаВремя) — для времени.

Внутренний формат даты в 1С — это число дней с 1 января 1 года н.э., где 1 января 1900 года = 693961. Это значение можно использовать для проверки корректности преобразований.

Как работает внутренний формат даты в 1С?

В 1С дата хранится как количество дней с 01.01.0001. Например:

- 01.01.0001 = 1

- 01.01.1900 = 693596

- 01.01.2000 = 730120

- 01.01.2023 = 738505

Это позволяет быстро вычислять разницу между датами и выполнять арифметические операции.

5. Оптимизация запросов с преобразованиями

Преобразование типов в запросах может значительно замедлить выполнение, особенно на больших объёмах данных. Следующие рекомендации помогут оптимизировать производительность:

  1. Переносите преобразования в виртуальные таблицы. Если возможно, создайте вычисляемое поле в виртуальной таблице вместо преобразования в основном запросе.
  2. Используйте индексы. Если часто преобразуете одно и то же поле, добавьте вычисляемый индекс в конфигураторе.
  3. Избегайте вложенных функций. Заменяйте конструкции вида ЧИСЛО(ЕСТЬNULL(Поле, "0")) на ВЫБОР КОГДА Поле ЕСТЬ NULL ТОГДА 0 ИНАЧЕ ЧИСЛО(Поле) — они выполняются быстрее.

Для анализа производительности используйте ПланВыполненияЗапроса():


Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ЧИСЛО(Поле) КАК ЧисловоеПоле ИЗ Таблица";

План = Запрос.ПланВыполнения();

⚠️ Внимание: В некоторых версиях платформы оптимизатор запросов может игнорировать индексы при использовании функций преобразования. Тестируйте запросы на реальных данных!

Использовать виртуальные таблицы для вычисляемых полей

Проверить наличие индексов на часто преобразуемых полях

Заменить вложенные функции на ВЫБОР КОГДА

Проанализировать план выполнения запроса-->

6. Типичные ошибки и их решения

Даже опытные разработчики сталкиваются с ошибками при преобразовании типов. Рассмотрим наиболее частые случаи:

Ошибка Причина Решение
Ошибка преобразования значения к типу Число Строка содержит нечисловые символы (буквы, знаки валюты). Очистите строку с помощью СОКРЛП() или СТРЗАМЕНИТЬ().
Переполнение при преобразовании к типу Число Число превышает допустимый диапазон (например, слишком большая дата). Используйте ВЫРАЗИТЬ(..., КАК Число(15, 0)) для увеличения разрядности.
Некорректный результат при работе с датами Не учтён внутренний формат даты (дни с 01.01.0001). Вычитайте ДАТАВРЕМЯ(1,1,1) для получения дней с начала отсчёта.
Медленное выполнение запроса Преобразования применяются к большому объёму данных без индексов. Перенесите логику в виртуальные таблицы или добавьте вычисляемые поля.

Если ошибка возникает при работе с NULL, проверьте настройки СУБД: в некоторых случаях пустые значения могут интерпретироваться как строки, а не как NULL.

💡

Всегда проверяйте исходные данные на наличие нечисловых символов, особенно при импорте из внешних источников (Excel, XML, JSON).

7. Практический пример: преобразование в отчёте

Рассмотрим реальный пример: нужно создать отчёт, который рассчитывает среднюю стоимость товара из строкового поля ЦенаТекст (хранит данные в формате "1 234,56 руб.").

Исходный запрос с ошибкой:


ВЫБРАТЬ

ЧИСЛО(ЦенаТекст) КАК ЦенаЧисло

ИЗ

Товары

Этот запрос завершится с ошибкой из-за нечисловых символов. Исправленный вариант:


ВЫБРАТЬ

ЧИСЛО(

СТРЗАМЕНИТЬ(

СТРЗАМЕНИТЬ(

СОКРЛП(ЦенаТекст),

" ",

""

),

"руб.",

""

)

) КАК ЦенаЧисло

ИЗ

Товары

Для ускорения работы можно добавить вычисляемое поле в конфигуратор или использовать виртуальную таблицу.

💡

Если формат цены стандартный (например, всегда "X XXX,XX руб."), используйте регулярные выражения для очистки данных. В 1С 8.3.14+ доступна функция РЕГВЫР().

8. Альтернативные подходы: встроенный язык vs SQL

Иногда преобразования удобнее выполнять не в запросе, а на уровне встроенного языка. Например:


// В модуле отчёта

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ЦенаТекст ИЗ Товары";

Результат = Запрос.Выполнить();

Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл

ЦенаЧисло = Число(СтрЗаменить(СокрЛП(Выборка.ЦенаТекст), " ", ""));

// Дальнейшая обработка

КонецЦикла;

Плюсы подхода:

  • 🔧 Больше гибкости: можно использовать любые функции встроенного языка.
  • 📈 Лучшая читаемость кода для сложных преобразований.

Минусы:

  • ⏳ Медленнее, чем преобразование в запросе (особенно на больших выборках).
  • 🔄 Требует дополнительной памяти для хранения промежуточных данных.

Для максимальной производительности комбинируйте оба подхода: простые преобразования оставляйте в запросе, сложные — выносите на уровень встроенного языка.

⚠️ Внимание: При работе с большими базами данных (100 000+ записей) избегайте массовых преобразований в цикле. Используйте пакетную обработку или временные таблицы.

FAQ: Частые вопросы по преобразованию в число

Как преобразовать строку с пробелами в число (например, "1 234")?

Используйте функцию СТРЗАМЕНИТЬ() для удаления пробелов:

ЧИСЛО(СТРЗАМЕНИТЬ("1 234", " ", ""))

Для автоматической очистки от всех нечисловых символов подойдёт комбинация СОКРЛП() и регулярных выражений (в версиях 8.3.14+).

Почему ЧИСЛО() возвращает ошибку для пустой строки?

Пустая строка не может быть преобразована в число. Используйте конструкцию:

ЧИСЛО(ВЫБОР КОГДА ДЛСТР(Строка) = 0 ТОГДА "0" ИНАЧЕ Строка КОНЕЦ)

Или замените пустые строки на NULL и обработайте через ЕСТЬNULL().

Как преобразовать булево значение в число (1 или 0)?

Функция ЧИСЛО() автоматически преобразует ИСТИНА в 1, а ЛОЖЬ в 0. Пример:

ЧИСЛО(Товар.ПометкаУдаления) // Вернёт 1, если товар помечен на удаление

Для обратного преобразования используйте ВЫБОР КОГДА Число = 1 ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ.

Можно ли преобразовать число обратно в строку с разделителями?

Да, используйте функцию ФОРМАТ():

ФОРМАТ(1234.56, "ЧДЦ=2; ЧРД= ; ЧГ=неразрывный пробел")

Результат: "1 234,56" (с пробелом как разделителем тысяч и запятой для дробной части).

Как ускорить запрос с множественными преобразованиями?

Оптимизируйте запрос следующими способами:

  1. Перенесите преобразования в виртуальные таблицы.
  2. Добавьте вычисляемые поля в конфигуратор сready-to-use числовыми значениями.
  3. Используйте временные таблицы для промежуточных расчётов.
  4. Замените вложенные функции на ВЫБОР КОГДА.

Для анализа узких мест используйте ПланВыполненияЗапроса().