Контрагент
экспорт
Интеграция и импорт данных
Разработка

Экспорт деталей контрагента в 1C 8.3

И снова здравствуйте!

Третий день мучаюсь с экспортом контрагентов в 1C. Сам контрагент, включая название передаётся легко, но загвоздка в его деталях - адресах, ИНН и КПП.

Адреса берутся из набора данных ТС "Адреса контрагента", а ИНН и КПП - из "Платежные реквизиты" но экспортируются в самого контрагента. То есть, это, вроде, подчинённые детали, а вроде и нет.

Сейчас детали настроены как подчинённые, чтобы была связь с самим контрагентом. Скорее всего, нужно правильное ключевое поле, которое я не могу подобрать. Всякие ID не будут совпадать, т.к. разные объекты в Террасофт, а других зацепок, по сути, нет.

Кто-нибудь решал эту проблему?

Нравится

14 комментариев

С ИНН и КПП разобрался программно, а также с произвольной строкой адреса. Теперь осталось только передавать детали адреса - Страну, Город, Улицу и т.д.

Лично у меня экспорт контрагентов всё одной настройкой...
Вот кусок с адресами. Событие OnAfterRecordExport:

[javascript]
//удалить все адреса и средства связи
var ci1C = Param.Obj1C.РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
ci1C.Отбор.Объект.Установить(Select1C.Ссылка);
//[не регистрируем изменения на стороне 1с
ci1C.ОбменДанными.Получатели.АвтоЗаполнение = false;
//]
ci1C.Записать();
//Адреса
var AccountID = Dataset('ID');
var ds = Services.GetNewItemByUSI('ds_AccountAddress');
ApplyDatasetFilter(ds, 'AccountID', AccountID, true);
ds.Open();
while(!ds.IsEOF) {
var ci1CMain = Param.Obj1C.РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
var ci1C = ci1CMain.Добавить();
ci1C.Объект = Select1C.Ссылка;
var met=Param.Obj1C.Метаданные.Перечисления.Найти("ТипыКонтактнойИнформации");
var meta=met.ЗначенияПеречисления.Найти('Адрес');
var metalink = Param.Obj1C.Перечисления.ТипыКонтактнойИнформации[meta.Имя];
ci1C.Тип = metalink;
var AdrTypeID = ds('KLADRAddressTypeID');
var AdrTypeUID1C = GetDatasetFieldValueByID('ds_AddressType',
AdrTypeID, 'UID1C');
var AddressType1CLink;
if(!IsEmptyValue(AdrTypeUID1C)) {
AddressType1CLink = GetObjectLinkByUID(
Param.Obj1C.Справочники.ВидыКонтактнойИнформации, AdrTypeUID1C, Param);
ci1C.Вид = !AddressType1CLink.Пустая() ? AddressType1CLink : null;
ci1C.Представление = ds('KLADRAddress');
ci1C.Поле1 = ds('KLADRAddressZIP');
ci1C.Поле2 = ds('KLADRAddressSubject');
ci1C.Поле3 = ds('KLADRAddressRegion');
ci1C.Поле4 = ds('KLADRAddressDistrictCenter');
ci1C.Поле5 = ds('KLADRAddressCity');
ci1C.Поле6 = ds('KLADRAddressStreet');
ci1C.Поле7 = ds('KLADRAddressHouse');
ci1C.Поле8 = ds('KLADRAddressCase');
ci1C.Поле9 = ds('KLADRAddressFlat');
//[не регистрируем изменения на стороне 1с
ci1CMain.ОбменДанными.Получатели.АвтоЗаполнение = false;
//]
ci1CMain.Записать(false);
}
ds.GotoNext();
}
ds.Close();
[/javascript]

По поводу заполнения справочных реквизитов...
Получаете ID страны из детали адреса, далее по этому ID получаете значение в поле UID1C, и далее получаете ссылку на страну в 1с, и кладете её в реквизит...
Примерно так:

[javascript]
var Invoice1C = Param.Obj1C.Документы.Счет;
var InvoiceUID1C = GetDatasetFieldValueByID('ds_Opportunity',
dlData.Dataset('ID'), 'UID1C');
InvoiceUID1C = CreateGUID1C(InvoiceUID1C, Param.Obj1C);
var Link1C = Invoice1C.GetRef(InvoiceUID1C);
[/javascript]

[javascript]
function CreateGUID1C(UID1C, Obj1C) {
if(UID1C == null) {
return '';
}
UID1C = UID1C.replace('{', '');
UID1C = UID1C.replace('}', '');
UID1C = Obj1C.NewObject('УникальныйИдентификатор', UID1C);
return UID1C;
}
[/javascript]

> Лично у меня экспорт контрагентов всё одной настройкой...

Да, этот ваш код мне сильно помог, хоть он и не подходит для 1С 8.3, так как "РегистрыСведений.КонтактнаяИнформация" больше не существует, они переехали в справочники.

> Получаете ID страны из детали адреса, далее по этому ID получаете значение в поле UID1C, и далее получаете ссылку на страну в 1с, и кладете её в реквизит...

Интересно. Меня смутило, что механизм интеграции определил эти поля как простые Строки, но попробовать надо.

ОК. Если что будет конкретного: кидайте ваш код или скрины.

Попробовал, не то чтобы получилось. Работает всё так:

Берём объект:

[javascript]
var Contragent = Select1C.Ссылка.ПолучитьОбъект();
[/javascript]

Получаем его ID, идём по списку адресов, добавляя каждый:

[javascript]
var AccountID = Dataset('ID');

var ds = Services.GetNewItemByUSI('ds_AccountAddress');
ApplyDatasetFilter(ds, 'AccountID', AccountID, true);
ds.Open();

while(!ds.IsEOF) {
AddAddress(Param, Contragent, ds);
ds.GotoNext();
}
ds.Close();

[/javascript]

Функция AddAddress:

[javascript]
var newAddress= Contragent.КонтактнаяИнформация.Добавить() ;
newAddress.Тип = Param.Obj1C.Перечисления.ТипыКонтактнойИнформации.Адрес;

switch(Dataset('AddressTypeID'))
{
//Добавляем вид адреса
}

//Из комментария выше
var Contragent1C = Param.Obj1C.Справочники.СтраныМира;
var CountryUID1C = GetDatasetFieldValueByID('ds_Country', Dataset('CountryID'), 'UID1C');
CountryUID1C = CreateGUID1C(CountryUID1C, Param.Obj1C);
newAddress.Страна = Contragent1C.GetRef(CountryUID1C);

Contragent.Записать(false);
[/javascript]

При этом поле Страна отображается верно. Однако, при обзоре в клиенте 1С, поле не заполнено.

Как-то так пока.

После записи выполните запрос в 1с и посмотрите что в этом поле. Если ничего - значит не записалось. Возможно срабатывают какие то проверки "перед записью" на стороне 1с?

Имеется ввиду запрос к БД 1С? Я, честно говоря, не в курсе, как это сделать с файловой версией 1С.

Забавно, но при попытке импорта импортируется именно то значение, что было экспортировано. Однако, в самом клиенте оно не меняется.

Посмотрите в 1С Администраторе - быть может в коде формы есть какая-то логика...

В функции РазместитьКонтактнуюИнформацию() логика загрузки простая:

[javascript]
ТаблицаРазмещенияКИ = УправлениеКонтактнойИнформациейБП.ПолучитьПустуюТаблицуРазмещенияКонтактнойИнформации();

УправлениеКонтактнойИнформациейБП.ДобавитьОписаниеРазмещенияКонтактнойИнформации(ТаблицаРазмещенияКИ, Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента, Элементы.ЮрАдресКонтрагента.ПутьКДанным);

[/javascript]

Ничего подозрительного пока не заметил.

Ну смотрите, предлагаю сделать так: зайдите в 1с и в меню "Операции" выберите "Обработка". Найдите там "КОнсоль запросов" либо "Консоль отчетов" (если нет - установите), и после записи через ТС выполните в обработке запрос к БД (думаю для файловой БД они тоже работают):

Выбрать ВашРеквизит Из Справочник.ВашСправочник.ВашаТаблЧасть
Где Ссылка.Наименование = "МойКонтрагент"

Если реквизит будет заполнен - значит запись проходит, если нет - значит нет :)

Если проходит - смотрите логику на карточке или в модуле объекта (чтото его при открытии чистит).
Если не проходит (но устанавливает корректно) - значит смотрите события модуля ПередЗаписью - что-то там его чистит.
Если не проходит (и не устанавливается) - скорее всего попутаны типы данных для реквизита.

пс: выполнение 1с-ного кода через COM (Террасофт) также можно отлаживать - погуглите.

Та-да! Всё дело в поле "ЗначенияПолей" (sic!), которое содержит... значения полей! То есть, значения всех остальных полей, у которых есть и свои собственные значения, только в xml формате. Я уже попробовал просто вбить скопированный и подправленный xml, всё загружается. Подробнее инфу можно найти тут: http://forum.aeroion.ru/topic779.html

Спасибо, Дмитрий. Без консоли запросов я бы ещё долго бился бы об это.

Ого! Это что-то новое :)

Показать все комментарии