В процессе автоматизации розничной торговли часто возникает задача: необходимо в реальном времени следить за появлением файлов в определенном каталоге (например, отчетов от банковского терминала) и при их обнаружении инициировать печать на кассовом оборудовании. Основная сложность заключается в том, что драйверы торгового оборудования обычно работают на стороне Тонкого клиента, а клиентское приложение 1С является однопоточным. Если запустить обычный цикл проверки внутри кода, интерфейс программы «зависнет», и пользователь не сможет работать.
В данной статье мы разберем, как правильно реализовать «фоновое» выполнение задач на клиенте, организовать очередь печати и обрабатывать технологические перерывы (например, требование оторвать чек) без блокировки системы.
Поскольку в 1С на клиенте нельзя создать честный фоновый поток (как на сервере), мы воспользуемся механизмом ПодключитьОбработчикОжидания. Этот метод позволяет платформе вызывать заданную процедуру через определенные интервалы времени в моменты, когда интерфейс системы свободен от других задач.
Разберем алгоритм настройки мониторинга по шагам:
Рассмотрим пример кода для инициализации мониторинга:
// В модуле управляемого приложения или глобальном модуле
Процедура ПриНачалеРаботыСистемы()
// Запускаем проверку каждые 2 секунды
ПодключитьОбработчикОжидания("ПроверитьНаличиеФайловПечати", 2);
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьНаличиеФайловПечати() Экспорт
ПутьКФайлу = "C:\Exchange\Terminal\report.txt";
ФайлНаДиске = Новый Файл(ПутьКФайлу);
// Используем метод Существует() для быстрой проверки
Если ФайлНаДиске.Существует() Тогда
// Сразу отключаем обработчик, чтобы повторные срабатывания
// не наслоились на текущий процесс печати
ОтключитьОбработчикОжидания("ПроверитьНаличиеФайловПечати");
ВыполнитьПечатьЧека(ПутьКФайлу);
// После завершения печати включаем мониторинг обратно
ПодключитьОбработчикОжидания("ПроверитьНаличиеФайловПечати", 2);
КонецЕсли;
КонецПроцедуры
Часто оборудование требует физического вмешательства пользователя, например, оторвать чек перед печатью следующей копии. Если использовать стандартное Предупреждение, выполнение кода остановится, и вся программа будет ждать нажатия кнопки. В современном интерфейсе «Такси» рекомендуется использовать немодальные методы.
Проанализируем ситуацию: нам нужно напечатать первую часть, вывести сообщение, дождаться подтверждения и напечатать вторую часть. Для этого мы разделим процесс печати на этапы с использованием ОписаниеОповещения.
Посмотрим на пример реализации такой логики:
&НаКлиенте
Процедура ВыполнитьПечатьЧека(ПутьКФайлу)
// 1. Читаем данные и печатаем первую часть (для банка)
ДанныеЧека = ПрочитатьФайлЧека(ПутьКФайлу);
ПечататьЧастьЧека(ДанныеЧека.БанковскаяЧасть);
// 2. Подготавливаем оповещение для продолжения после отрыва
ПараметрыПродолжения = Новый Структура("Путь", ПутьКФайлу, "Данные", ДанныеЧека);
Оповещение = Новый ОписаниеОповещения("ПослеОтрезкиЧека", ЭтотОбъект, ПараметрыПродолжения);
// 3. Показываем немодальное окно
ПоказатьВопрос(Оповещение, "Чек напечатан. Оторвите его и нажмите ОК для печати копии клиента", РежимДиалогаВопрос.ОК);
КонецПроцедуры
&НаКлиенте
Процедура ПослеОтрезкиЧека(Результат, ДополнительныеПараметры) Экспорт
// 4. Печатаем вторую часть (для клиента)
ПечататьЧастьЧека(ДополнительныеПараметры.Данные.КлиентскаяЧасть);
// 5. Удаляем файл, чтобы он не обработался повторно
УдалитьФайлы(ДополнительныеПараметры.Путь);
КонецПроцедуры
Для мониторинга каталога можно использовать несколько встроенных функций 1С. Выясним, какая из них лучше подходит для нашей задачи:
Файл.Существует() — самый простой и быстрый способ проверить конкретный файл, если его имя заранее известно.НайтиФайлы() — позволяет искать файлы по маске (например, *.txt). Это удобно, если терминал создает файлы с уникальными именами (например, по номеру чека).НайтиФайлыАсинх() — современный метод (доступен в новых версиях платформы), который выполняет поиск, не блокируя поток выполнения.Проанализируем пример использования поиска по маске:
&НаКлиенте
Процедура МониторингКаталога() Экспорт
Маска = "*.txt";
Каталог = "C:\Exchange\Terminal\";
НайденныеФайлы = НайтиФайлы(Каталог, Маска);
Для Каждого Файл Из НайденныеФайлы Цикл
// Обрабатываем каждый найденный файл
ОбработатьФайл(Файл.ПолноеИмя);
КонецЦикла;
КонецПроцедуры
При реализации фонового мониторинга на клиенте следует придерживаться нескольких правил, чтобы система работала надежно:
Попытка...Исключение. Если касса заклинила или закончилась бумага, ваш обработчик ожидания не должен «уронить» все приложение.Использование связки ПодключитьОбработчикОжидания и ОписаниеОповещения позволяет создать отзывчивый интерфейс, который успешно справляется с внешними событиями (появлением файлов) и взаимодействием с торговым оборудованием, не заставляя пользователя ждать окончания каждой операции.