При интеграции 1С с внешними системами (например, банковскими терминалами, утилитами СБП или P2P-переводами Сбера) программисты часто сталкиваются с проблемой: внешнее приложение запускается, выполняет операцию, но не возвращает результат напрямую в 1С. Вместо этого результат записывается в текстовый лог-файл. В данной статье мы подробно разберем, как научить 1С «понимать», что файл изменился, и как правильно организовать ожидание ответа от стороннего ПО.
Если внешняя утилита закрывается сразу после завершения операции, самым простым и надежным способом будет использование встроенных средств платформы 1С. Вместо использования COM-объекта WScript.Shell, рассмотрим использование метода ЗапуститьПриложение. Этот метод позволяет приостановить выполнение кода 1С до тех пор, пока внешнее приложение не закончит свою работу.
Проанализируем пример реализации:
ПараметрыЗапуска = ДиректорияПрограммы + " /new """ + НомерОрдера + """";
КодВозврата = 0;
// Третий параметр "Истина" означает ожидание завершения приложения
ЗапуститьПриложение(ПараметрыЗапуска, , Истина, КодВозврата);
// После завершения программы читаем лог
Если КодВозврата = 0 Тогда
ТекстЛога = Новый ТекстДокумента;
ТекстЛога.Прочитать(ПутьКФайлуЛога);
// Обрабатываем результат
КонецЕсли;
Важный нюанс: как отметили участники обсуждения, современные асинхронные вызовы в управляемом приложении требуют использования ЗапуститьПриложениеАсинх. Это позволяет не блокировать интерфейс пользователя, пока длится транзакция (которая может занимать до 9 минут).
В ситуациях, когда внешняя программа не закрывается или 1С должна реагировать на промежуточные записи в логе, мы не можем просто «ждать завершения». В этом случае нам необходимо организовать периодический опрос файла. Рассмотрим способ проверки изменения файла через расчет хеш-суммы (SHA256). Этот метод точнее, чем проверка даты изменения, так как дата может обновиться без изменения содержимого.
Разберем алгоритм по шагам:
Пример функции для расчета хеш-суммы:
Функция ПолучитьХешФайла(ПутьКФайлу) Экспорт
Файл = Новый Файл(ПутьКФайлу);
Если Не Файл.Существует() Тогда
Возврат "";
КонецЕсли;
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеширование.Добавить(ДвоичныеДанные);
Возврат СтрЗаменить(Строка(Хеширование.ХешСумма), " ", "");
КонецФункции
В обработчике ожидания сравним полученный хеш с предыдущим значением. Если они различаются — файл был дополнен новой информацией, и мы можем начать парсинг текста.
Для более продвинутых решений, когда недопустимы лишние циклы опроса, можно рассмотреть использование подписок WMI (Windows Management Instrumentation). Это позволяет операционной системе самой уведомлять 1С о событии изменения файла. Рассмотрим, как это работает концептуально.
Выполнение запроса через WMI выглядит как работа с базой данных событий ОС. Мы создаем подписку на изменение объекта типа CIM_DataFile. Однако стоит учитывать, что работа с WMI напрямую из 1С через COMОбъект("winmgmts:") требует специфических прав доступа и определенных навыков системного программирования. Для большинства бизнес-задач этот метод является избыточным, но он незаменим при высоконагруженном мониторинге файловой системы.
Если утилита Сбера является консольным приложением, мы можем попытаться перехватить данные еще до того, как они попадут в файл лога. При использовании WScript.Shell метод Exec возвращает объект, у которого есть поток StdOut.
Рассмотрим пример кода:
WshShell = Новый COMОбъект("WScript.Shell");
Процесс = WshShell.Exec(КомандаЗапуска);
Пока Процесс.Status = 0 Цикл // Пока процесс запущен
Если Не Процесс.StdOut.AtEndOfStream Тогда
СтрокаВывода = Процесс.StdOut.ReadLine();
// Сразу анализируем строку в 1С
КонецЕсли;
КонецЦикла;
Этот подход позволяет получать данные «на лету», не дожидаясь записи на диск, что значительно ускоряет реакцию системы на действия пользователя.
Проанализируем типичную ошибку: внешняя программа держит файл лога открытым для записи, и 1С не может его прочитать (ошибка «Файл занят другим процессом»). Чтобы избежать этой ситуации, следуйте правилам:
КопироватьФайл во временную директорию и читайте уже копию.ЧтениеТекста с указанием кодировки, которую использует внешняя утилита (часто это OEM или UTF-8).Мы рассмотрели несколько способов мониторинга внешних данных: от простых встроенных функций 1С до низкоуровневых системных механизмов. Для интеграции с банковским ПО наиболее сбалансированным решением будет использование асинхронного запуска с обработчиком ожидания и проверкой даты или хеша файла. Это обеспечит стабильную работу интерфейса и гарантированное получение результата транзакции.