Разработчики, работающие с платформой 1С:Предприятие 7.7, нередко сталкиваются с ситуацией, когда результат умножения цены на количество внезапно «теряет» свою дробную часть. На первый взгляд ситуация кажется мистической: в коде производятся стандартные арифметические операции, однако на печать или в документ выводится округленное до целого число. При этом округление может происходить как по математическим правилам, так и простым отсечением дробной части (в меньшую сторону).
В рамках данной статьи мы подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы платформы 1С 7.7 и рассмотрим по шагам методы борьбы с некорректным отображением и расчетом дробных чисел.
Как показывает практика и реальный опыт разработчиков, наиболее частой причиной «исчезновения» копеек является банальная настройка отображения данных в печатной форме (макете). Сама переменная в оперативной памяти компьютера может содержать абсолютно точное значение с любым количеством знаков после запятой, но при выводе в таблицу платформа принудительно скрывает дробную часть.
Выясним, как работает форматирование в табличных документах 1С 7.7. Для вывода числовых данных используется форматная строка. Она может быть задана двумя способами:
#, а за ним следует специальный код формата.Синтаксис форматной строки для числовых показателей имеет вид Ч<Длина>.<Точность>, где Длина — общее количество символов, отводимых под число, а Точность — количество знаков в дробной части.
Рассмотрим примеры настройки отображения переменной СуммаТО:
СуммаТО#Ч15.2, то число будет выведено строго с двумя знаками после запятой (например, 723.37).СуммаТО#Ч15.0 или просто использовать базовый числовой формат без указания точности (например, Ч), платформа автоматически округлит число до целого значения при выводе на экран или печать. В результате число 723.37 превратится в 723.Решение: Проверьте свойства проблемной ячейки в макете табличного документа. Убедитесь, что в поле «Формат» или непосредственно в выражении ячейки после символа # указана необходимая точность (как минимум два знака для денежных сумм, например, Ч15.2).
Вторая распространенная проблема кроется в неявном преобразовании строковых данных в числовой тип. Зачастую исходные данные (например, цены из внешних файлов, текстовых выгрузок или API) приходят в систему в виде текстовых строк.
Рассмотрим классический некорректный пример кода:
ЦенаТО = "723.37"; // Строковое значение цены с точкой в качестве разделителя
СуммаТО = К1 * ЦенаТО; // Попытка умножения числа на строку
В 1С 7.7 при попытке выполнить арифметическую операцию со строкой платформа пытается выполнить неявное преобразование типов. Однако этот процесс критически зависит от региональных стандартов операционной системы Windows, установленной на сервере или компьютере пользователя.
Разберем этот механизм по шагам:
,). Точка (.) при этом считается недопустимым символом для числа."723.37"), процесс преобразования мгновенно останавливается."723.37" превращается в целое число 723. Соответственно, при умножении на любое количество мы получаем результат без копеек, округленный в меньшую сторону.Для решения этой проблемы необходимо полностью отказаться от хранения чисел в строковом формате в кодовой части программы. Все математические операции должны производиться только над переменными числового типа. Если же получения строки не избежать, необходимо выполнить принудительное и безопасное преобразование.
Проанализируем пример безопасного преобразования строки в число:
// Исходная строка, полученная из внешнего источника
ЦенаСтрока = "723.37";
// Принудительно заменяем точку на запятую, чтобы соответствовать русской локали Windows
ПодготовленнаяСтрока = СтрЗаменить(ЦенаСтрока, ".", ",");
// Выполняем явное преобразование типов с помощью встроенной функции Число()
ЦенаЧисло = Число(ПодготовленнаяСтрока);
// Теперь умножение пройдет корректно с сохранением дробной части
СуммаТО = К1 * ЦенаЧисло;
Этот простой прием гарантирует, что дробная часть не будет утеряна вне зависимости от того, какой символ (точка или запятая) используется в качестве разделителя в региональных настройках операционной системы конкретного пользователя.
Если расчет производится корректно, на печать данные выводятся с копейками, но после сохранения документа в базу данных копейки бесследно исчезают, проблему следует искать в структуре метаданных конфигурации.
В конфигураторе 1С 7.7 для каждого числового реквизита (будь то реквизит документа, справочника, табличной части или ресурс регистра) разработчик жестко задает два базовых параметра:
Если для реквизита Сумма установлена точность, равная 0, то при записи объекта в базу данных (в файлы таблиц DBF или таблицы СУБД MS SQL) СУБД автоматически выполнит округление до целого числа. Платформа произведет эту операцию молча, без вывода каких-либо предупреждений или ошибок в журнал регистрации.
Решение: Откройте конфигуратор, найдите соответствующий документ или справочник, перейдите в свойства числового реквизита и убедитесь, что параметр «Точность» установлен в значение 2 (или более, если требуется особая точность, например, для цен или коэффициентов).
Когда программисту требуется округлить число непосредственно в коде для выполнения дальнейших расчетов, используется стандартная функция платформы Окр(). Синтаксис функции выглядит следующим образом:
Окр(<Число>, <Точность>, <Способ>)
Важно понимать нюансы работы третьего параметра — Способ. Он управляет тем, как система округляет пограничные значения (когда первая отбрасываемая цифра равна 5):
Окр(1.5, 0, 0) вернет число 1.Окр(1.5, 0, 1) вернет число 2.Посмотрим на пример правильного математического округления суммы до копеек в кодовой базе:
Цена = 723.37;
Количество = 1.15;
СуммаБезОкругления = Количество * Цена; // Получаем 831.8755
// Округляем до 2 знаков по математическим правилам
СуммаИтоговая = Окр(СуммаБезОкругления, 2, 1); // Результат: 831.88
Подводя итоги нашего анализа проблемы ложного округления в 1С 7.7, сформулируем краткий чек-лист для предотвращения подобных ошибок в будущем:
Число().СтрЗаменить().#Ч15.2).Окр() всегда явно указывайте третий параметр в значении 1, если вам требуется классическое математическое округление.