Как отобразить число с точностью, заданной пользователем, сохранив значащие нули?

Программист 1С v8.3 (Управляемые формы)
← На главную

Встречаемся с задачей, когда стандартное поведение платформы 1С для числовых полей не соответствует требованиям. Пользователь вводит в табличной части число, например, 0,5 или 0,010, а система автоматически форматирует его до вида 0,5000 или 0,0100, согласно заданной точности реквизита. Нам же нужно сохранить и отобразить именно тот вид, в котором число было введено, особенно когда важны конечные нули, указывающие на точность измерения или расчета.

Проанализируем ситуацию. Стандартный реквизит с типом Число хранит само значение, но не информацию о том, как оно было введено. Для системы числа 0,01 и 0,010 абсолютно идентичны. Следовательно, чтобы решить нашу задачу, нужно либо изменить способ хранения данных, либо гибко управлять их представлением на форме. Рассмотрим несколько подходов, которые помогут добиться желаемого результата.

Решение 1: Хранение данных в двух реквизитах

Один из самых прямолинейных и надежных методов, предложенных на форуме. Суть заключается в разделении данных для вычислений и данных для отображения.

Разберем по шагам:

  1. Создаем в табличной части два реквизита:
    • ЗначениеЧисло (тип Число) — этот реквизит будет использоваться для всех расчетов, суммирования и хранения числового значения. Его можно (и нужно) скрыть от пользователя, убрав видимость в свойствах колонки на форме.
    • ЗначениеПредставление (тип Строка) — этот реквизит будет виден пользователю. Именно в него он будет вводить данные и именно из него будет считываться отображаемое значение.
  2. Организуем синхронизацию между этими полями. Для этого в свойствах элемента формы (колонки ЗначениеПредставление) создадим обработчик события ПриИзменении.

Посмотрим на пример кода для события ПриИзменении:


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

Преимущества этого подхода:

Недостатки:

Решение 2: Хранение значения и его точности отдельно

Это более "академически" правильный подход, который разделяет сами данные (число) и метаданные о них (точность представления). Он идеально подходит для случаев, когда точность является важным бизнес-параметром.

Разберем по шагам:

  1. В табличной части создаем два реквизита:
    • Значение (тип Число) — для хранения самого числового значения. Это поле будет основным для расчетов.
    • ТочностьОтображения (тип Число) — служебный реквизит для хранения количества знаков после запятой, которое нужно отобразить. Этот реквизит делаем невидимым для пользователя.
  2. Основная сложность — определить точность, с которой пользователь ввел число. Поскольку событие ПриИзменении числового поля получает уже преобразованное число, мы теряем информацию о конечных нулях. Чтобы это обойти, можно временно назначить полю строковый тип, получить текст, определить точность, а затем вернуть числовой тип. Но это сложно.
    Более простой вариант — по-прежнему использовать строковое поле для ввода, как в Решении 1, но вместо хранения всей строки, вычислять из нее число и точность.
  3. Для отображения воспользуемся одним из двух механизмов платформы.

Вариант А: Динамическое форматирование через "Условное оформление"

Этот способ позволяет гибко настраивать внешний вид ячеек таблицы без написания кода в событиях, связанных с отрисовкой.

  1. Настраиваем условное оформление для нашей табличной части.
  2. Создаем несколько правил, по одному для каждой возможной точности.
    • Правило для точности 1:
      • Условие: ИмяТабличнойЧасти.ТочностьОтображения = 1
      • Оформление: Для поля Значение устанавливаем свойство Формат в значение "ЧДЦ=1; ЧГ=0".
    • Правило для точности 2:
      • Условие: ИмяТабличнойЧасти.ТочностьОтображения = 2
      • Оформление: Для поля Значение устанавливаем свойство Формат в значение "ЧДЦ=2; ЧГ=0".
    • ... и так далее для всех нужных уровней точности (например, до 4).

Когда значение в поле ТочностьОтображения будет меняться, платформа автоматически применит к ячейке соответствующий формат, и пользователь увидит число с нужным количеством знаков.

Вариант Б: Использование события ПриВыводеСтроки

Этот метод дает тот же визуальный эффект, но реализуется программно. Он полезен, когда логика форматирования сложнее, чем просто проверка значения.

Для табличного поля на форме нужно создать обработчик события ПриВыводеСтроки.


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

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

Итог и рекомендации

Выбор конкретного решения зависит от сложности задачи и общих требований к разработке.

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

← На главную