При разработке систем мониторинга или инструментов для централизованного аудита часто возникает задача получения данных из журнала регистрации (ЖР) удаленной информационной базы. Одним из наиболее доступных способов является использование COMConnector. Однако программисты часто сталкиваются с ошибками вроде "Несоответствие типов" или "Метод объекта не обнаружен". В этой статье мы подробно разберем, как правильно организовать обращение к журналу регистрации через COM-соединение, и проанализируем основные подводные камни.
Главная причина ошибок при работе с COM-соединением заключается в непонимании того, в каком контексте создаются объекты. Рассмотрим типичную ситуацию: вы создаете объект ТаблицаЗначений в своей текущей базе и пытаетесь передать его в метод ВыгрузитьЖурналРегистрации, вызванный у COM-объекта другой базы. Система выдает ошибку "Несоответствие типов", так как таблица значений «нашей» базы и таблица значений «той» базы — это разные типы объектов с точки зрения платформы, даже если они называются одинаково.
Проанализируем ситуацию: для успешного вызова метода все сложные объекты (таблицы, структуры, массивы), передаваемые в качестве параметров, должны быть созданы «на той стороне», то есть внутри COM-сессии. Для этого используется метод NewObject() самого COM-соединения.
Для начала нам необходимо установить связь с удаленной базой и подготовить объекты-контейнеры. Давайте рассмотрим, как правильно инициализировать приемник данных и структуру отбора.
// Устанавливаем соединение
COMConnector = Новый COMObject("V83.COMConnector");
ПараметрыСоединения = "Srvr=""ServerName"";Ref=""BaseName"";Usr=""Admin"";Pwd=""Password"";";
База1С = COMConnector.Connect(ПараметрыСоединения);
// КРИТИЧЕСКИ ВАЖНО: Создаем объекты в контексте удаленной базы
ВыгрузЖР = База1С.NewObject("ТаблицаЗначений");
Отбор = База1С.NewObject("Структура");
Используя конструкцию База1С.NewObject(), мы гарантируем, что типы данных будут полностью совместимы с методами глобального контекста удаленной базы.
Выгрузка всего журнала регистрации — крайне ресурсоемкая операция, которая может привести к зависанию COM-соединения или переполнению оперативной памяти. Поэтому крайне важно использовать фильтрацию. Разберем основные параметры отбора, такие как ДатаНачала, ДатаОкончания и Событие.
Обратите внимание на работу с пользователями. Если мы хотим отфильтровать данные по конкретному пользователю, нам нужно получить его объект или идентификатор также из удаленной базы.
Отбор.Вставить("Событие", "_$Session$_.Start"); // Фильтр по началу сеансов
Отбор.Вставить("ДатаНачала", НачалоДня(ДобавитьМесяц(ТекущаяДата(), - 1)));
Отбор.Вставить("ДатаОкончания", КонецДня(ТекущаяДата()));
// Если нужен фильтр по пользователям удаленной базы:
СписокПользователей = База1С.ПользователиИнформационнойБазы.ПолучитьПользователей();
// Здесь можно выбрать конкретного пользователя из полученного массива
// Отбор.Вставить("Пользователь", СписокПользователей[0]);
После подготовки всех параметров мы вызываем метод ВыгрузитьЖурналРегистрации. Синтаксис метода предполагает указание приемника, отбора и списка колонок, которые мы хотим получить.
// Определяем список необходимых колонок через запятую
НужныеКолонки = "Дата, ПредставлениеПриложения, Пользователь, ИмяПользователя, Метаданные, Данные, ПредставлениеДанных";
Попытка
База1С.ВыгрузитьЖурналРегистрации(ВыгрузЖР, Отбор, НужныеКолонки);
Сообщить("Данные успешно получены. Количество записей: " + ВыгрузЖР.Количество());
Исключение
Сообщить("Ошибка при выгрузке: " + ОписаниеОшибки());
КонецПопытки;
Важный нюанс, который мы выяснили в ходе обсуждения: хотя платформа умеет автоматически создавать колонки в таблице-приемнике, иногда (в зависимости от версии платформы) может потребоваться предварительное создание колонок в ВыгрузЖР. Если вы получаете ошибку о несовпадении колонок, попробуйте добавить их вручную в ТаблицаЗначений перед вызовом метода.
Работа с большой ТаблицаЗначений через COM-соединение может быть медленной. Каждое обращение к строке или колонке таблицы «той» базы из «нашей» программы — это отдельный сетевой вызов (маршалинг). Если записей тысячи, это превратится в огромные задержки.
Рассмотрим альтернативный, более профессиональный подход — выгрузку в промежуточный XML-файл. Метод ВыгрузитьЖурналРегистрации позволяет передать в качестве первого параметра строку с путем к файлу.
ВыгрузитьЖурналРегистрации.Это исключает проблемы с типами данных ТаблицаЗначений и работает значительно быстрее на больших объемах данных.
Если вы столкнулись с ошибкой "Метод объекта не обнаружен", и при этом синтаксис написан верно, следует проверить права доступа пользователя, под которым выполняется COM-подключение. Для работы с журналом регистрации недостаточно иметь право на Внешнее соединение. У пользователя должна быть роль, содержащая право "Журнал регистрации" (административное право).
Также помните, что в некоторых редких конфигурациях или при использовании определенных патчей платформы доступ к некоторым методам глобального контекста через COM может быть ограничен. В таких случаях мы рекомендуем создать в удаленной базе специальный общий модуль с признаком "Внешнее соединение" и написать там экспортную функцию-обертку, которая будет выполнять выгрузку и возвращать результат (например, в виде строки XML или массива структур).
Подведем итоги нашего исследования. Для успешной работы с ЖР через COM необходимо соблюдать три главных правила:
База1С.NewObject(). Это решает проблему "Несоответствия типов".Использование этих рекомендаций позволит вам стабильно получать данные аудита из любых баз 1С в вашей инфраструктуре.