Как в 1С 7.7 узнать точное время через интернет и предотвратить ошибки фискального регистратора?

Программист 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

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

Разберем подробно несколько эффективных способов решения этой задачи: от использования системных утилит Windows до написания программного кода внутри 1С.

Метод 1: Использование системной утилиты w32tm

Самый простой и надежный способ — задействовать встроенную службу времени Windows. Мы можем выполнить запрос к публичным NTP-серверам (например, pool.ntp.org), чтобы получить информацию о разнице между системным и эталонным временем. Проанализируем команду, которая позволяет получить срез данных:


// Пример команды для командной строки или вызова через КомандаСистемы()
w32tm /stripchart /computer:pool.ntp.org /samples:1 /dataonly

Разберем параметры этой команды:

  1. /stripchart — выводит график (или данные) разницы во времени.
  2. /computer:pool.ntp.org — адрес сервера точного времени.
  3. /samples:1 — количество запросов (нам достаточно одного для проверки).
  4. /dataonly — возвращает только числовые данные без лишнего текста.

В 1С 7.7 результат выполнения можно перенаправить в текстовый файл и считать его. Рассмотрим, как это реализовать:


Процедура ПроверитьВремяЧерезNTP()
    ИмяФайла = "time_check.txt";
    КомандаСистемы("w32tm /stripchart /computer:pool.ntp.org /samples:1 /dataonly > " + ИмяФайла);
    
    Текст = СоздатьОбъект("Текст");
    Текст.Открыть(ИмяФайла);
    Если Текст.КоличествоСтрок() > 0 Тогда
        // Анализируем строку с результатом
        Результат = Текст.ПолучитьСтроку(Текст.КоличествоСтрок());
        Сообщить("Результат проверки времени: " + Результат);
    КонецЕсли;
КонецПроцедуры

Метод 2: Определение часового пояса через WMI

Для того чтобы сопоставить время из интернета (которое обычно передается в формате UTC/GMT) с локальным временем компьютера, нам нужно точно знать текущий часовой пояс. В 1С 7.7 нет встроенной функции ЧасовойПоясСеанса, поэтому мы воспользуемся механизмом WMI (Windows Management Instrumentation) через MSScriptControl.

Рассмотрим пример функции, которая возвращает смещение локального времени от GMT в часах:


Функция ПолучитьСмещениеВремениWMI()
    Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl");
    Скрипт.Language = "vbscript";
    Скрипт.AddCode("
        |function GetGMTOffset()
        |    set Service = GetObject(""winmgmts:\\.\root\cimv2"")
        |    set colTimeZone = Service.ExecQuery(""Select * from Win32_TimeZone"")
        |    for each objTimeZone In colTimeZone 
        |        GetGMTOffset = objTimeZone.Bias / 60
        |        exit for
        |    next
        |end function
        |");
    Сдвиг = Скрипт.Run("GetGMTOffset");
    Возврат Сдвиг; 
КонецФункции

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

Метод 3: Получение времени через HTTP-заголовок (альтернатива NTP)

Иногда порт 123 (UDP), необходимый для NTP, закрыт системными администраторами или провайдером. В этом случае мы можем прибегнуть к хитрости: отправить HTTP-запрос к любому крупному веб-серверу и прочитать заголовок Date, который всегда содержит точное время сервера в формате GMT.

Выясним, как реализовать это через объект MSXML2.XMLHTTP:


Функция ПолучитьВремяЧерезHTTP()
    Http = СоздатьОбъект("MSXML2.XMLHTTP");
    Http.Open("GET", "https://google.com", 0);
    Http.Send();
    
    // Получаем заголовок ответа
    ДатаСтрокой = Http.getResponseHeader("Date"); 
    // Пример строки: "Mon, 21 Aug 2023 12:00:00 GMT"
    Сообщить("Время по GMT из заголовка HTTP: " + ДатаСтрокой);
    Возврат ДатаСтрокой;
КонецФункции

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

Метод 4: Сравнение времени 1С и Фискального Регистратора

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

  1. При запуске 1С или перед формированием чека вызываем метод драйвера ФР для получения текущего времени устройства (например, GetDeviceMetrics или GetStatus в зависимости от модели).
  2. Сравниваем полученное время с результатом функции ТекущееВремя().
  3. Если разница составляет более допустимого значения (например, 5 минут), блокируем работу пользователя и выводим предупреждение.

Пример логики на языке 1С 7.7 (псевдокод драйвера):


ФР.Password = 30; // Пароль администратора ФР
ФР.GetStatus();
ВремяФР = ФР.Time; // Получаем время из ФР
ВремяПК = ТекущееВремя();

Если Макс(ВремяФР, ВремяПК) - Мин(ВремяФР, ВремяПК) > "00:05:00" Тогда
    Предупреждение("ВНИМАНИЕ! Время на компьютере расходится с временем в кассе!");
    СтатусВозврата(0); // Блокируем дальнейшее действие
КонецЕсли;

Метод 5: Административные меры

Программные методы — это хорошо, но первопричину (возможность изменения времени пользователем) нужно устранять административно. Рассмотрим шаги, которые следует предпринять системному администратору:

  1. Ограничение прав доступа: Убедитесь, что учетная запись пользователя не входит в группу "Администраторы".
  2. Групповые политики: Через secpol.msc (Локальная политика безопасности) в разделе Локальные политики -> Назначение прав пользователя найдите параметр "Изменение системного времени". Удалите оттуда всех, кроме администраторов и службы LOCAL SERVICE.
  3. Автоматическая синхронизация: Настройте планировщик задач Windows на выполнение команды w32tm /resync при каждом включении компьютера или раз в час.
  4. Проверка батарейки CMOS: Если время сбрасывается на одну и ту же дату (например, на 2000-й год) после выключения ПК, необходимо заменить батарейку на материнской плате.

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

← На главную