При переходе от ручного к автоматическому обмену данными в Распределенной Информационной Базе (РИБ) возникает важная задача: как контролировать процесс? Если при ручном запуске мы можем визуально отследить результат в «Мониторе обмена данными», то автоматический обмен часто работает как «черный ящик». Возникает вопрос: как программно получить информацию об успешном или неудачном завершении обмена, чтобы записать результат в лог-файл или отправить уведомление на почту?
Давайте подробно разберем несколько эффективных способов решения этой задачи, от самых простых до более продвинутых.
Прежде чем перейти к решениям, проясним один важный момент. Инструмент, который мы видим в меню «Сервис - РИБ - Монитор обмена данными», — это, как правило, не универсальный механизм платформы 1С, а часть конкретной конфигурации (например, «Бухгалтерии предприятия» или «Управления торговлей»). Поэтому не существует единой платформенной функции, которая бы позволила «прочитать» данные из этого конкретного окна.
Автоматический обмен данными почти всегда реализуется через механизм регламентных или фоновых заданий. Именно в этом и кроется ключ к решению нашей проблемы. Наша задача смещается от «чтения монитора» к «получению результата выполнения фонового задания».
Это наиболее универсальный и надежный платформенный метод. Он позволяет получить точную информацию о статусе завершения задания, включая текст ошибки, если она произошла. Для этого будем работать с системными объектами управления фоновыми заданиями.
Рассмотрим по шагам:
Состояние. Нас интересуют состояния Завершено и ЗавершеноСАварийнойОстановкой.ИнформацияОбОшибке.Посмотрим на пример кода, который можно выполнять в другом регламентном задании (например, «Проверка статуса обменов»), запускаемом через некоторое время после предполагаемого окончания обмена.
// Этот код должен выполняться на сервере, например, в процедуре регламентного задания
Процедура КонтрольОбменовРИБ()
// Можно установить фильтр, чтобы не перебирать все задания в системе,
// например, по имени или по дате начала
Отбор = Новый Структура;
// Отбор.Вставить("Имя", "Обмен по узлу Торговый_Дом"); // Если известно точное имя
МассивЗаданий = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
// Перебираем найденные задания
Для Каждого Задание Из МассивЗаданий Цикл
// Проверяем, что это наше задание обмена (логика поиска зависит от вашей системы)
Если НЕ Найти(Задание.Имя, "ОбменРИБ") > 0 Тогда
Продолжить;
КонецЕсли;
// Анализируем состояние задания
Если Задание.Состояние = СостояниеФоновогоЗадания.ЗавершеноСАварийнойОстановкой Тогда
// Обмен завершился с ошибкой
ИнформацияОбОшибке = Задание.ИнформацияОбОшибке;
ТекстОшибки = "Обмен данными по узлу '" + Задание.Имя
+ "' завершился с ошибкой: " + ИнформацияОбОшибке.Описание;
// Здесь вызываем процедуру для логирования или отправки почты
ЗаписатьОшибкуВЛог(ТекстОшибки);
ОтправитьУведомлениеАдминистратору(ТекстОшибки);
ИначеЕсли Задание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда
// Обмен завершился успешно
ТекстСообщения = "Обмен данными по узлу '" + Задание.Имя + "' успешно завершен.";
ЗаписатьУспехВЛог(ТекстСообщения);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Этот метод дает полный контроль над ситуацией и работает в любой конфигурации, где автообмен настроен через фоновые задания.
Во многих типовых конфигурациях (УТ 10.3, БП 2.0, УПП и более современных) уже заложен функционал для уведомления об ошибках обмена. Это самый простой способ, который не требует программирования.
Как это работает? В настройках конкретного обмена данными можно указать адрес электронной почты, на который система будет автоматически отправлять письмо в случае возникновения ошибки. Проанализируем, где искать эти настройки:
Настройки обмена данными, Настройки выполнения обмена или что-то похожее.Важно: для работы этого механизма в информационной базе должна быть корректно настроена системная учетная запись для работы с почтой (отправка и получение писем).
Этот способ идеален своей простотой, но он зависит от конфигурации. Если у вас самописная система или в вашей типовой конфигурации такого функционала нет, придется использовать другие методы.
Если автообмен запускается не внутренним регламентным заданием 1С, а внешним планировщиком (например, Планировщиком заданий Windows), который запускает 1С в пакетном режиме, то можно использовать ведение текстовых логов.
Суть метода заключается в том, чтобы при запуске 1С указать специальный параметр командной строки /Out, который перенаправит все системные сообщения в указанный файл.
Пример строки запуска в bat-файле:
"C:\Program Files\1cv8\8.3.20.1234\bin\1cv8.exe" ENTERPRISE /F"D:\InfoBases\MyTrade" /N"Admin" /P"AdminPass" /Execute"D:\Scripts\DoExchange.epf" /Out"C:\Logs\exchange_log.txt" -NoTruncate
Разберем ключевые параметры:
/Execute: запускает внешнюю обработку, которая инициирует сеанс обмена данными./Out"C:\Logs\exchange_log.txt": указывает, что все сообщения (включая информацию об ошибках) нужно записывать в файл exchange_log.txt.-NoTruncate: флаг, который указывает не перезаписывать лог-файл при каждом запуске, а дописывать информацию в конец.После выполнения такого скрипта у вас будет текстовый файл с подробным отчетом о ходе обмена. Следующим шагом будет создание второго скрипта (на PowerShell, Python или даже на 1С), который будет:
exchange_log.txt.Этот метод дает очень подробную информацию, но требует настройки внешних по отношению к 1С инструментов.
Помимо анализа фоновых заданий, платформа предоставляет и другие инструменты для глубокого контроля.
Любая операция обмена, как успешная, так и неуспешная, фиксируется в журнале регистрации 1С. Мы можем программно обращаться к этому журналу и отбирать нужные нам события.
// Пример отбора событий обмена из журнала регистрации
Процедура ПроверитьЖурналРегистрации()
// Устанавливаем отбор по событию "Обмен данными"
Отбор = Новый Структура("Событие", "%Обмен данными%");
// Устанавливаем интервал, например, за последний час
КонецПериода = ТекущаяДата();
НачалоПериода = КонецПериода - 3600; // 3600 секунд = 1 час
Выборка = ЖурналРегистрации.Выбрать(Отбор, НачалоПериода, КонецПериода);
Пока Выборка.Следующий() Цикл
// Анализируем запись
Если Выборка.Уровень = УровеньЖурналаРегистрации.Ошибка Тогда
// Найдена запись об ошибке обмена
ТекстОшибки = "Ошибка в журнале регистрации: " + Выборка.ПредставлениеДанных;
ЗаписатьОшибкуВЛог(ТекстОшибки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Этот метод хорош тем, что он не зависит от способа запуска обмена (фоновое задание или интерактивный запуск), так как фиксирует само событие платформы.
Для контроля целостности данных можно сравнивать номера отправленных и принятых сообщений между узлами РИБ. У каждого узла в плане обмена есть два важных реквизита: НомерОтправленного и НомерПринятого.
Логика проста: если из главного узла было отправлено сообщение с номером 50 (ГлавныйУзел.НомерОтправленного = 50), то после успешного обмена в подчиненном узле номер принятого сообщения также должен стать равен 50 (ПодчиненныйУзел.НомерПринятого = 50). Программная проверка этих номеров между базами (например, через COM-соединение) может выявить "потерянные" сообщения.
Мы рассмотрели несколько способов контроля автоматического обмена в РИБ. Выбор конкретного метода зависит от вашей задачи и архитектуры системы:
Комбинируя эти подходы, вы сможете построить надежную и прозрачную систему автоматического обмена данными, которая будет оперативно информировать вас о любых возникающих проблемах.