Разработка и Конфигурация · 10 мин
1С запрос: как число выразить строкой
Как в запросе 1С преобразовать число в строку: ограничения ВЫРАЗИТЬ, приёмы через ПОДСТРОКА и Формат(), типичные ошибки и готовые примеры кода.
Задача преобразовать число в строку прямо в тексте запроса 1С возникает регулярно: нужно склеить номер документа с префиксом, сравнить числовое поле со строковым, сформировать представление для отчёта на СКД. Проблема в том, что язык запросов 1С не содержит прямой функции «число в строку» — конструкция ВЫРАЗИТЬ(Поле КАК Строка) для числовых типов не работает и вызывает ошибку при выполнении запроса.
Обойти ограничение можно несколькими способами: через приведение строки к числу с обратной стороны сравнения, через функцию ПОДСТРОКА с хитрым приёмом, через вычисляемые поля СКД или через перенос преобразования на уровень встроенного языка с функцией Формат(). Каждый вариант имеет свои ограничения по производительности и читаемости.
Ниже разобраны рабочие приёмы с примерами кода, условия их применимости и типичные ошибки, которые приводят к неожиданным результатам — например, к потере лидирующих нулей или несрабатыванию соединений таблиц.
Почему ВЫРАЗИТЬ не преобразует число в строку
Функция ВЫРАЗИТЬ в языке запросов 1С предназначена для уточнения типа поля: сузить составной тип до одного значения, ограничить длину строки или точность числа. Она не выполняет конвертацию между несовместимыми типами. Число и строка — несовместимые типы, поэтому запись ВЫРАЗИТЬ(Сумма КАК Строка(20)) завершится ошибкой вида «Несовместимые типы ВЫРАЗИТЬ».
При этом обратное преобразование тоже не работает напрямую: ВЫРАЗИТЬ(СтроковоеПоле КАК Число) вызовет ошибку, если в строке есть нечисловые символы. Платформа просто не умеет интерпретировать произвольный текст как число в рамках запроса.
Это архитектурное ограничение, а не недоработка конкретной версии: оно одинаково действует в управляемых и обычных формах, в файловом и клиент-серверном режимах. Поэтому решать задачу нужно обходными путями.
Приём с ПОДСТРОКА: преобразование внутри запроса
Классический обходной приём основан на том, что число можно «встроить» в строковый литерал через конкатенацию, а затем извлечь функцией ПОДСТРОКА. Однако конкатенация числа со строкой в запросе тоже запрещена, поэтому приём работает иначе: числовое значение сначала приводится к строке на стороне передачи параметра или через соединение с таблицей, где число уже хранится как строка.
На практике чаще используется обратная задача — сравнить числовое поле со строковым. В этом случае надёжнее преобразовать строку к числу на стороне условия, если строка гарантированно числовая, либо сравнивать строковые представления, подготовленные заранее в параметрах запроса:
Запрос.Текст =
"ВЫБРАТЬ
| Док.Номер КАК Номер
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Док
|ГДЕ
| Док.Номер = &НомерСтрокой";
Запрос.УстановитьПараметр("НомерСтрокой", "000000042");
Ключевой момент: если номер документа строковый, а вам известно числовое значение, передавайте в параметр уже отформатированную строку с лидирующими нулями. Сам запрос за вас форматирование не выполнит.
Преобразование через вычисляемые поля СКД
Если запрос используется в схеме компоновки данных, самое чистое решение — вычисляемое поле. В нём доступен почти весь встроенный язык выражений СКД, включая функцию Формат(), которая преобразует число в строку по заданному шаблону.
Порядок настройки: на закладке «Вычисляемые поля» добавьте поле, укажите путь к данным, например СуммаСтрокой, а в выражении напишите Формат(Сумма, "ЧГ=0"). После этого поле доступно для вывода в отчёт, группировок и отборов как обычная строка.
Форматные строки дают гибкость: "ЧН=0" подставляет ноль вместо пустого значения, "ЧГ=0" убирает разделители групп разрядов, "ЧЦ=10; ЧВН=" дополняет число лидирующими нулями до заданной длины. Это удобно для вывода номеров и кодов в фиксированном формате.
Формат(Номер, "ЧЦ=11; ЧВН=; ЧГ=0") // число 42 -> "00000000042"Преобразование на встроенном языке после выборки
Когда запрос возвращает таблицу значений или выборку, преобразование часто разумнее выполнить уже в модуле — при обходе результата. Это самый производительный и предсказуемый вариант, потому что СУБД не тратит ресурсы на строковые операции, а вы контролируете формат каждого значения.
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СуммаСтрокой = Формат(Выборка.Сумма, "ЧДЦ=2; ЧРД=,; ЧГ=0");
НомерСтрокой = Формат(Выборка.НомерЧислом, "ЧЦ=8; ЧВН=; ЧГ=0");
КонецЦикла;
Для целых чисел без особых требований к формату достаточно функции Строка(Число) или неявного преобразования при конкатенации: "Заказ № " + Число. Но помните: неявное преобразование вставляет разделители групп для больших чисел в некоторых контекстах, поэтому для кодов и номеров всегда используйте Формат() с явным шаблоном.
Если строковое представление нужно многократно — например, для последующих соединений в пакете запросов — добавьте вычисляемую колонку в таблицу значений и заполните её в цикле, затем передайте таблицу обратно в запрос как параметр-источник.
- 1Определите, где нужна строка: в самом запросе, в отчёте СКД или в коде после выборки
- 2Для СКД добавьте вычисляемое поле с Формат()
- 3Для кода используйте Формат() или Строка() при обходе результата
- 4Для сравнений передавайте в параметр готовую строку нужного формата
- 5Проверьте результат на значениях с лидирующими нулями и дробной частью
Сравнение числовых и строковых полей в соединениях
Частая прикладная задача — соединить таблицы, где в одной код хранится числом, а в другой строкой. Прямое соединение Т1.Код = Т2.Код вернёт пустой результат, потому что типы не совпадают. ВЫРАЗИТЬ здесь не поможет ни в одну сторону.
Рабочие варианты: привести данные к единому типу на этапе подготовки (например, во временной таблице, заполненной кодом с преобразованием), либо использовать функцию ПОДСТРОКА совместно с конкатенацией строкового литерала для усечения, если строковый код имеет известный префикс. Универсального «красивого» решения внутри запроса нет — это сигнал, что преобразование стоит вынести на уровень кода.
| Подход | Где работает | Ограничение |
|---|---|---|
| Вычисляемое поле с Формат() | Отчёты на СКД | Не участвует в соединениях внутри запроса |
| Формат() в коде после выборки | Любой модуль | Требует обхода результата |
| Параметр с готовой строкой | Условия ГДЕ | Формат готовит вызывающий код |
| Временная таблица с подготовленным полем | Пакетные запросы | Дополнительный цикл заполнения |
Сравнение вариантов
Лучший выбор для отчётов: формат задаётся декларативно, но поле нельзя использовать в соединениях самого запроса
Универсально и быстро, но требует обхода выборки и ручного контроля шаблона
Подходит для отборов по одному значению; не масштабируется на соединения таблиц
Типичные ошибки и как их избежать
Самая распространённая ошибка — попытка написать ВЫРАЗИТЬ(Сумма КАК Строка(20)) и удивление ошибке «Несовместимые типы». Запомните: ВЫРАЗИТЬ только уточняет тип, но не конвертирует значение.
Вторая ошибка — потеря лидирующих нулей. Если число 42 должно стать строкой «00000042», простое преобразование даст «42». Решение — форматная строка "ЧЦ=8; ЧВН=", где ЧВН с пустым значением включает вывод ведущих нулей.
Третья ошибка — разделители групп разрядов. Строка(1234567) может дать «1 234 567» с неразрывными пробелами, что сломает дальнейшие сравнения и выгрузки. Всегда добавляйте "ЧГ=0" в форматную строку, если нужен «чистый» числовой текст.
Проверка результата и границы применимости
Проверяйте преобразование на граничных значениях: ноль, отрицательное число, число с дробной частью, максимальное значение по разрядности поля. Для дробных чисел явно задавайте ЧДЦ и разделитель ЧРД, иначе результат зависит от региональных настроек сеанса.
Отдельно проверьте поведение с NULL: функция Формат() для NULL вернёт пустую строку или значение по умолчанию в зависимости от контекста. Если NULL возможен, обработайте его через ЕСТЬNULL в запросе или через проверку в коде.
Если преобразование нужно массово — например, для выгрузки миллиона записей — замерьте время на реальных данных. Вычисляемые поля СКД и строковые операции в запросе заметно дороже, чем обход выборки с Формат() в коде.
Как проверить результат
Только цифры, без пробелов и разделителей
Неразрывные пробелы между группами разрядов
Длина строки соответствует ЧЦ, нули на месте
Строка короче шаблона, нули потеряны
Ожидаемое число знаков и нужный разделитель
Разделитель зависит от настроек сеанса
Пустая строка или явная замена через ЕСТЬNULL
Ошибка или непредсказуемое значение
Что важно запомнить
Прямого преобразования числа в строку в запросе 1С нет. Для отчётов используйте вычисляемые поля СКД с Формат(), для кода — Формат() при обходе выборки, для отборов — готовые строковые параметры. Всегда задавайте шаблон с ЧГ=0 и при необходимости ЧВН= для лидирующих нулей.
Частые вопросы
Почему ВЫРАЗИТЬ(Сумма КАК Строка(20)) выдаёт ошибку?
ВЫРАЗИТЬ не конвертирует значения между несовместимыми типами, а только уточняет тип поля — длину строки, точность числа или конкретный тип из составного. Число в строку этим оператором преобразовать нельзя, используйте Формат() в коде или вычисляемое поле СКД.
Как получить строку с лидирующими нулями из числа?
Примените функцию Формат() с шаблоном вида "ЧЦ=10; ЧВН=; ЧГ=0". Параметр ЧВН с пустым значением включает вывод ведущих нулей, ЧЦ задаёт общую длину, ЧГ=0 убирает разделители групп разрядов.
Можно ли сравнить числовое поле со строкой в условии ГДЕ?
Напрямую — нет, типы должны совпадать. Передайте в параметр запроса строку, заранее отформатированную под хранимый формат (с лидирующими нулями, если они есть), либо приведите данные к одному типу на этапе подготовки временной таблицы.
Почему в строке из числа появляются пробелы?
Это разделители групп разрядов (неразрывные пробелы), которые добавляет преобразование по умолчанию. Чтобы получить «чистые» цифры, используйте Формат() с параметром "ЧГ=0".
Что быстрее: вычисляемое поле СКД или Формат() в коде?
Для крупных выборок обход результата с Формат() в коде обычно предсказуемее и не нагружает СУБД строковыми операциями. Вычисляемые поля удобнее для отчётов, где результат сразу выводится пользователю без дополнительной обработки.
Как преобразовать NULL в строку?
Функции преобразования для NULL дают пустой результат или значение по умолчанию. Надёжнее обработать NULL заранее: в запросе через ЕСТЬNULL(Поле, 0), а затем уже форматировать полученное число.