При работе в клиент-серверном режиме 1С часто возникает задача получить точное время сервера для фиксации событий, создания документов или выполнения других операций. Стандартная функция ТекущаяДата(), вызванная на стороне клиента (например, в модуле формы), вернет системное время с компьютера пользователя, которое может отличаться от серверного. Это может привести к ошибкам в учете, нарушению хронологии документов и другим проблемам. Рассмотрим, как правильно получить именно серверное время.
Проблема кроется в архитектуре платформы 1С, которая разделяет выполнение кода на клиентское и серверное. Код с директивой &НаКлиенте выполняется на машине пользователя, а с директивой &НаСервере — на сервере 1С. Соответственно, функция ТекущаяДата() вернет время той машины, где она была физически выполнена.
Давайте разберем два надежных способа решения этой задачи.
Это самый простой и предпочтительный метод для современных конфигураций на управляемых формах. Платформа 1С предоставляет специальную функцию ТекущаяДатаСеанса(), которая создана именно для таких целей.
В чем ее особенность? Эта функция возвращает дату и время, которые были актуальны на сервере в момент установки сеанса пользователя. Это значение одинаково для всего сеанса работы и не зависит от того, где вызывается функция — на клиенте или на сервере. Это гарантирует единообразие временных меток для всех документов и операций, созданных в рамках одной сессии.
Как использовать:
Использовать ее так же просто, как и ТекущаяДата(). В задачах, где требуется программное изменение форм, в коде клиентской процедуры можно написать:
&НаКлиенте
Процедура УстановитьДатуДокумента()
// Получаем дату сеанса, которая соответствует времени сервера
ДатаДляДокумента = ТекущаяДатаСеанса();
// Присваиваем ее реквизиту формы
Объект.Дата = ДатаДляДокумента;
Сообщить("Документу установлена дата сеанса: " + ДатаДляДокумента);
КонецПроцедуры
Когда стоит применять этот метод:
Этот способ идеален для большинства повседневных задач:
Важный нюанс: Помните, что ТекущаяДатаСеанса() "замораживает" время на момент входа в программу. Если сеанс пользователя длится несколько часов, функция все равно будет возвращать то же самое значение. Для задач, где нужна актуальная серверная дата с точностью до секунды (например, для логирования событий), лучше подойдет второй способ.
Этот метод более универсален и дает полный контроль над ситуацией. Он заключается в создании специальной функции в общем модуле, который будет выполняться строго на сервере и возвращать актуальное серверное время в момент вызова. Это классический подход для организации клиент-серверного взаимодействия.
Разберем по шагам, как это сделать.
Если у вас еще нет подходящего общего модуля, создайте новый. Назовем его, например, ОбщегоНазначенияСерверныеВызовы. Важно правильно настроить его свойства.
Откройте палитру свойств созданного модуля и установите следующие флаги:
Сервер — этот флаг указывает, что код модуля компилируется и выполняется на стороне сервера 1С.Вызов сервера — этот ключевой флаг разрешает обращаться к экспортным процедурам и функциям этого модуля из клиентского кода. Платформа автоматически организует "мост" для такого вызова.Остальные флаги (Клиент (управляемое приложение), Внешнее соединение и др.) можно оставить без изменений, если они не требуются для других задач.
Теперь в тексте нашего нового модуля напишем простую функцию (предварительно можно выполнить анализ конфигураций на наличие ошибок), которая будет делать только одно — возвращать результат выполнения ТекущаяДата() на сервере.
' Обязательно указываем директиву компиляции, хотя для серверного модуля это избыточно,
' но является хорошим тоном для читаемости кода.
&НаСервере
Функция ПолучитьАктуальнуюДатуСервера() Экспорт
// Так как эта функция выполняется на сервере,
// ТекущаяДата() вернет именно системное время сервера.
Возврат ТекущаяДата();
КонецФункции
Ключевое слово Экспорт делает эту функцию доступной для вызова из других модулей, в том числе и с клиента (благодаря флагу `Вызов сервера`).
Теперь из любого клиентского кода, например, из модуля формы, можно легко получить актуальное время сервера:
&НаКлиенте
Процедура ЗаписатьВремяСобытия(Команда)
// Обращаемся к нашему общему модулю и его экспортной функции
ТочноеСерверноеВремя = ОбщегоНазначенияСерверныеВызовы.ПолучитьАктуальнуюДатуСервера();
Сообщить("Событие зафиксировано в: " + ТочноеСерверноеВремя);
// Далее можно использовать это значение для записи в лог, регистр и т.д.
КонецПроцедуры
Когда стоит применять этот метод:
ТекущаяДатаСеанса() не подходит.Важный нюанс: Каждый такой вызов — это полноценное обращение с клиента на сервер. При редком использовании это не оказывает никакого влияния на производительность. Однако не стоит использовать этот метод в циклах или в событиях, которые срабатывают очень часто (например, ПриИзменении поля ввода), так как это может создать избыточную нагрузку на сеть и сервер.
Давайте подведем итог и сравним оба метода, чтобы вы могли выбрать наиболее подходящий для вашей задачи.
ТекущаяДатаСеанса()
Собственная серверная функция
В заключение, понимание разницы между клиентским и серверным контекстом выполнения кода — один из фундаментальных навыков разработчика 1С. Выбор правильного инструмента для получения даты не только решает поставленную задачу, но и обеспечивает стабильность, предсказуемость и производительность вашей системы.