Как автоматически рассчитать дату выезда в форме 1С по дате заезда и продолжительности?

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

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

Основная идея заключается в том, что когда пользователь изменяет поле "Дата заезда" или "Продолжительность", система должна автоматически пересчитать и заполнить поле "Дата выезда". Для этого мы будем использовать обработчики событий формы.

Подход 1: Прямое добавление секунд к дате

В платформе 1С:Предприятие даты хранятся как числовое значение, представляющее собой количество секунд, прошедших от определенной базовой даты. Это позволяет нам выполнять арифметические операции непосредственно с датами. Чтобы прибавить к дате определенное количество дней, нам необходимо перевести это количество дней в секунды. Мы знаем, что в одном дне 24 часа, в каждом часе 60 минут, а в каждой минуте 60 секунд. Таким образом, один день равен 24 * 60 * 60 = 86400 секунд.

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

Разберем по шагам, как мы можем реализовать этот подход в обработчике события, например, ПриИзменении для поля "Продолжительность":

  1. Откройте форму, в которой вы хотите реализовать расчет.
  2. Выберите поле, изменение которого должно запускать расчет (например, "Продолжительность" или "ДатаЗаезда").
  3. В палитре свойств этого поля найдите раздел "События" и создайте обработчик для события ПриИзменении.
  4. Поскольку для доступа к данным объекта и выполнения расчетов нам может понадобиться серверный контекст, мы будем размещать код на сервере. Для этого в модуле формы создайте процедуру с атрибутом &НаСервере.

Посмотрим на пример кода:


&НаСервере
Процедура ПродолжительностьПриИзмененииНаСервере()
    // Проверяем, что дата заезда и продолжительность заполнены
    Если ЗначениеЗаполнено(Объект.ДатаЗаезда) И ЗначениеЗаполнено(Объект.Продолжительность) Тогда
        // Приводим дату заезда к началу дня, чтобы избежать влияния времени
        ПеременнаяДатаЗаезда = НачалоДня(Объект.ДатаЗаезда);
        
        // Рассчитываем дату выезда, прибавляя количество дней в секундах
        Объект.ДатаВыезда = ПеременнаяДатаЗаезда + Объект.Продолжительность * 24 * 60 * 60;
    Иначе
        // Если данные не заполнены, очищаем дату выезда
        Объект.ДатаВыезда = Неопределено;
    КонецЕсли;
КонецПроцедуры

// Также желательно создать аналогичный обработчик для поля ДатаЗаезда, 
// чтобы расчет происходил при изменении любого из этих полей.
&НаСервере
Процедура ДатаЗаездаПриИзмененииНаСервере()
    ПродолжительностьПриИзмененииНаСервере(); // Вызываем ту же процедуру расчета
КонецПроцедуры

Преимущества этого метода:

Недостатки:

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

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

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

Проанализируем шаги реализации:

  1. Как и в предыдущем случае, создайте обработчик события ПриИзменении для поля "Продолжительность" (или "ДатаЗаезда") на сервере.
  2. Внутри этого обработчика мы будем формировать новый запрос.
  3. В тексте запроса используйте функцию ДОБАВИТЬКДАТЕ, указав дату заезда, единицу измерения (ДЕНЬ) и количество дней.
  4. Передайте необходимые параметры в запрос (ДатаЗаезда и КоличествоДней).
  5. Выполните запрос и получите результат.

Рассмотрим пример кода:


&НаСервере
Процедура ПродолжительностьПриИзмененииНаСервере()
    // Проверяем, что дата заезда и продолжительность заполнены
    Если ЗначениеЗаполнено(Объект.ДатаЗаезда) И ЗначениеЗаполнено(Объект.Продолжительность) Тогда
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ
            |    ДОБАВИТЬКДАТЕ(&ДатаЗаезда, ДЕНЬ, &КоличествоДней) КАК ДатаВыезда";
        
        // Устанавливаем параметры запроса
        Запрос.УстановитьПараметр("ДатаЗаезда", Объект.ДатаЗаезда);
        Запрос.УстановитьПараметр("КоличествоДней", Объект.Продолжительность);
        
        // Выполняем запрос
        РезультатЗапроса = Запрос.Выполнить();
        ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
        
        // Получаем результат и присваиваем его полю формы
        Если ВыборкаДетальныеЗаписи.Следующий() Тогда
            Объект.ДатаВыезда = ВыборкаДетальныеЗаписи.ДатаВыезда;
        КонецЕсли;
    Иначе
        // Если данные не заполнены, очищаем дату выезда
        Объект.ДатаВыезда = Неопределено;
    КонецЕсли;
КонецПроцедуры

// Аналогично, для поля ДатаЗаезда вызываем эту же процедуру.
&НаСервере
Процедура ДатаЗаездаПриИзмененииНаСервере()
    ПродолжительностьПриИзмененииНаСервере(); // Вызываем ту же процедуру расчета
КонецПроцедуры

Преимущества этого метода:

Недостатки:

Размещение кода и обработчики событий

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

Для создания обработчика:

  1. Откройте форму в конфигураторе.
  2. Выберите нужный элемент формы (например, поле ввода для "Продолжительность").
  3. Перейдите на вкладку "События" в палитре свойств.
  4. Рядом с событием ПриИзменении нажмите на кнопку с лупой (или значком открытой папки), чтобы создать или перейти к процедуре обработчика.

Контекст выполнения:

В управляемых формах код может выполняться как на клиенте (в браузере или тонком клиенте), так и на сервере. Для нашей задачи, поскольку мы либо работаем с данными объекта (который находится на сервере), либо выполняем запрос к базе данных, нам требуется серверный контекст. Поэтому мы используем атрибут &НаСервере перед определением процедуры.

Пример вызова серверной процедуры из клиентского обработчика, если бы мы захотели разделить логику:


&НаКлиенте
Процедура ПродолжительностьПриИзменении(Элемент)
    // Здесь можем выполнить какую-то клиентскую логику
    
    // Вызываем серверную процедуру для выполнения расчета
    ПродолжительностьПриИзмененииНаСервере();
КонецПроцедуры

В наших примерах мы размещаем всю логику на сервере, поэтому сразу определяем процедуру как &НаСервере.

Общие рекомендации при работе с датами в 1С

Мы хотим, чтобы вы всегда помнили о нескольких важных аспектах при работе с датами в 1С:

  1. Точность даты: Тип данных "Дата" в 1С хранит не только календарную дату, но и время с точностью до 0,1 миллисекунды. Это важно учитывать, чтобы избежать неожиданных результатов при арифметических операциях или сравнениях.
  2. Функция НачалоДня(): Когда вы работаете с продолжительностью в целых днях, всегда рекомендуется приводить даты к началу дня с помощью функции НачалоДня(). Это гарантирует, что время в исходной дате не повлияет на расчет и "Дата выезда" будет корректной календарной датой, а не датой со смещенным временем.
  3. Функция ЗначениеЗаполнено(): Всегда проверяйте, что исходные поля (ДатаЗаезда и Продолжительность) заполнены, прежде чем выполнять расчет. Это поможет избежать ошибок и некорректных значений в поле "Дата выезда", а также позволяет очищать "Дату выезда", если одно из полей-источников было очищено.
  4. Гибкость ДОБАВИТЬКДАТЕ: Если вам потребуется добавлять не только дни, но и другие интервалы времени (месяцы, годы, часы), функция ДОБАВИТЬКДАТЕ в запросах является очень гибким и удобным инструментом. Просто измените второй параметр функции (например, МЕСЯЦ, ГОД, ЧАС). Она также прекрасно работает с отрицательными значениями, позволяя вычитать даты.

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

← На главную