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

Программист 1С v7.7
← На главную

В практике разработки на платформе 1С часто возникает задача контроля времени реакции сотрудника на тот или иной документ. Типичный сценарий: с момента появления документа в системе у ответственного лица есть ровно 24 часа на его обработку. Если время вышло, отчет должен зафиксировать просрочку. Однако техническая реализация этой задачи в старых версиях платформы (1С 7.7) и современных (1С 8.3) существенно различается из-за особенностей хранения данных о времени и позиции документа.

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

Метод 1: Математическое сравнение через преобразование даты и времени (для 1С 7.7)

Рассмотрим подход, предложенный в сообществе, который основан на формировании уникального числового значения, представляющего собой момент времени. Основная проблема 1С 7.7 заключается в том, что тип Дата не содержит времени. Время получается отдельно через функцию ТекущееВремя() или извлекается из позиции документа.

Чтобы сравнить два момента времени, мы можем привести их к виду ГГГГММДДЧЧММСС. Проанализируем реализацию этого метода через вспомогательную функцию:


// Функция преобразует дату и время в длинное число для удобного сравнения
Функция СформироватьЧислоПозиции(ДатаП, ЧасП, МинП, СекП)
    // Форматируем дату в ГГГГММДД и добавляем время с ведущими нулями
    Рез = Формат(ДатаП, "ДГГГГММДД") + Формат(ЧасП, "Ч(0)2") + Формат(МинП, "Ч(0)2") + Формат(СекП, "Ч(0)2");
    Рез = Число(Рез);
    Возврат Рез;
КонецФункции

Функция ПрошлиСутки(Док)
    Перем ДатаП, ЧасП, МинП, СекП;
    
    // Получаем текущее системное время и дату
    ТекущееВремя(ЧасП, МинП, СекП);
    ТекПозиция = СформироватьЧислоПозиции(РабочаяДата, ЧасП, МинП, СекП);
    
    // Извлекаем дату и время из позиции проверяемого документа
    РазобратьПозициюДокумента(Док, ДатаП, ЧасП, МинП, СекП);
    
    // Прибавляем ровно одни сутки к дате документа
    // В 1С 7.7 прибавление единицы к дате корректно переносит на следующий день
    ПозицияРеакции = СформироватьЧислоПозиции(ДатаП + 1, ЧасП, МинП, СекП);
    
    Если ТекПозиция > ПозицияРеакции Тогда
        Возврат 1; // Сутки прошли
    КонецЕсли;
    
    Возврат 0; // Сутки еще не прошли
КонецФункции

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

Метод 2: Работа с позицией документа через встроенные функции

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

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

Выясним причину, почему разработчики часто избегают прямого сравнения позиций. Позиция — это 32-ричная строка, и прибавить к ней "24 часа" математически невозможно без перевода в формат даты/времени. Поэтому алгоритм "Разобрать -> Изменить дату -> Собрать/Сравнить" является стандартным путем для этой версии платформы.

Метод 3: Современный подход в 1С 8.3 (Управляемые формы)

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


// Проверка просрочки в 24 часа (86400 секунд)
ВремяДокумента = ОбъектСсылка.Дата;
ТекущийМомент = ТекущаяДата(); // Или ТекущаяДатаСеанса() для разных часовых поясов

Если ТекущийМомент > (ВремяДокумента + 86400) Тогда
    Сообщить("С момента создания документа прошло более суток!");
КонецЕсли;

Проанализируем ситуацию с точки зрения производительности. Если документов много, проверку в цикле делать неэффективно. Лучше всего использовать язык запросов. В 1С 8.х для этого предусмотрена функция РАЗНОСТЬДАТ.


ВЫБРАТЬ
    Ссылка,
    Дата КАК ДатаСоздания,
    ВЫБОР
        КОГДА РАЗНОСТЬДАТ(Дата, &ТекущаяДата, СЕКУНДА) > 86400
            ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК Просрочено
ИЗ
    Документ.РеализацияТоваровУслуг
ГДЕ
    Проведен = ИСТИНА

Метод 4: Учет нюансов (рабочее время и часовые пояса)

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

  1. Рабочие и выходные дни: Если "сутки на реакцию" — это рабочие сутки, то простая арифметика не поможет. Вам потребуется календарь (в 7.7) или Регистр сведений "Производственный календарь" (в 8.х). В этом случае время будет считаться только по интервалам рабочего графика.
  2. Перепроведение документов: Если сотрудник изменил документ и перепровел его "задним числом", его позиция может измениться. Выясним причину: если нам нужно время именно первого появления документа, то стоит использовать либо Журнал регистрации, либо создать в документе дополнительный реквизит ДатаПервойЗаписи, который заполняется только один раз при создании.
  3. Часовые пояса: В крупных компаниях сервер может находиться в Москве, а сотрудник — во Владивостоке. В 1С 8.3 всегда используйте ТекущаяДатаСеанса(), чтобы сравнение шло в контексте локального времени пользователя, иначе вы можете получить ложные срабатывания о просрочке.

Резюме

Для реализации проверки интервала в 1С 7.7 самым надежным "быстрым" способом является перевод даты и времени в числовой формат ГГГГММДДЧЧММСС через Формат() и последующее сравнение. Для 1С 8.х лучшим решением будет использование запросов с функцией РАЗНОСТЬДАТ или прямая работа с типом Дата, учитывая, что единица времени в ней — это секунда.

Выбирая метод, всегда оценивайте объем данных: для отчета по тысячам документов всегда выбирайте запросы (SQL или встроенный язык запросов 1С), а для проверки в форме конкретного документа — объектные методы платформы.

← На главную