Идея дня
A1sO.NumOrZero(X)— возвращает число из X или 0, если значения нет/нечисло.A1sO.RoundNum(X, Точность = 2)— округляет число по заданной разрядности; на вход допускает «нечисло» (вернёт корректно округлённыйNumOrZero(X)).- Комбинируйте с
A1sO.Empty/NotEmpty(см. День 10) и используйте единообразно во всём проекте.
Почему это важно
- В формах и интеграциях часто прилетают пустые строки, Неопределено, «N/A» —
NumOrZeroспасает от падений. - Округление «как везде» делает отчёты сопоставимыми.
RoundNum— единый слой поверх платформеннойОкр. - Логика «0 ≠ пусто» сохраняется (см. День 10): ноль — валидное значение.
Базовые примеры
NumOrZero: дефолт 0 вместо «пусто/нечисло»
Сообщить( A1sO.NumOrZero(15) ); // 15
Сообщить( A1sO.NumOrZero("12.34") ); // 12.34 (строка → число)
Сообщить( A1sO.NumOrZero("") ); // 0
Сообщить( A1sO.NumOrZero(Неопределено) ); // 0
Сообщить( A1sO.NumOrZero("N/A") ); // 0
RoundNum: стандартное округление к 2 знакам
Сообщить( A1sO.RoundNum(12.345) ); // 12.35
Сообщить( A1sO.RoundNum("12.3", 1) ); // 12.3
Сообщить( A1sO.RoundNum("", 2) ); // 0.00 (пусто → 0 → округлить)
Паттерн «вход → нормализовать → округлить»
Ввод из формы: приводим к числу, затем округляем к нужной точности (например, 2 для денег).
Функция НормализоватьСумму(Значение, Точность = 2) Экспорт
Число = A1sO.NumOrZero(Значение);
Возврат A1sO.RoundNum(Число, Точность);
КонецФункции
// Пример
СуммаВвода = " 1 234,567 "; // как пришло из UI/интеграции
Сумма = НормализоватьСумму(СуммаВвода, 2); // → 1234.57
С A1sQ: суммирование и округления
ТекстQ = "
|ВЫБРАТЬ
| Док.СуммаДокумента КАК Amount
|ИЗ Документ.РеализацияТоваровУслуг КАК Док
|ГДЕ Док.Дата МЕЖДУ &Начало И &Конец
";
Нач = НачалоДня(ТекущаяДата());
Кон = КонецДня(ТекущаяДата());
Рез = A1sQ.ExecuteQ(ТекстQ, Нач, Кон);
Вб = Рез.Выбрать();
Итого = 0;
Пока Вб.Следующий() Цикл
Итого = Итого + A1sO.NumOrZero(Вб.Amount);
КонецЦикла;
// Финальное округление, например, к 2 знакам:
Итого = A1sO.RoundNum(Итого, 2);
A1sLog.Info("Day13", "ИТОГО за день: " + Формат(Итого, "ЧГ=15.2"));
Округление количества/цен и итогов
Функция ОкруглитьПозицию(Кол, Цена, ТочнКол = 3, ТочнЦена = 2) Экспорт
КолН = A1sO.RoundNum(A1sO.NumOrZero(Кол), ТочнКол);
ЦенаН = A1sO.RoundNum(A1sO.NumOrZero(Цена), ТочнЦена);
Сумма = A1sO.RoundNum(КолН * ЦенаН, ТочнЦена);
Возврат Новый Структура("Кол,Цена,Сумма", КолН, ЦенаН, Сумма);
КонецФункции
// Пример
Стр = ОкруглитьПозицию("1,2345", "99.995"); // Кол=1.235, Цена=100.00, Сумма=123.50
Контроль ввода и сообщения пользователю
Ноль — валидно, «пусто/нечисло» — заменяем на 0 и сообщаем.
Процедура ПринятьВводЦены(ТекстЦены) Экспорт
БылоПусто = A1sO.Empty(ТекстЦены);
Цена = A1sO.NumOrZero(ТекстЦены); // нормализуем
Цена = A1sO.RoundNum(Цена, 2); // округляем
Если БылоПусто Тогда
A1sLog.Warn("Day13", "Цена не задана — подставлен 0.00");
КонецЕсли;
Сообщить("Цена к записи: " + Формат(Цена, "ЧГ=15.2"));
КонецПроцедуры
Анти-паттерны
- Хранить деньги с «длинным хвостом» и округлять только в выводе — округляйте по правилам домена при записи.
- Рely на неявные преобразования строк в число — всегда используйте
NumOrZero. - Округлять каждый член выражения отдельно, когда правило требует округлять итог — различайте уровни округления.
Микро-утилиты
Сумма колонки ТаблицаЗначений с безопасной нормализацией
Функция SumSafe(Таб, Колонка, ТочностьИтога = 2) Экспорт
Если A1sO.Empty(Таб) Тогда Возврат 0; КонецЕсли;
Итог = 0;
Для каждого Стр Из Таб Цикл
Итог = Итог + A1sO.NumOrZero(Стр[Колонка]);
КонецЦикла;
Возврат A1sO.RoundNum(Итог, ТочностьИтога);
КонецФункции
Безопасное деление (на случай нулевого делителя)
Функция DivSafe(Числитель, Знаменатель, Точность = 2) Экспорт
A = A1sO.NumOrZero(Числитель);
B = A1sO.NumOrZero(Знаменатель);
Если B = 0 Тогда Возврат 0; КонецЕсли;
Возврат A1sO.RoundNum(A / B, Точность);
КонецФункции
Практика (15–30 минут)
- Замените ручные
Если ПустаяСтрока/ПопыткаЧислонаNumOrZeroв одном модуле. - Примените
RoundNumпри записи суммы документа и при расчёте «Кол × Цена». - Сделайте
SumSafeи посчитайте безопасный итог по колонкеAmountпослеUnload. - Используйте
DivSafeв отчёте, где возможен нулевой делитель.
Чек-лист
- □ Везде нормализую вход в число через
NumOrZero. - □ Правильно выбираю уровень округления (позиция / итог).
- □ Итоги и показатели округляю через
RoundNumс единой точностью.
Что дальше
День 14: A1sO — Заполнение объектов (FillObject) — удобная и безопасная инициализация реквизитов.