При разработке отчетов в 1С:Предприятие часто возникает задача вывести суммарное время (длительность) в часах и минутах. Стандартный системный формат времени ДФ=ЧЧ:мм отлично работает, пока общее количество часов не превышает 23. Как только сумма минут достигает 1440 (24 часа), стандартное форматирование «обнуляет» часы, переходя на новые сутки. Например, 5000 минут вместо ожидаемых 83:20 превратятся в 11:20 (так как 83 часа — это 3 полных дня и 11 часов).
Ситуация осложняется требованием заказчика: при сохранении или выгрузке отчета в Excel значение должно остаться числовым. Это необходимо для того, чтобы в самом Excel пользователь мог суммировать эти ячейки или использовать их в формулах. Рассмотрим, как решить эту задачу, используя возможности табличного документа 1С и особенности хранения данных в офисных приложениях.
Функция Формат() в 1С предназначена для работы с типом Дата. Внутреннее устройство типа Дата подразумевает конкретный момент времени (день, месяц, год, час...). Когда мы пытаемся вывести «83 часа», 1С воспринимает это как дату, отстоящую от начала календаря, и показывает только время внутри последних суток. Нам же нужно отобразить интервал или длительность.
Для решения мы разделим задачу на две части: формирование правильного текста для отображения в 1С и подготовка данных для корректного распознавания в Excel.
Первым делом проанализируем, как программно получить строку вида «83:20» из произвольного количества минут. Для этого нам понадобится простая целочисленная арифметика. Разберем алгоритм вычисления:
// Предположим, у нас есть переменная ВсегоМинут = 5000;
ЦелыхЧасов = Цел(ВсегоМинут / 60);
ОстатокМинут = ВсегоМинут % 60; // используем остаток от деления
// Формируем строковое представление
// Для минут добавим лидирующий ноль, если их меньше 10
ПредставлениеВремени = Формат(ЦелыхЧасов, "ЧГ=0") + ":" + Формат(ОстатокМинут, "ЧЦ=2; ЧВН=");
В данном примере Формат(ЦелыхЧасов, "ЧГ=0") гарантирует, что в числе не будет разделителей групп разрядов (пробелов), а ЧВН= обеспечит вывод «05» вместо «5» для минут.
Чтобы в 1С мы видели красивую строку «83:20», а Excel получил число, мы воспользуемся свойствами объекта ОбластьЯчеек. У каждой ячейки табличного документа есть три критически важных для нас свойства:
СодержитЗначение — булево флаг, указывающий, что ячейка не просто текст.Значение — фактические данные (число, дата и т.д.).Текст — то, что видит пользователь на экране.Проанализируем ситуацию с точки зрения Excel. В Excel время хранится как число, где 1 единица равна 24 часам. Следовательно, 1 час — это 1/24, а 1 минута — это 1/(24*60), то есть 1/1440. Чтобы Excel понял наше число как время, мы должны передать ему «долю суток».
Рассмотрим код заполнения ячейки:
// ВсегоМинут = 5000;
Область = ТабДок.Область(Строка, Колонка);
Область.СодержитЗначение = Истина;
Область.ТипЗначения = Новый ОписаниеТипов("Число");
// Записываем значение в формате, который поймет Excel (доля суток)
Область.Значение = ВсегоМинут / 1440;
// Устанавливаем визуальное представление для пользователя в 1С
Часов = Цел(ВсегоМинут / 60);
Минут = ВсегоМинут - (Часов * 60);
Область.Текст = Формат(Часов, "ЧГ=0") + ":" + Формат(Минут, "ЧЦ=2; ЧВН=");
Важный момент: Если вы просто запишете в значение число 5000, Excel при попытке форматирования в «Время» интерпретирует это как 5000 дней. Поэтому деление на 1440 (количество минут в сутках) обязательно.
Для удобства использования в отчетах или СКД (Системе компоновки данных), целесообразно оформить логику в виде функции. Рассмотрим пример функции, которая преобразует секунды (часто хранящиеся в базе) в удобный формат, учитывая требования по выводу длительности:
Функция ФорматДлительности(Знач ВсегоСекунд) Экспорт
Если ВсегоСекунд = 0 Или ВсегоСекунд = Неопределено Тогда
Возврат "00:00";
КонецЕсли;
ЦелыхЧасов = Цел(ВсегоСекунд / 3600);
ОстатокМинут = Цел((ВсегоСекунд % 3600) / 60);
// Формируем строку hhhh:mm
Результат = СтрШаблон("%1:%2",
Формат(ЦелыхЧасов, "ЧГ=0"),
Формат(ОстатокМинут, "ЧЦ=2; ЧВН="));
Возврат Результат;
КонецФункции
Использование СтрШаблон позволяет сделать код более читаемым. Вы можете расширить эту функцию, добавив вывод секунд, если это требуется по условиям задачи.
После того как мы программно сформировали отчет, пользователь сохраняет его в формате .xlsx. При открытии файла в Excel мы увидим наше число (например, 3.47222...). Чтобы оно превратилось в «83:20», в самом Excel ячейка должна иметь специальный формат.
К сожалению, при стандартном сохранении из 1С (ТабДок.Записать()), платформа не всегда может передать специфический макрос формата [h]:mm. Квадратные скобки вокруг «h» в Excel — это ключевой символ, который дает команду: «не сбрасывай часы в 0 после 24, а продолжай накопление».
Если требуется, чтобы файл открывался сразу в идеальном виде без ручной настройки пользователем, проанализируем вариант с использованием COM-соединения (если отчет формируется на стороне клиента под ОС Windows):
Попытка
ExcelApp = Новый COMОбъект("Excel.Application");
Книга = ExcelApp.Workbooks.Add();
Лист = Книга.Worksheets(1);
// Передаем значение
Лист.Cells(1, 1).Value = ВсегоМинут / 1440;
// Устанавливаем специальный числовой формат Excel
Лист.Cells(1, 1).NumberFormat = "[h]:mm";
ExcelApp.Visible = Истина;
Исключение
Сообщить("Excel не установлен");
КонецПопытки;
Подведем итоги нашего исследования. Для корректного отображения длительности более 24 часов с сохранением числовой природы данных необходимо:
Текст для вывода строки hhhh:mm, рассчитанной вручную через Цел() и % (остаток от деления).Значение записывать число минут, деленное на 1440 (перевод в формат «сутки» для Excel).[h]:mm в Excel, либо использовать прямое управление через COM/библиотеки для формирования файлов.Рассмотренный метод позволяет обойти ограничения стандартной маски форматирования 1С и предоставляет пользователю отчет, пригодный для дальнейшего анализа и математических вычислений в сторонних редакторах таблиц.