При разработке механизмов интеграции между различными базами «1С:Предприятие» через COM-соединение программисты часто сталкиваются с ситуацией, когда данные, которые они привыкли видеть в интерфейсе программы, внезапно оказываются недоступными или «пустыми» при программном обращении. Рассмотрим подробнее одну из таких ситуаций на примере передачи данных об основных средствах (ОС) и их счетах учета между базами «Склад» и «Бухгалтерия».
Разберем типичную проблему: вы подключаетесь из одной базы к другой через COMConnector, находите нужный элемент справочника (например, Справочники.ОсновныеСредства), обращаетесь к его реквизиту СчетУчета, но получаете пустое значение. При этом, если открыть тот же элемент в базе-источнике через обычное пользовательское приложение, поле «Счет учета» будет заполнено.
Первое, что нам необходимо сделать в такой ситуации, — это проанализировать источник данных на форме. В современных конфигурациях, особенно построенных на базе «Библиотеки стандартных подсистем» (БСП), разработчики часто выносят учетные данные в регистры сведений для обеспечения версионности или разделения учета. В этом случае на форму объекта данные попадают не из самого реквизита справочника, а подтягиваются программно в процедуре ПриЧтенииНаСервере или ПриСозданииНаСервере.
Проанализируем шаги для проверки этой гипотезы:
Объект.СчетУчета, а к какому-то иному реквизиту формы, значит, значение заполняется динамически.СчетаУчетаОС).Как показала практика, именно в этом часто кроется «обман» зрения: визуально данные есть, но в физической таблице справочника в поле СчетУчета записано значение ПустаяСсылка.
Допустим, реквизит в базе действительно существует и заполнен. Почему он все равно может не передаваться или отображаться некорректно? Выясним причину, кроющуюся в архитектуре COM-объектов. Когда мы получаем ссылку через COM, мы получаем не саму Ссылка текущей базы, а COM-обертку (объект типа ComObject).
Важно понимать: прямая передача ссылок между базами невозможна, так как ссылки — это уникальные идентификаторы (GUID), которые имеют смысл только внутри конкретной информационной базы. Даже если в обеих базах есть одинаковый план счетов, счета «01.01» в базе «Склад» и в базе «Бухгалтерия» могут иметь совершенно разные внутренние идентификаторы.
Рассмотрим способы корректного получения таких данных:
// Пример получения кода счета через COM-объект
СчетСсылкаCOM = ОбъектОС.СчетУчета;
КодСчета = СчетСсылкаCOM.Код; // Получим строку "01.01"
ПРЕДСТАВЛЕНИЕ().
// В запросе через COM лучше сразу выбирать представление
ТекстЗапроса = "ВЫБРАТЬ ПРЕДСТАВЛЕНИЕ(ОС.СчетУчета) КАК СчетПредставление ИЗ Справочник.ОсновныеСредства КАК ОС";
Если данные все же хранятся в регистре, нам придется выполнить запрос в базе-источнике через наше COM-соединение. Посмотрим на пример кода, который позволяет получить данные, даже если они не являются реквизитом справочника:
// Устанавливаем соединение (предположим, COMСоединение уже создано)
ЗапросCOM = COMСоединение.NewObject("Запрос");
ЗапросCOM.Текст =
"ВЫБРАТЬ
| СчетаУчетаОС.СчетУчета.Код КАК КодСчета
|ИЗ
| РегистрСведений.СчетаУчетаОС.СрезПоследних(&Период, ОсновноеСредство = &ОС) КАК СчетаУчетаОС";
ЗапросCOM.SetParameter("Период", ТекущаяДата());
ЗапросCOM.SetParameter("ОС", ОбъектОС_COM); // Передаем COM-ссылку на ОС
Выборка = ЗапросCOM.Execute().Choose();
Если Выборка.Next() Тогда
КодСчетаСтрокой = Выборка.КодСчета;
// Теперь в приемнике ищем счет по коду
СчетВПриемнике = ПланыСчетов.Хозрасчетный.НайтиПоКоду(КодСчетаСтрокой);
КонецЕсли;
Обратите внимание: мы выполняем запрос внутри контекста базы-источника, используя объекты, созданные через COMСоединение.NewObject. Это позволяет нам получить доступ ко всем таблицам базы данных, включая те, которые не связаны напрямую с объектом справочника.
Проанализируем еще один способ решения проблемы — использование XDTO-сериализации. Этот метод особенно полезен, если структуры баз идентичны. Вместо того чтобы поштучно вытягивать реквизиты, мы можем сериализовать объект в XML-строку в базе-источнике и десериализовать его в базе-приемнике.
Преимущества этого подхода:
Выясним разницу между двумя способами подключения, так как это напрямую влияет на доступность данных:
COMConnector вы всегда будете видеть пустое значение.Объект.Реквизит, если они не записаны в базу данных.Резюме: Если вы столкнулись с «пустым» реквизитом при работе через COM, первым делом проверьте, не является ли это поле расчетным или подтягиваемым из регистра сведений. Используйте запросы через COM-объект для получения актуальных данных из регистров и всегда оперируйте примитивными типами (строками, числами) для поиска соответствий в базе-приемнике.