Как отсечь незначащие нули в числовом поле высокой точности в 1С

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В процессе разработки и настройки прикладных решений на платформе 1С:Предприятие (особенно в конфигурациях на обычных формах, таких как Управление торговлей 10.3, УПП 1.3 или КА 1.1) программисты часто сталкиваются с эстетической и эргономической проблемой: отображением большого количества незначащих нулей в числовых полях высокой точности.

Например, если для реквизита табличной части задана точность в 5, 10 или даже 25 знаков после запятой (что бывает необходимо при расчете микродоз химических концентратов, драгметаллов или фармацевтических ингредиентов), платформа принудительно выводит в поле ввода значения вида 0,500000... вместо лаконичного 0,5. Попытки использовать стандартную опцию ФиксДробнаяЧасть в свойствах элемента формы часто не приносят желаемого результата.

В этой статье мы подробно рассмотрим, почему так происходит, и разберем как технические методы маскировки нулей на уровне интерфейса, так и более правильные архитектурные (методологические) подходы к организации учета малых величин.

Почему стандартные свойства 1С «не работают» при редактировании?

Давайте проанализируем поведение платформы 1С:Предприятие. Когда ячейка табличного поля на обычной форме находится в режиме просмотра, она отображает текстовое представление данных. В этот момент к ней применяются настройки свойства Формат (Format) колонки.

Однако, как только пользователь делает двойной клик по ячейке или начинает вводить данные, платформа активизирует полноценный элемент управления — ПолеВвода (TextBox). Этот элемент жестко связывается с типом данных реквизита базы данных. Если у реквизита в метаданных прописана точность, например, 25 знаков, элемент управления обязан предоставить пользователю возможность ввести число именно с такой точностью. Чтобы показать доступную разрядность ввода, платформа принудительно заполняет всё поле нулями до максимального предела точности. Скрыть их стандартными свойствами маски в момент ввода невозможно, так как система должна отличать незаполненные младшие разряды от реально введенных данных.

Ниже мы рассмотрим три способа решения этой проблемы, начиная с простых визуальных приемов и заканчивая реструктуризацией бизнес-логики.

Решение №1: Косметическая маскировка нулей в режиме просмотра

Если бизнес-требования допускают, чтобы лишние нули пропадали только тогда, когда пользователь перемещает фокус с ячейки, мы можем использовать событие табличной части ПриВыводеСтроки (OnRowOutput). Этот метод идеально подходит для обычных форм.

Суть метода заключается в том, что мы принудительно подменяем свойство Текст (Text) ячейки оформления, оставляя при этом реальное числовое значение в самом реквизите нетронутым. Система будет хранить точное число, но для «приятного глазу» отображения выведет только значащую часть.

Разберем по шагам реализацию этого механизма:

  1. Откройте форму документа или справочника, содержащую нужную табличную часть.
  2. Перейдите в свойства табличного поля и найдите событие ПриВыводеСтроки.
  3. Сгенерируйте обработчик события на сервере/клиенте и вставьте следующий код:

Процедура КомплектующиеПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    
    // Включаем режим ручного управления отображением текста в конкретной ячейке
    ОформлениеСтроки.Ячейки.Количество.ОтображатьТекст = Истина;
    
    // Применяем форматирование к числу, чтобы убрать лишние нули в режиме просмотра
    // Параметр ЧГ=0 убирает группировку триад цифр (пробелы между тысячами)
    ЗначениеКоличества = ДанныеСтроки.Количество;
    ОформлениеСтроки.Ячейки.Количество.Текст = Формат(ЗначениеКоличества, "ЧГ=0");
    
КонецПроцедуры

Важное примечание: Использование стандартной функции Формат() с пустой форматной строкой или без указания жесткой дробной части автоматически отсекает все незначащие нули справа. Например, число 0,500000 превратится в строку "0,5", а число 0,321400 — в строку "0,3214". При этом в режиме редактирования пользователь по-прежнему будет видеть полную сетку нулей, определяемую метаданными.

Решение №2: Использование текстового «прокси»-поля для полного скрытия нулей

Если руководство компании категорически требует, чтобы лишние нули не мозолили глаза пользователям даже во время непосредственного редактирования ячейки, стандартный механизм связи элемента управления с числовым реквизитом нам не подойдет. В этом случае мы можем прибегнуть к программной эмуляции ввода через текстовое поле.

Рассмотрим алгоритм реализации этого обходного пути:

  1. В табличном поле на форме создаем новую колонку. Назовем ее, например, КоличествоТекст.
  2. В свойствах этой колонки устанавливаем тип значения Строка. Данную колонку не связываем напрямую с реквизитом табличной части (оставляем свойство Данные пустым).
  3. Реальную числовую колонку Количество делаем невидимой на форме.
  4. При выводе строки заполняем текстовую колонку отформатированным строковым значением без нулей.
  5. При начале редактирования и изменении текстового поля пишем обработчики, которые переводят введенный текст обратно в число, валидируют его и записывают в скрытый числовой реквизит.

Разберем пример реализации кода для этого подхода:


// Функция для удаления незначащих нулей из строки числа
Функция ПолучитьЧислоБезНулей(ЗначениеЧисла) Экспорт
    ТекстЧисла = Формат(ЗначениеЧисла, "ЧГ=0");
    Если Найти(ТекстЧисла, ",") > 0 Тогда
        Пока Прав(ТекстЧисла, 1) = "0" Цикл
            ТекстЧисла = Лев(ТекстЧисла, СтрДлина(ТекстЧисла) - 1);
        КонецЦикла;
        Если  Прав(ТекстЧисла, 1) = "," Тогда
            ТекстЧисла = Лев(ТекстЧисла, СтрДлина(ТекстЧисла) - 1);
        КонецЕсли;
    КонецЕсли;
    Возврат ТекстЧисла;
КонецФункции

// Заполняем текстовое представление при выводе строк в таблицу
Процедура ТабличнаяЧастьПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    ОформлениеСтроки.Ячейки.КоличествоТекст.ОтображатьТекст = Истина;
    ОформлениеСтроки.Ячейки.КоличествоТекст.Текст = ПолучитьЧислоБезНулей(ДанныеСтроки.Количество);
КонецПроцедуры

// Обрабатываем ввод пользователя в текстовую ячейку
Процедура ТабличнаяЧастьКоличествоТекстПриИзменении(Элемент)
    СтрокаТЧ = ЭлементыФормы.ТабличнаяЧасть.ТекущиеДанные;
    Если СтрокаТЧ = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Заменяем точку на запятую для корректного преобразования в число
    ЧистаяСтрока = СтрЗаменить(Элемент.Значение, ".", ",");
    
    Попытка
        ЧисловоеЗначение = Число(ЧистаяСтрока);
        // Записываем результат в скрытый реальный числовой реквизит
        СтрокаТЧ.Количество = ЧисловоеЗначение;
    Исключение
        Предупреждение("Введено некорректное числовое значение!");
        Элемент.Значение = ПолучитьЧислоБезНулей(СтрокаТЧ.Количество);
    КонецПопытки;
КонецПроцедуры

Этот подход полностью решает визуальную проблему: пользователь взаимодействует исключительно с компактной текстовой строкой без навязчивых нулей, а система под капотом сохраняет полноценное число высокой точности. Минусом данного подхода является необходимость написания дополнительного кода валидации, контроля ввода спецсимволов и усложнение поддержки формы.

Решение №3: Изменение единиц учета и масштабирование (Архитектурный подход)

Как совершенно справедливо замечают опытные архитекторы и методологи учета 1С, техническая борьба со сверхвысокой точностью — это почти всегда следствие ошибок проектирования нормативно-справочной информации (НСИ).

Рассмотрим классический пример: на производство одной единицы продукции (например, флакона жидкого мыла объемом 1 литр) требуется 0,00015 кг (то есть 150 миллиграммов) редкого концентрированного красителя. Из-за того, что базовой единицей учета красителя выбран килограмм, разработчикам приходится увеличивать точность полей спецификации до 5-6 знаков после запятой, что приводит к появлению нечитаемых таблиц с «километрами» нулей.

Разберем два методологических пути решения этой проблемы, которые не требуют написания программного кода и не нагружают интерфейс системы.

Вариант А: Переход на более мелкие единицы хранения

Самым простым и логичным решением является перевод учета микро-компонентов на адекватные физические единицы хранения остатков. В системе 1С:Управление торговлей 10.3 для каждой номенклатурной позиции можно настроить базовую единицу хранения (в которой ведутся остатки в регистрах) и единицы для отчетов.

Если перевести единицу хранения красителя или химиката из «килограммов» (кг) в «миллиграммы» (мг) или «граммы» (г), то норма расхода в спецификации мгновенно превратится из неудобочитаемой дроби 0,00015 в понятное целое число 150. При этом на складе учет будет вестись с точностью до миллиграмма, а в управленческих отчетах руководство по-прежнему сможет видеть общие итоги в килограммах благодаря правильно настроенным коэффициентам пересчета единиц измерения.

Вариант Б: Изменение размера партии (кратности) в спецификации

Если бизнес-процессы компании жестко требуют вести учет сырья исключительно в крупных единицах (например, в тоннах или килограммах), существует второй классический прием — масштабирование спецификации.

Вместо того чтобы указывать нормы расхода комплектующих на выпуск одной бутылки готовой продукции, укажите в шапке спецификации выпуск партии объемом 1000 или 10 000 бутылок. При таком подходе расход сырья автоматически увеличится пропорционально размеру партии:

При оформлении выпуска продукции в документе «Отчет производства за смену» или «Выпуск продукции» система 1С автоматически пересчитает фактический расход материалов исходя из реального объема выпуска. Например, если фактически выпущена 1 бутылка, система разделит нормативный расход партии на 10 000 и спишет точные 0,00012 кг. Списание произойдет автоматически на уровне проведения документа, а пользователи в интерфейсе спецификаций будут видеть простые и понятные числа без нагромождения нулей.

Резюме и рекомендации

Подводя итоги нашего анализа, выделим ключевые рекомендации для разработчиков и аналитиков 1С:

← На главную