При работе с языком запросов 1С:Предприятие программисты часто сталкиваются с необходимостью преобразования числовых данных в строковый формат непосредственно в теле запроса. Казалось бы, стандартная функция Строка() должна работать предсказуемо, однако на практике можно получить крайне неожиданные результаты: исчезновение запятой, пропажу ведущих нулей или добавление странных хвостов из нулей. Рассмотрим подробно, почему это происходит и как правильно обрабатывать такие ситуации.
Проанализируем типичную ситуацию, с которой сталкиваются разработчики. Допустим, у нас есть дробное число, которое мы принудительно приводим к определенной точности с помощью ВЫРАЗИТЬ, а затем пытаемся получить его строковое представление. Рассмотрим пример кода запроса:
ВЫБРАТЬ
ВЫРАЗИТЬ(0.56 КАК ЧИСЛО(15, 10)) КАК ЧисловоеПоле,
Строка(ВЫРАЗИТЬ(0.56 КАК ЧИСЛО(15, 10))) КАК СтрокаСВыразить,
Строка(0.56) КАК ПрямаяСтрока
На различных версиях платформы 8.3 результат может варьироваться самым неожиданным образом:
Выясним причину такого поведения. Проблема кроется во взаимодействии трех факторов: механизмов платформы 1С, используемой СУБД (SQL Server или PostgreSQL) и региональных настроек сервера.
Когда мы используем функцию Строка() в запросе, платформа 1С не выполняет форматирование сама. Она транслирует эту команду в SQL-оператор CAST(Field AS VARCHAR). Если перед этим было использовано ВЫРАЗИТЬ(... КАК ЧИСЛО(15, 10)), то в базе данных создается временный контейнер типа numeric/decimal с фиксированной точностью 10 знаков после запятой.
Разберем, что происходит внутри СУБД:
(15, 10).CAST в строку, некоторые версии SQL-серверов выдают «сырое» представление данных.5600000000), либо потерю символа разделителя, если настройки локали СУБД и сервера приложений не совпали.Проанализируем ситуацию с исчезновением нуля (результат вида ",56"). Это классическое поведение для некоторых конфигураций PostgreSQL. При преобразовании типа numeric в text, если число меньше единицы, PostgreSQL может не выводить ведущий ноль. Платформа 1С должна «подправлять» этот результат перед выдачей пользователю, но в ряде релизов (например, в ветках 8.3.20 и начале 8.3.22) наблюдались ошибки, когда эта правка не срабатывала.
Как показывает практика и обсуждения специалистов, поведение функции сильно зависит от версии платформы 1С. Посмотрим на результаты тестов на разных релизах:
",56")."0,56".Рассмотрим несколько подходов к решению задачи, от наиболее правильных до обходных путей.
Если ваша цель — просто вывести данные на экран пользователю в отчете или списке, вместо Строка() следует использовать ПРЕДСТАВЛЕНИЕ(). Разберем разницу:
Строка() — пытается получить строковое значение на уровне базы данных. Оно пригодно для использования в ОБЪЕДИНИТЬ или для строковых операций внутри запроса.ПРЕДСТАВЛЕНИЕ() — это инструкция платформе 1С получить форматированную строку. Форматирование в этом случае происходит на стороне сервера 1С или клиента с учетом всех региональных настроек и без участия логики преобразования типов СУБД.Пример правильного вывода для интерфейса:
ВЫБРАТЬ
ПРЕДСТАВЛЕНИЕ(ВЫРАЗИТЬ(0.56 КАК ЧИСЛО(15, 10))) КАК ПолеДляПользователя
Проанализируем ситуацию, когда нам нужно программно обработать результат. Опытные разработчики рекомендуют правило: «Запрос для данных, код для оформления». Вместо того чтобы мучиться с функцией Строка() в запросе, получите числовое значение и примените к нему функцию Формат() в коде на языке 1С.
Рассмотрим пример кода:
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
Для Каждого СтрокаРезультата Из РезультатЗапроса Цикл
// Используем стандартную функцию Формат для гарантированного результата
СтроковоеЗначение = Формат(СтрокаРезультата.ЧисловоеПоле, "ЧЦ=15; ЧДЦ=2; ЧГ=0");
КонецЦикла;
Этот метод гарантирует, что разделитель будет соответствовать настройкам системы, а ведущие нули не пропадут независимо от версии платформы или типа СУБД.
Если использование Строка() в запросе неизбежно (например, вы строите сложное условие связи или используете ОБЪЕДИНИТЬ), проверьте следующие моменты:
Подводя итог, можно сказать, что функция Строка() внутри запроса для дробных чисел — механизм нестабильный. Выяснив причину (зависимость от CAST в SQL), мы понимаем, что наиболее надежным способом всегда будет получение чистого числа и его последующая обработка средствами встроенного языка 1С.