Как в 1С отнять определенное количество дней от даты

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

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

Способ 1. Вычитание дней на встроенном языке 1С

В платформе 1С:Предприятие значение типа Дата хранится с точностью до секунды. Любые арифметические операции сложения и вычитания с датами производятся в секундах. Соответственно, чтобы отнять от даты нужное количество дней, необходимо умножить число дней на количество секунд в сутках (24 часа * 60 минут * 60 секунд = 86400 секунд).

Посмотрим на пример базового вычисления:


КоличествоДней = 10;
НужнаяДата = ТекущаяДата() - (КоличествоДней * 24 * 60 * 60);

Рассмотрим важные нюансы работы с датой во встроенном языке:

  1. Учет времени суток: при простом вычитании секунд итоговая дата сохраняет то же самое время, которое было в исходной точке. Если вам требуется получить точное начало суток (00:00:00) или конец суток (23:59:59), используем встроенные функции НачалоДня() или КонецДня():
    
    // Получаем начало дня 10 дней назад
    ДатаСреза = НачалоДня(ТекущаяДата() - 10 * 86400);
    
    // Получаем конец дня 10 дней назад
    КонечнаяДата = КонецДня(ТекущаяДата() - 10 * 86400);
    
  2. Клиент-серверное время и часовые пояса: функция ТекущаяДата() на стороне клиента возвращает время операционной системы клиентского компьютера. Для корректной работы в клиент-серверном варианте и с учетом настроек пользователя рекомендуется использовать функцию ТекущаяДатаСеанса().

Способ 2. Вычитание дней в языке запросов 1С

В языке запросов 1С арифметические действия над датами в секундах не поддерживаются напрямую, как в коде. Для изменения даты на определенный интервал предназначена специализированная функция ДОБАВИТЬКДАТЕ.

Синтаксис функции:

ДОБАВИТЬКДАТЕ(ИсходнаяДата, ТипПериода, Количество)

Чтобы вычесть дни, мы передаем отрицательное значение количества. Рассмотрим пример запроса:


ВЫБРАТЬ
    ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -&КоличествоДней) КАК НужнаяДата,
    НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -&КоличествоДней), ДЕНЬ) КАК НачалоНужногоДня

Проанализируем особенности использования функции ДОБАВИТЬКДАТЕ в запросах:

  1. Параметр типа периода (в нашем случае ДЕНЬ) является зарезервированным ключевым словом языка запросов. Его нельзя передавать через параметр запроса в виде строки или переменной.
  2. Если исходное поле даты в выборке содержит значение NULL (например, при левом соединении таблиц), результат функции ДОБАВИТЬКДАТЕ также будет равен NULL. В таких случаях поле необходимо оборачивать в ЕСТЬNULL.
  3. Для очистки времени в запросе используем функцию НАЧАЛОПЕРИОДА с указанием типа периода ДЕНЬ.

Разбор ошибки «Преобразование к типу Число не может быть выполнено»

При реализации расчета на форме разработчики часто сталкиваются с ошибкой выполнения: «Преобразование к типу Число не может быть выполнено». Выясним причину ее возникновения и способы устранения.

Ошибка происходит в том случае, когда переменная, участвующая в операции умножения на 86400, не имеет числового типа. Рассмотрим типичные ситуации:

  1. Обращение к элементу формы вместо реквизита: если на управляемой форме написать Элементы.КоличествоДней, платформа возвращает объект элемента интерфейса (ПолеФормы), а не само значение, введенное пользователем. Для получения значения необходимо обращаться напрямую к реквизиту формы: КоличествоДней или к реквизиту объекта: Объект.КоличествоДней.
  2. Несоответствие типов данных или пустые значения: если реквизит имеет составной тип, содержит строку или значение не заполнено (равно Неопределено или NULL), при попытке умножения возникнет исключение.

Посмотрим на безопасный вариант получения значения и расчета даты на форме:


&НаКлиенте
Процедура РассчитатьДату()
    
    // Проверяем заполненность реквизита
    Если Не ЗначениеЗаполнено(КоличествоДней) Тогда
        Возврат;
    КонецЕсли;
    
    // Приводим значение к типу Число для исключения ошибок
    ЧислоДней = Число(КоличествоДней);
    
    // Вычисляем результирующую дату
    НужнаяДата = НачалоДня(ТекущаяДатаСеанса() - ЧислоДней * 86400);
    
КонецПроцедуры

Расчет рабочих дней по производственному календарю

Если перед вами стоит задача отнять не просто календарные, а исключительно рабочие дни с учетом праздников и выходных, простое математическое вычитание секунд не подойдет. В типовых конфигурациях на базе Библиотеки стандартных подсистем (БСП) для таких расчетов применяется общий модуль КалендарныеГрафики, позволяющий определить дату с учетом производственного календаря или графиков работы предприятия.

← На главную