При организации переноса данных между базами 1С (например, из 1С:Бухгалтерия предприятия 3.0 в нетиповую 1С:Управление торговлей 10.3) разработчики часто используют прямое программное подключение через COM-соединение. Для отключения лишних проверок и логики проведения принято устанавливать свойство ОбменДанными.Загрузка = Истина. Однако нередко при записи объекта платформа все равно генерирует критическую ошибку. Разберем подробно, почему это происходит и как решить данную проблему без изменения конфигурации базы-приемника.
Рассмотрим, как устроено свойство ОбменДанными.Загрузка в платформе 1С:Предприятие. Согласно документации, если параметру присвоено значение Истина, платформа отключает системные проверки (контроль уникальности номеров и кодов, обязательность заполнения реквизитов на уровне метаданных). Однако важно помнить следующее:
ПередЗаписью, ПриЗаписи и зарегистрированные в метаданных подписки на события (Event Subscriptions) не отключаются автоматически платформой.
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Проанализируем типичный сценарий, в котором возникает сбой. При подключении через COM-объект создается сеанс с контекстом «Внешнее соединение» (COM-соединение). В этом режиме среда исполнения платформы кардинально отличается от интерактивного сеанса толстого или тонкого клиента:
#Если Клиент Тогда ... #КонецЕсли, физически не компилируется в режиме внешнего соединения и отсутствует в памяти процесса.Процедура или функция с указанным именем не определена.Посмотрим на пример проблемного участка в базе-приемнике:
#Если Клиент Тогда
Функция ОбъектИсключенИзПроверкиПравДоступаПоПериоду(Объект) Экспорт
ИсключенияИзПроверки = Новый Массив;
ИсключенияИзПроверки.Добавить(Тип("ДокументОбъект.АктСверкиВзаиморасчетов"));
Если ИсключенияИзПроверки.Найти(ТипЗНЧ(Объект)) = Неопределено Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
#КонецЕсли
При вызове этой функции из подписки на событие в контексте COMConnector происходит падение, даже если свойство ОбменДанными.Загрузка установлено в Истина.
Если вносить правки в рабочую конфигурацию базы-приемника нельзя, разберем альтернативные пути решения задачи.
Выясним разницу между компонентами подключения. Объект V83.COMConnector инициализирует легковесное внешнее соединение, где недоступен клиентский контекст. В то же время V83.Application запускает полноценный клиентский сеанс, где директивы #Если Клиент Тогда успешно отрабатывают.
Рассмотрим пример кода подключения и записи объекта:
// Инициализируем Automation-сервер вместо COMConnector
СоединениеБД = Новый COMОбъект("V83.Application");
СтрокаПодключения = "Srvr=""Сервер1С"";Ref=""БазаПриемник"";Usr=""Пользователь"";Pwd=""Пароль"";";
СоединениеБД.Connect(СтрокаПодключения);
ПлПрВ = СоединениеБД.Документы.ПлатежноеПоручениеВходящее;
// Создание и запись документа
ППВ = ПлПрВ.СоздатьДокумент();
ППВ.Дата = ТекущаяДата();
ППВ.Номер = "000000001";
ППВ.ОбменДанными.Загрузка = Истина;
ППВ.Записать();
Если требуется продолжить использование COMConnector, можно вынести процедуру создания и заполнения документов во внешнюю обработку, запускаемую на стороне приемника через COM:
.epf), в экспортном методе которой реализуем создание документа, ручное управление движениями и заполнение реквизитов.СоединениеБД.ВнешниеОбработки.Создать("ПутьКФайлу.epf").Рассмотрим вариант с полным отказом от прямой COM-записи в пользу штатных механизмов:
ОбменДанными.Загрузка = Истина отрабатывает без сбоев препроцессора.