Как организовать фоновый мониторинг папки и печать чеков на клиенте в 1С без зависания программы

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

В процессе автоматизации розничной торговли часто возникает задача: необходимо в реальном времени следить за появлением файлов в определенном каталоге (например, отчетов от банковского терминала) и при их обнаружении инициировать печать на кассовом оборудовании. Основная сложность заключается в том, что драйверы торгового оборудования обычно работают на стороне Тонкого клиента, а клиентское приложение 1С является однопоточным. Если запустить обычный цикл проверки внутри кода, интерфейс программы «зависнет», и пользователь не сможет работать.

В данной статье мы разберем, как правильно реализовать «фоновое» выполнение задач на клиенте, организовать очередь печати и обрабатывать технологические перерывы (например, требование оторвать чек) без блокировки системы.

Решение 1: Использование обработчика ожидания

Поскольку в 1С на клиенте нельзя создать честный фоновый поток (как на сервере), мы воспользуемся механизмом ПодключитьОбработчикОжидания. Этот метод позволяет платформе вызывать заданную процедуру через определенные интервалы времени в моменты, когда интерфейс системы свободен от других задач.

Разберем алгоритм настройки мониторинга по шагам:

  1. Размещение процедуры: Процедура, которую будет вызывать обработчик, должна находиться либо в модуле управляемого приложения, либо в глобальном общем модуле с установленным флагом «Клиент (управляемое приложение)».
  2. Инициализация: При старте системы или открытии рабочего места кассира мы подключаем мониторинг.
  3. Логика проверки: Внутри процедуры мы проверяем наличие файла. Важно: внутри процедуры не должно быть циклов ожидания. Если файла нет — просто выходим.

Рассмотрим пример кода для инициализации мониторинга:


// В модуле управляемого приложения или глобальном модуле
Процедура ПриНачалеРаботыСистемы()
    // Запускаем проверку каждые 2 секунды
    ПодключитьОбработчикОжидания("ПроверитьНаличиеФайловПечати", 2);
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьНаличиеФайловПечати() Экспорт
    ПутьКФайлу = "C:\Exchange\Terminal\report.txt";
    ФайлНаДиске = Новый Файл(ПутьКФайлу);
    
    // Используем метод Существует() для быстрой проверки
    Если ФайлНаДиске.Существует() Тогда
        // Сразу отключаем обработчик, чтобы повторные срабатывания 
        // не наслоились на текущий процесс печати
        ОтключитьОбработчикОжидания("ПроверитьНаличиеФайловПечати");
        
        ВыполнитьПечатьЧека(ПутьКФайлу);
        
        // После завершения печати включаем мониторинг обратно
        ПодключитьОбработчикОжидания("ПроверитьНаличиеФайловПечати", 2);
    КонецЕсли;
КонецПроцедуры

Решение 2: Обработка разрыва чека и немодальные вызовы

Часто оборудование требует физического вмешательства пользователя, например, оторвать чек перед печатью следующей копии. Если использовать стандартное Предупреждение, выполнение кода остановится, и вся программа будет ждать нажатия кнопки. В современном интерфейсе «Такси» рекомендуется использовать немодальные методы.

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

Посмотрим на пример реализации такой логики:


&НаКлиенте
Процедура ВыполнитьПечатьЧека(ПутьКФайлу)
    // 1. Читаем данные и печатаем первую часть (для банка)
    ДанныеЧека = ПрочитатьФайлЧека(ПутьКФайлу);
    ПечататьЧастьЧека(ДанныеЧека.БанковскаяЧасть);
    
    // 2. Подготавливаем оповещение для продолжения после отрыва
    ПараметрыПродолжения = Новый Структура("Путь", ПутьКФайлу, "Данные", ДанныеЧека);
    Оповещение = Новый ОписаниеОповещения("ПослеОтрезкиЧека", ЭтотОбъект, ПараметрыПродолжения);
    
    // 3. Показываем немодальное окно
    ПоказатьВопрос(Оповещение, "Чек напечатан. Оторвите его и нажмите ОК для печати копии клиента", РежимДиалогаВопрос.ОК);
КонецПроцедуры

&НаКлиенте
Процедура ПослеОтрезкиЧека(Результат, ДополнительныеПараметры) Экспорт
    // 4. Печатаем вторую часть (для клиента)
    ПечататьЧастьЧека(ДополнительныеПараметры.Данные.КлиентскаяЧасть);
    
    // 5. Удаляем файл, чтобы он не обработался повторно
    УдалитьФайлы(ДополнительныеПараметры.Путь);
КонецПроцедуры

Методы проверки файлов на клиенте

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

Проанализируем пример использования поиска по маске:


&НаКлиенте
Процедура МониторингКаталога() Экспорт
    Маска = "*.txt";
    Каталог = "C:\Exchange\Terminal\";
    НайденныеФайлы = НайтиФайлы(Каталог, Маска);
    
    Для Каждого Файл Из НайденныеФайлы Цикл
        // Обрабатываем каждый найденный файл
        ОбработатьФайл(Файл.ПолноеИмя);
    КонецЦикла;
КонецПроцедуры

Важные рекомендации по стабильности

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

  1. Защита от «зацикливания»: Всегда отключайте обработчик ожидания перед началом длительной операции (печать, сетевой запрос) и включайте его только после полного завершения всех процедур.
  2. Работа с правами доступа: Убедитесь, что у пользователя Windows, под которым запущена 1С, есть права на чтение и удаление файлов в целевом каталоге.
  3. Обработка ошибок драйвера: Операции с кассовым оборудованием всегда должны быть обернуты в блок Попытка...Исключение. Если касса заклинила или закончилась бумага, ваш обработчик ожидания не должен «уронить» все приложение.
  4. Очередь в памяти: Если файлы приходят быстрее, чем касса успевает их печатать, организуйте массив (очередь) путей к файлам на клиенте. Обработчик ожидания будет брать первый элемент из массива, печатать его и переходить к следующему.

Использование связки ПодключитьОбработчикОжидания и ОписаниеОповещения позволяет создать отзывчивый интерфейс, который успешно справляется с внешними событиями (появлением файлов) и взаимодействием с торговым оборудованием, не заставляя пользователя ждать окончания каждой операции.

← На главную