При интеграции различных информационных систем на базе 1С:Предприятие одной из наиболее часто встречающихся задач является перенос данных или создание документов в одной базе на основании данных из другой. Однако механизм COM-соединения (или внешнего соединения) остается одним из самых надежных и популярных способов реализации прямого взаимодействия. В этой статье мы детально разберем, как программно подключиться к внешней базе, создать в ней документ и корректно заполнить его табличную часть, учитывая особенности работы со ссылочными типами данных. Для автоматизации этих процессов можно использовать готовое решение для универсального переноса данных между конфигурациями 1С.
Прежде чем мы перейдем к заполнению табличной части, нам необходимо установить связь с информационной базой. Проанализируем, какой объект нам для этого понадобится. В платформе 1С для этих целей используется объект V83.COMConnector. Основное отличие внешнего соединения от запуска полноценного приложения (через V83.Application) заключается в том, что внешнее соединение работает быстрее и потребляет меньше ресурсов, так как не инициализирует графический интерфейс клиента. При возникновении технических сложностей с разрядностью или версиями платформы на сервере пригодится методика запуска COM-объекта в виде удаленного COM+.
Рассмотрим пример инициализации подключения к базе:
Попытка
COMСоединитель = Новый COMОбъект("V83.COMConnector");
// Строка подключения зависит от типа базы (файловая или серверная)
СтрокаСоединения = "Srvr='ServerName';Ref='BaseName';Usr='Login';Pwd='Password';";
ВнешняяБаза = COMСоединитель.Connect(СтрокаСоединения);
Исключение
Сообщить("Не удалось установить соединение: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
После успешного выполнения метода Connect(), переменная ВнешняяБаза становится точкой входа. Через нее мы получаем доступ к метаданным, менеджерам документов и справочников. Стоит отметить, что через такое соединение можно даже получать данные отчетов.
Представим ситуацию: нам необходимо создать документ РеализацияТоваровУслуг во внешней базе и заполнить его табличную часть Товары. Важно понимать, что все действия происходят в контексте удаленной базы, поэтому методы создания и поиска должны вызываться через объект соединения.
Разберем по шагам алгоритм действий:
Посмотрим на практический пример кода, который реализует данную логику:
// Создаем новый документ во внешней базе
НовыйДок = ВнешняяБаза.Documents.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйДок.Дата = ТекущаяДата();
НовыйДок.Организация = ВнешняяБаза.Reference.Организации.НайтиПоРеквизиту("ИНН", "7701010101");
// Начинаем заполнение табличной части
Для Каждого СтрокаДанных Из ТЗ_ДанныеДляПереноса Цикл
// Добавляем новую строку в ТЧ документа внешней базы
НоваяСтрока = НовыйДок.Товары.Добавить();
// Важный момент: поиск номенклатуры во внешней базе
// Мы не можем просто присвоить ссылку из текущей базы!
СсылкаНоменклатура = ВнешняяБаза.Catalogs.Номенклатура.НайтиПоНаименованию(СтрокаДанных.Наименование);
Если Не СсылкаНоменклатура.Пустая() Тогда
НоваяСтрока.Номенклатура = СсылкаНоменклатура;
НоваяСтрока.Количество = СтрокаДанных.Количество;
НоваяСтрока.Цена = СтрокаДанных.Цена;
НоваяСтрока.Сумма = СтрокаДанных.Количество * СтрокаДанных.Цена;
КонецЕсли;
КонецЦикла;
// Записываем документ с проведением
Попытка
НовыйДок.Записать(ВнешняяБаза.DocumentWriteMode.Write); // Или .Post для проведения
Сообщить("Документ успешно создан во внешней базе!");
Исключение
Сообщить("Ошибка при записи документа: " + ОписаниеОшибки());
КонецПопытки;
Одной из главных проблем начинающих разработчиков является попытка передать ссылку (объект типа СправочникСсылка) напрямую из текущей базы во внешнюю. Важно помнить: ссылки одной базы не имеют никакого смысла в другой базе, даже если конфигурации идентичны. У них разные уникальные идентификаторы (GUID).
Для решения этой проблемы мы используем следующие методы поиска во внешней базе:
НайтиПоКоду() — если коды синхронизированы.НайтиПоНаименованию() — если названия уникальны.НайтиПоРеквизиту() — например, по ИНН для контрагентов или Артикулу для товаров.GUID — самый надежный метод, если объекты создавались путем обмена данными.Рассмотрим пример поиска по GUID, так как это наиболее профессиональный подход:
// Получаем строку GUID из текущей базы
СтрокаGUID = Строка(ТекущаяНоменклатура.УникальныйИдентификатор());
// Находим этот же объект во внешней базе
ВнешняяСсылка = ВнешняяБаза.Catalogs.Номенклатура.GetRef(ВнешняяБаза.NewObject("UUID", СтрокаGUID));
Если ВнешняяБаза.XMLString(ВнешняяСсылка) = ВнешняяБаза.XMLString(ВнешняяБаза.Catalogs.Номенклатура.EmptyRef()) Тогда
// Объект не найден
Иначе
НоваяСтрока.Номенклатура = ВнешняяСсылка;
КонецЕсли;
Проанализируем ситуацию: если в табличной части документа тысячи строк, каждое обращение к внешней базе через Добавить() и последующий поиск НайтиПоНаименованию() будет инициировать отдельный сетевой вызов (RPC). Это может привести к крайне низкой скорости работы.
Чтобы оптимизировать процесс, мы рекомендуем использовать следующие приемы:
Пример вызова серверной функции внешней базы для обработки данных:
// Во внешней базе должна быть процедура в общем модуле с флагом "Внешнее соединение"
// Процедура ЗагрузитьДокументИзJSON(ДанныеJSON) Экспорт ...
ДанныеДляПередачи = СформироватьJSONДанные(); // Формируем строку данных
ВнешняяБаза.ОбщийМодульИнтеграции.ЗагрузитьДокументИзJSON(ДанныеДляПередачи);
Мы изучили механизм заполнения табличных частей через COM-соединение. Главные правила, которые мы выделили:
Во-первых, всегда проверяйте успешность подключения. Во-вторых, помните, что объекты ссылочных типов нужно искать в целевой базе заново. В-третьих, для повышения производительности старайтесь сокращать количество обращений через границу COM-соединения, используя передачу массивов или структурированных строк.
Соблюдение этих рекомендаций позволит вам создавать надежные и быстрые механизмы интеграции между базами 1С:Предприятие 8.3.