Как ввести значение времени больше 24 часов в поле ввода 1С?

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

При разработке прикладных решений нередко возникает задача учета длительности или отработанного времени, значение которого превышает 24 часа (например, 150 часов 30 минут). Разработчики часто пытаются настроить стандартное поле ввода с типом Дата, рассчитывая обойтись параметрами форматной строки. Рассмотрим, почему этот подход не работает на уровне платформы и какими способами можно правильно решить данную задачу.

Причина проблемы и ограничения платформы

В платформе «1С:Предприятие 8» отсутствует отдельный примитивный тип данных для хранения временных интервалов или продолжительности (Duration/Interval). Примитивный тип Дата предназначен исключительно для фиксации конкретной календарной точки во времени в диапазоне от 0001-01-01 00:00:00 до 3999-12-31 23:59:59.

Даже если в метаданных или свойствах элемента формы установить свойство «Состав даты = Время», реквизит физически продолжает оставаться полной датой. При этом параметры форматной строки Ч или ЧЧ жестко привязаны к суточному циклу: платформа воспринимает часы строго в диапазоне от 0 до 23 (или от 1 до 12 при 12-часовом формате). Попытка вывести или ввести значение вида 150:00:00 через форматную строку даты принципиально невозможна. Поэтому для реализации длительности свыше 24 часов необходимо изменить модель хранения и ввода данных.

Способ 1. Хранение в секундах и ввод через строку с парсингом

Проанализируем наиболее универсальный подход для хранения длительности. Для хранения значения в базе данных лучше всего использовать реквизит с типом Число(10, 0) (общее количество секунд) или Число(10, 2) (дробное количество часов). Это позволяет в дальнейшем без проблем суммировать показатели в запросах, регистрах и отчетах.

Для организации удобного пользовательского ввода на управляемой форме создадим строковый реквизит формы (например, ДлительностьСтрокой) и свяжем его с полем ввода. Разберем по шагам, как настроить преобразование:

  1. При открытии формы преобразуем числовое значение секунд из объекта в формат ЧЧЧ:ММ:СС.
  2. В событии поля ввода ПриИзменении выполняем обратный разбор строки, валидацию введенных данных и пересчет в секунды.

Посмотрим на пример серверных и клиентских процедур для обработки такой строки:


&НаКлиенте
Процедура ДлительностьСтрокойПриИзменении(Элемент)
    
    ЧастиВремени = СтрРазделить(ДлительностьСтрокой, ":");
    
    КоличествоЧастей = ЧастиВремени.Количество();
    Если КоличествоЧастей = 0 Тогда
        Объект.ДлительностьВСекундах = 0;
        ДлительностьСтрокой = "00:00:00";
        Возврат;
    КонецЕсли;
    
    Попытка
        Часы = Число(ЧастиВремени[0]);
        Минуты = ?(КоличествоЧастей > 1, Число(ЧастиВремени[1]), 0);
        Секунды = ?(КоличествоЧастей > 2, Число(ЧастиВремени[2]), 0);
    Исключение
        ВызватьИсключение "Некорректный формат времени. Используйте шаблон ЧЧЧ:ММ:СС";
    КонецПопытки;
    
    Если Минуты >= 60 Или Секунды >= 60 Или Часы < 0 Или Минуты < 0 Или Секунды < 0 Тогда
        ВызватьИсключение "Минуты и секунды должны быть в диапазоне от 0 до 59";
    КонецЕсли;
    
    Объект.ДлительностьВСекундах = Часы * 3600 + Минуты * 60 + Секунды;
    ДлительностьСтрокой = СтрШаблон("%1:%2:%3", 
        Формат(Часы, "ЧЦ=10; ЧВН=; ЧГ="), 
        Формат(Минуты, "ЧЦ=2; ЧВН=; ЧГ="), 
        Формат(Секунды, "ЧЦ=2; ЧВН=; ЧГ="));
    
КонецПроцедуры

Способ 2. Использование трех отдельных числовых полей

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

  1. Создаем на форме реквизиты: ИнтервалЧасы (тип Число(6, 0)), ИнтервалМинуты (тип Число(2, 0)) и при необходимости ИнтервалСекунды (тип Число(2, 0)).
  2. Добавляем на форму элементы и помещаем их в группу с видом Обычная группа без выделения и группировкой Горизонтальная если возможно.
  3. У полей минут и секунд в свойствах настраиваем параметры минимального и максимального значения: от 0 до 59.
  4. В событиях ПриИзменении числовых полей рассчитываем результирующее значение для реквизита объекта.

Посмотрим на пример обработчика:


&НаКлиенте
Процедура ПересчитатьИнтервалВСекунды()
    
    Если ИнтервалМинуты > 59 Тогда
        ИнтервалМинуты = 59;
    КонецЕсли;
    
    Если ИнтервалСекунды > 59 Тогда
        ИнтервалСекунды = 59;
    КонецЕсли;
    
    Объект.ДлительностьВСекундах = ИнтервалЧасы * 3600 + ИнтервалМинуты * 60 + ИнтервалСекунды;
    
КонецПроцедуры

Способ 3. Строковое поле с маской ввода

В качестве быстрого решения можно применить маску ввода для строкового поля формы. Для этого в свойствах элемента управления задается свойство Маска, например: 999:99:99.

Однако при использовании маски важно учитывать существенные ограничения:

  1. Фиксированная разрядность: маска 999:99:99 жестко ограничивает ввод тремя знаками часов. Ввести 1000 часов без программной смены маски пользователь не сможет.
  2. Отсутствие логической проверки: маска проверяет лишь ввод цифр, поэтому пользователь сможет ввести значение 150:99:99, что потребует обязательной программной проверки в событии ПриИзменении.
  3. Особенности интерфейса «Такси»: маски ввода могут создавать неудобства при редактировании отдельных символов и вставке значений через буфер обмена.

Резюме: для работы со временем свыше 24 часов стандартный тип Дата не подходит. Оптимальным решением является хранение общего количества секунд в числовом реквизите объекта с организацией пользовательского ввода через парсинг строки или раздельные горизонтальные числовые поля.

← На главную