При разработке в среде «1С:Предприятие» программисты часто сталкиваются с ситуацией, когда при обращении к числовому реквизиту табличной части или переменной отсекаются незначащие нули в дробной части. Например, число 0,20 превращается в 0,2, а 12,20 превращается в 12,2. Если ваша задача требует дальнейшего разбора этого числа как строки (например, разделения по запятой на целую и дробную части), такое поведение платформы ломает логику алгоритма. Особенно часто эта проблема возникает при попытке работать с временными интервалами, записанными в числовом виде.
В этой статье мы подробно разберем, почему платформа 1С так обрабатывает числа, как правильно вернуть незначащие нули для текстового анализа и как переписать алгоритм работы со временем на надежные математические методы, избегая нестабильного строкового разбора.
Для начала проанализируем поведение самой платформы. В «1С:Предприятие» тип данных Число представляет собой десятичное число с фиксированной точностью. С точки зрения чистой математики и хранения данных в СУБД, числа 0,20 и 0,2 абсолютно тождественны. Хранение лишних нулей в оперативной памяти компьютера не имеет практического смысла, поэтому при получении значения из базы данных или при вычислениях платформа автоматически отсекает хвостовые незначащие нули.
Если в вашем коде присутствует логика, завязанная на строковом представлении числа (например, использование функции СтрРазделить() с поиском запятой), то попытка обработать число напрямую приведет к ошибке, так как вместо ожидаемой подстроки "20" вы получите "2".
---
Если вам все же критически необходимо получить строковое представление числа с фиксированным количеством знаков после запятой (включая незначащие нули), воспользуйтесь встроенной функцией 1С Формат(). Эта функция преобразует число в строку в соответствии с заданной маской форматирования.
Рассмотрим пример, когда нам нужно жестко зафиксировать два знака в дробной части:
ИсходноеЧисло = 12.20; // В памяти системы это 12.2
СтроковоеПредставление = Формат(ИсходноеЧисло, "ЧДЦ=2; ЧГ=0");
// Теперь СтроковоеПредставление гарантированно равно "12,20" (или "12.20" в зависимости от локали)
Разберем параметры управляющей строки формата:
ЧДЦ=2 (Число Десятичных Знаков) — указывает системе, что в дробной части должно быть ровно два знака. Если их меньше, платформа принудительно дополнит строку нулями справа.ЧГ=0 (Группировка) — отключает группировку триад цифр пробелами. Это крайне важно, так как при больших числах (например, 1000.20) без этого параметра функция вернет строку с неразрывным пробелом "1 000,20", что усложнит дальнейший разбор.---
Зачастую хранение времени в формате 12.20 (где подразумевается 12 часов и 20 минут) или в формате десятичной дроби (где 0.20 — это доля часа) является архитектурной ошибкой проектирования базы данных. Разбор такого числа через строки — крайне нестабильный процесс. Он зависит от региональных настроек сервера: разделителем дробной части может выступать как точка, так и запятая, из-за чего функция СтрРазделить(Строка, ",") на англоязычной операционной системе вернет пустой массив.
Давайте выясним, как получить составляющие времени без использования строк. Если в вашей системе число 12.20 означает именно 12 часов и 20 минут, мы можем применить простую математику для выделения минут:
ИсходноеЧисло = 12.20;
// Извлекаем целую часть (часы)
Часы = Цел(ИсходноеЧисло); // Результат: 12
// Вычитаем из исходного числа целую часть и умножаем остаток на 100
Минуты = Окр((ИсходноеЧисло - Часы) * 100); // Результат: 20
Этот способ полностью исключает работу со строками, работает мгновенно и не зависит от региональных настроек операционной системы или СУБД.
---
Если число в вашей системе является классической десятичной долей часа (то есть 1.2 часа — это 1 час и 20% от часа, что равняется 1 часу и 12 минутам), то строковый разбор по запятой в принципе математически неверен.
Проанализируем правильный алгоритм перевода десятичного числа в формат "Дни - Часы - Минуты" через перевод всей величины в секунды. Этот метод является наиболее профессиональным и отказоустойчивым:
// Предположим, у нас есть длительность движения в часах (например, 100.2 часа)
ДлительностьВЧасах = 100.2;
// Шаг 1. Переводим всё время в секунды
ВремяВСекундах = ДлительностьВЧасах * 3600; // 1 час = 3600 секунд
// Шаг 2. Вычисляем количество полных дней
Дней = Цел(ВремяВСекундах / 86400); // 1 день = 86400 секунд
// Шаг 3. Вычисляем остаток секунд после вычета дней и определяем часы
ОстатокСекунд = ВремяВСекундах % 86400;
Часов = Цел(ОстатокСекунд / 3600);
// Шаг 4. Вычисляем остаток секунд после вычета часов и определяем минуты
Минут = Окр((ОстатокСекунд % 3600) / 60);
// Шаг 5. Формируем красивое представление для пользователя
ВремяПрописью = Строка(Дней) + " дн. " + Строка(Часов) + " ч. " + Строка(Минут) + " м.";
// Результат: "4 дн. 4 ч. 12 м."
В данном алгоритме мы использовали оператор % (остаток от деления), который позволяет лаконично отсекать уже посчитанные временные интервалы без громоздких математических конструкций с вычитанием.
---
Если специфика вашей конфигурации такова, что пользователи должны вручную вводить значения вроде 12.20 и система обязана сохранять именно этот ввод без каких-либо математических округлений (например, это может быть некий внутренний шифр или специфический формат записи), то использование числового типа данных противопоказано.
В этом случае выполните следующие шаги:
Число на Строка с необходимой длиной.Число(), выполните вычисления, а результат форматируйте обратно в строку.---
Подводя итог, дадим важный совет по проектированию структуры метаданных. Хранение времени в виде дробных чисел — это мина замедленного действия, которая рано или поздно приведет к ошибкам округления или сбоям при интеграции с другими системами.
Рассмотрим две лучшие практики проектирования учета времени в 1С:
ДлительностьСекунд с типом Число(10, 0). Любые расчеты (сложение времени в пути, расчет средней скорости, суммирование трудозатрат в отчетах) будут выполняться мгновенно стандартными средствами платформы и языка запросов SQL. Перевод в читаемый вид (дни, часы, минуты) делайте только на клиенте при выводе на форму или в отчет.Дата (например, ДатаВыезда и ДатаПрибытия). Получить точную длительность в секундах можно простым вычитанием одной даты из другой прямо в коде или запросе: СекундВПути = ДатаПрибытия - ДатаВыезда;.