Как в 1С написать условие: "дата документа старше текущей более чем на 5 дней"?

Программист IT и автоматизация бизнеса
← На главную

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

Базовое решение: разница в секундах

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

Проанализируем математику: 1 день — это 24 часа, 60 минут, 60 секунд. Получаем: 60 * 60 * 24 = 86400 секунд в сутках. Следовательно, 5 дней — это 86400 * 5.

Посмотрим на пример простейшего кода, который можно поместить в обработчик события ПередЗаписью в модуле объекта:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    ПятьДней = 86400 * 5;
    ТекГраница = ТекущаяДатаСеанса() - ПятьДней;
    
    Если Объект.Дата < ТекГраница Тогда
        Отказ = Истина;
        Сообщить("Дата документа не может быть старше 5 дней от текущей даты!");
    КонецЕсли;

КонецПроцедуры

Этот код решает проблему в первом приближении, однако он таит в себе "подводные камни", связанные со временем суток.

Учитываем время суток и неполные дни

Разберем подробнее, почему простое вычитание секунд может привести к ошибкам. Если текущее время 15:00, а документ создается датой пятидневной давности, но со временем 10:00, система посчитает разницу и выдаст отказ, хотя календарно пятые сутки еще не истекли (или истекли не полностью).

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    РазницаВДнях = (НачалоДня(ТекущаяДатаСеанса()) - НачалоДня(Объект.Дата)) / 86400;
    
    Если РазницаВДнях > 5 Тогда
        Отказ = Истина;
        Сообщить("Нельзя сохранять документы старше 5 дней!");
    КонецЕсли;

КонецПроцедуры

Такой подход намного надежнее, так как исключает влияние времени создания документа на логику проверки.

Исключаем блокировку старых документов при перепроведении

Проанализируем следующую ситуацию: пользователь открыл старый документ (которому уже больше 5 дней), чтобы изменить в нем комментарий, или просто перепроводит его. Если мы оставим код в том виде, в котором написали выше, 1С выдаст отказ. Ведь дата документа действительно старше 5 дней. Но пользователь дату не менял!

Чтобы блокировать только попытки переноса даты в прошлое или создания нового документа задним числом, необходимо сравнивать текущую дату объекта с той датой, которая уже записана в базе данных. Для этого используем обращение к свойству Ссылка:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    Если Объект.Дата <> Объект.Ссылка.Дата Тогда
        РазницаВДнях = (НачалоДня(ТекущаяДатаСеанса()) - НачалоДня(Объект.Дата)) / 86400;
        
        Если РазницаВДнях > 5 Тогда
            Отказ = Истина;
            Сообщить("Запрещено переносить дату документа более чем на 5 дней назад!");
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры

Теперь наша проверка сработает только в том случае, если пользователь физически изменил реквизит Дата.

Типовое решение: Дата запрета изменения данных

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

  1. Для защиты закрытых периодов от изменений.
  2. Для контроля выгрузок в сторонние базы данных.
  3. Для дисциплинирования пользователей.

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

Как это настроить:

  1. Перейти в раздел Администрирование.
  2. Открыть Настройки пользователей и прав (или аналогичный раздел, в зависимости от конфигурации).
  3. Включить опцию Даты запрета изменения.
  4. В настройках указать относительную дату запрета (например, "Конец прошлого месяца" или задать сдвиг в днях).

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

Дата документа и Дата создания: в чем разница?

В завершение разберем важную понятийную ошибку. Часто пользователи путают "дату создания" и "дату документа".

Реквизит Дата, который мы проверяли в коде — это дата отражения хозяйственной операции в учете. Именно по ней строятся бухгалтерские и управленческие отчеты. Платформа 1С "из коробки" не хранит фактическое время, когда пользователь нажал кнопку создания.

Если вам нужно отследить именно время фактического появления объекта в базе (независимо от того, какую дату установил пользователь внутри документа), используйте Журнал регистрации или типовую подсистему Версионирование объектов.

← На главную