При интеграции 1С:Предприятия 7.7 с внешним оборудованием, таким как банковские терминалы, программисты часто сталкиваются с ситуацией, когда взаимодействие происходит через файловый обмен. Банковское приложение запускается из 1С, выполняет транзакцию и сохраняет результат в текстовый файл. Основная сложность здесь заключается в том, чтобы заставить 1С «ждать» появления этого файла, не блокируя систему намертво, и корректно обработать результат. Рассмотрим подробно, как реализовать этот механизм с помощью функции ОбработкаОжидания.
Функция ОбработкаОжидания предназначена для циклического вызова определенной процедуры через заданный интервал времени. В платформе 7.7 этот механизм реализован на уровне глобального контекста. Разберем синтаксис этой функции:
ОбработкаОжидания(ИмяПроцедуры, Интервал)
0, выполнение периодической процедуры прекращается.Проанализируем важную особенность: в 1С 7.7 может существовать только один активный глобальный таймер. Если одна часть кода запустила ожидание, а затем другая вызвала ОбработкаОжидания с другими параметрами, первый таймер будет остановлен и заменен вторым.
Для того чтобы остановить процесс опроса после того, как файл ответа от банка найден и обработан, необходимо вызвать ту же самую функцию, но с нулевым интервалом. Рассмотрим пример реализации в коде Глобального модуля:
Перем глФайлОжидания Экспорт;
Процедура глПроверитьФайлОтвета() Экспорт
Если ФС.ВыбратьФайл(0, глФайлОжидания, , , , ) = 1 Тогда
// Файл найден, останавливаем ожидание
ОбработкаОжидания("глПроверитьФайлОтвета", 0);
// Здесь выполняем действия по обработке файла (печать чека и т.д.)
Сообщить("Оплата прошла успешно. Печатаем чек...");
// Удаляем файл, чтобы он не сработал повторно при следующей оплате
ФС.УдалитьФайл(глФайлОжидания);
КонецЕсли;
КонецПроцедуры
В модуле формы документа оплаты запуск процесса будет выглядеть так:
Процедура ПриОплатеКартой()
// Путь к файлу, который создаст банковская утилита
глФайлОжидания = "C:\Bank\result.txt";
// Запускаем внешнее банковское приложение
КомандаЗапуска = "C:\Bank\load.exe /sum=" + СуммаДокумента;
ЗапуститьПриложение(КомандаЗапуска);
// Включаем опрос файла каждые 2 секунды
ОбработкаОжидания("глПроверитьФайлОтвета", 2);
КонецПроцедуры
Стандартная ОбработкаОжидания имеет существенный недостаток: она перестает работать, если в программе открыто модальное окно (например, окно выбора из справочника, вопрос с кнопками Да/Нет или предупреждение). Если кассир в процессе ожидания оплаты откроет какое-либо окно, процедура проверки файла не запустится.
Для решения этой проблемы рекомендуется использовать внешнюю компоненту FormEx. Она позволяет создавать таймеры, которые работают даже в модальных режимах и привязаны к конкретной форме, а не к глобальному модулю. Посмотрим, как это реализовать через объект РасширениеФормы:
// В модуле формы
Перем РФ;
Процедура ПриОткрытии()
РФ = СоздатьОбъект("РасширениеФормы");
РФ.УстановитьФорму(Форма);
КонецПроцедуры
Процедура ПроверкаФайла()
Если ФС.ФайлСуществует("C:\Bank\result.txt") = 1 Тогда
РФ.ОбработкаОжидания("ПроверкаФайла", 0); // Остановка таймера FormEx
// Логика обработки...
КонецЕсли;
КонецПроцедуры
Процедура НачатьОплату()
ЗапуститьПриложение(...);
РФ.ОбработкаОжидания("ПроверкаФайла", 1000); // Интервал в миллисекундах (1000 мс = 1 сек)
КонецПроцедуры
Выясним, как избежать ситуации, когда 20 пользователей работают одновременно и могут перепутать файлы ответов. Если все терминалы будут писать ответ в один и тот же файл STATE.TXT, возникнет «состояние гонки».
Рекомендация 1: Уникальные имена файлов. Используйте сетевое имя компьютера или имя пользователя 1С для формирования уникального пути. Например:
ПутьКФайлу = "D:\1C\Bank\Resp_" + ИмяКомпьютера() + ".txt";
Рекомендация 2: Безопасное чтение. Проверка ФС.ФайлСуществует() может вернуть истину, когда файл еще только записывается банковской программой. Попытка прочитать его в этот момент вызовет ошибку доступа. Чтобы этого избежать, используйте попытку переименования файла перед его обработкой:
// Попытка монопольного захвата файла через переименование
Если ФС.ПереименоватьФайл(ПутьКФайлу, ПутьКФайлу, 0) = 1 Тогда
// Если переименование в самого себя прошло успешно - файл свободен
// Теперь можно безопасно читать данные
КонецЕсли;
Чтобы пользователь не мог совершать другие действия в 1С до получения ответа от банка, создадим специальную небольшую форму «Ожидание оплаты». Разберем алгоритм по шагам:
ОткрытьФормуМодально("Обработка.ОжиданиеОплаты", КонтекстПараметров);.Форма.Закрыть();.Таким образом, пока банк не вернет ответ (или не выйдет время таймаута), кассир не сможет закрыть форму или нажать на другие элементы интерфейса 1С. Это гарантирует целостность данных и исключает ошибки человеческого фактора.
Проанализировав вышеописанные методы, можно сделать вывод, что наиболее надежным способом интеграции в 1С 7.7 является использование локального таймера FormEx в сочетании с уникальными именами файлов для каждого рабочего места. Это обеспечивает стабильную работу даже при большом количестве пользователей и открытых модальных диалогах.