При интеграции баз данных 1С и переносе справочников через прямое COM-соединение разработчики часто сталкиваются с ситуацией: элемент номенклатуры успешно создается, однако при программном обращении к нему реквизиты ВидНоменклатуры или Услуга оказываются пустыми либо содержат значения по умолчанию (например, Ложь вместо Истина). При этом, если открыть элемент интерактивно в пользовательском интерфейсе и вручную перевыбрать вид номенклатуры, данные начинают отображаться и считываться корректно.
Разберем детально, почему возникает подобное поведение платформы 1С:Предприятие, какие тонкости контекста COM-соединения необходимо учитывать и как правильно программно переносить номенклатуру.
Выясним главные факторы, приводящие к ошибкам при программном создании элементов справочника:
Услуга при выборе определенного вида номенклатуры) реализована в клиентских обработчиках событий формы (ПриИзменении). При создании объекта через COM-соединение код формы не исполняется, а срабатывают только события модуля объекта и модуля менеджера. Поэтому автоматического заполнения связанных полей не происходит.ВидНоменклатуры должна быть найдена или создана строго в контексте COM-соединения целевой базы. Если передать чужую ссылку или значение не того типа, реквизит останется пустым или получит значение Неопределено.Услуга (булево) непосредственно в справочнике Номенклатура, ссылка на справочник ВидыНоменклатуры, а также реквизит ТипНоменклатуры внутри самого вида номенклатуры. Все эти поля должны быть согласованы между собой.Рассмотрим правильный алгоритм переноса номенклатуры из конфигурации «Управление торговлей 11» в «Бухгалтерию предприятия 3.0» через COM-соединение.
ВидыНоменклатуры в целевой базе по наименованию или уникальному идентификатору (GUID).ВидНоменклатуры и Услуга у создаваемого объекта номенклатуры в приемнике.Записать().Посмотрим на пример программного кода в базе-источнике (УТ 11):
// Устанавливаем COM-соединение с базой БП
V8Коннектор = Новый COMОбъект("V83.COMConnector");
БазаБП = V8Коннектор.Connect("Srvr=""Server1C"";Ref=""buh_db"";Usr=""Admin"";Pwd=""Password"";");
// Получаем данные номенклатуры из текущей базы (УТ)
ВыборкаУТ = Справочники.Номенклатура.Выбрать();
Пока ВыборкаУТ.Следующий() Цикл
// Пропускаем группы
Если ВыборкаУТ.ЭтоГруппа Тогда
Продолжить;
КонецЕсли;
// Создаем или находим номенклатуру в БП
НомБПСсылка = БазаБП.Справочники.Номенклатура.НайтиПоНаименованию(ВыборкаУТ.Наименование);
Если НомБПСсылка.Пустая() Тогда
НомБПОбъект = БазаБП.Справочники.Номенклатура.СоздатьЭлемент();
НомБПОбъект.Наименование = ВыборкаУТ.Наименование;
НомБПОбъект.НаименованиеПолное = ВыборкаУТ.НаименованиеПолное;
Иначе
НомБПОбъект = НомБПСсылка.ПолучитьОбъект();
КонецЕсли;
// Ищем соответствующий вид номенклатуры строго в контексте БП
НаименованиеВида = ВыборкаУТ.ВидНоменклатуры.Наименование;
ВидНомБП = БазаБП.Справочники.ВидыНоменклатуры.НайтиПоНаименованию(НаименованиеВида);
Если Не ВидНомБП.Пустая() Тогда
НомБПОбъект.ВидНоменклатуры = ВидНомБП;
КонецЕсли;
// Явно определяем и проставляем признак услуги в базе-приемнике
Если ВыборкаУТ.ТипНоменклатуры = Перечисления.ТипыНоменклатуры.Услуга Тогда
НомБПОбъект.Услуга = Истина;
Иначе
НомБПОбъект.Услуга = Ложь;
КонецЕсли;
// Записываем подготовленный объект
НомБПОбъект.Записать();
КонецЦикла;
Проанализируем ситуацию, если после переноса поведение элемента все еще вызывает сомнения. В этом случае полезно воспользоваться консолью запросов в базе-приемнике:
Справочник.Номенклатура и детально сравниваем их значения.ЕдиницаИзмерения, СтавкаНДС, НоменклатурнаяГруппа и признак Услуга.Работа через прямой COM-коннектор накладывает технические ограничения: требование к совпадению разрядности процессов (32/64 бит) и точной версии платформы. Если перенос номенклатуры требуется выполнять регулярно, рекомендуем рассмотреть альтернативные архитектурные подходы: