Как в отчете 1С пересчитать минуты в формат «часы и минуты»?

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

При разработке отчетов в 1С часто возникает задача представить длительность, которая хранится в базе в минутах, в удобном для пользователя виде — например, вместо «150 мин» вывести «2 ч 30 мин». В этой статье мы подробно разберем, как реализовать такой пересчет, используя Систему компоновки данных (СКД), и как избежать типичных ошибок при подсчете итогов в отчете.

Разберем ситуацию: почему стандартный подход документа не подходит для отчета напрямую?

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


Функция ОбновитьНадписьВремя() Экспорт 
    ВремяДляНадписи = УчетРабочегоВремени.Итог("ИтогоОтработано") / 60;
    ВремяЧасы = Цел(ВремяДляНадписи);
    ВремяМинуты = Формат((ВремяДляНадписи - ВремяЧасы) * 60, "ЧЦ=2; ЧДЦ=0");
    ЗаголовокВремяНадписи = "" + ВремяЧасы + " ч " + ВремяМинуты + " мин";
    НадписьВремя = ?(СокрЛП(ЗаголовокВремяНадписи) = "0 ч 00 мин", "", ЗаголовокВремяНадписи);
КонецФункции

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

Решение 1: Использование функции общего модуля

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

  1. Создадим общий модуль (например, с именем РаботаСоВременем).
  2. Установим свойства модуля: Сервер, Внешнее соединение.
  3. Добавим в него функцию, которая принимает количество минут и возвращает строку:

Функция ПолучитьДлительностьТекстом(Знач ДлительностьВМинутах) Экспорт
    
    Если ДлительностьВМинутах = 0 Или ДлительностьВМинутах = Неопределено Тогда
        Возврат "";
    КонецЕсли;
    
    КолЧасов = Цел(ДлительностьВМинутах / 60);
    КолМинут = ДлительностьВМинутах % 60; // Получаем остаток от деления на 60
    
    ТекстЧасов = ?(КолЧасов > 0, Формат(КолЧасов, "ЧГ=0") + " ч ", "");
    ТекстМинут = ?(КолМинут > 0, Формат(КолМинут, "ЧЦ=2; ЧВН=") + " мин", "");
    
    Возврат СокрЛП(ТекстЧасов + ТекстМинут);
    
КонецФункции

Важное замечание: В некоторых примерах предлагают использовать конструкцию Дата(1,1,1) + Минуты * 60. Мы настоятельно рекомендуем избегать этого метода. Если количество минут превысит 1440 (24 часа), 1С обнулит часы и начнет отсчет новых суток, что приведет к потере данных в отчетах за большие периоды. Математический расчет через Цел() и % (остаток от деления) лишен этого недостатка.

Настройка вызова функции в СКД

Теперь разберем, как вызвать эту функцию внутри схемы компоновки данных. Перейдем на закладку «Вычисляемые поля» и добавим новое поле:

Здесь СуммаМинут — это имя вашего поля из набора данных, в котором хранятся исходные числа.

Решение 2: Настройка ресурсов для корректных итогов

Частая проблема: в детальных записях отчет выводит «1 ч 30 мин», а в строке «Итого» либо пусто, либо выводится ошибка. Выясним причину: СКД пытается применить функцию к итоговому значению, но настройки ресурсов заданы неверно.

Чтобы итоги считались правильно, перейдем на закладку «Ресурсы»:

  1. Выберите ваше поле ВремяПредставление (или то поле, где должен быть текст).
  2. В колонке «Выражение» напишите: РаботаСоВременем.ПолучитьДлительностьТекстом(Сумма(ИтогоОтработано))

Проанализируем это выражение: Сначала СКД выполняет агрегатную функцию Сумма(), складывая все минуты (числа) по группировке, и только потом передает полученное число в вашу функцию для форматирования в текст. Это гарантирует, что в итогах вы увидите правильную сумму часов и минут, а не результат сложения строк.

Решение 3: Математический расчет без общего модуля (Вычисляемые поля)

Если у вас нет возможности или желания создавать новый общий модуль, можно прописать всю логику прямо в СКД. Рассмотрим подробнее выражение для вычисляемого поля:


Выбор 
    Когда СуммаМинут > 0 
    Тогда Строка(Цел(СуммаМинут / 60)) + " ч " + Формат(СуммаМинут % 60, "ЧЦ=2; ЧВН=") + " мин"
    Иначе "" 
Конец

В этом выражении мы используем:

Проблема «Индекс находится за границами массива»

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

Чтобы этого избежать, всегда оборачивайте числовые поля в наборе данных функцией ЕСТЬNULL(Поле, 0). Это гарантирует, что в расчеты всегда будет попадать число, и логика не сломается на пустых значениях.

Использование условного оформления для красоты

Посмотрим на еще один профессиональный прием. Иногда удобно оставить поле числовым (чтобы пользователь мог сам суммировать его в Excel), но в отчете видеть текст. Для этого используйте свойство «Выражение представления» в настройках поля СКД. Туда можно вставить вызов функции РаботаСоВременем.ПолучитьДлительностьТекстом(ИтогоОтработано). В итоге визуально в ячейке будет текст «2 ч 10 мин», но «внутри» 1С будет помнить, что это число 130.

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

← На главную