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

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

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

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

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

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

Нравится

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

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

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

//удалить  все адреса и средства связи	
	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();

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

var Invoice1C = Param.Obj1C.Документы.Счет;
var InvoiceUID1C = GetDatasetFieldValueByID('ds_Opportunity', 
	dlData.Dataset('ID'), 'UID1C');
InvoiceUID1C = CreateGUID1C(InvoiceUID1C, Param.Obj1C);
var Link1C = Invoice1C.GetRef(InvoiceUID1C);
function CreateGUID1C(UID1C, Obj1C) {
	if(UID1C == null) {
		return '';
	}
	UID1C = UID1C.replace('{', '');
	UID1C = UID1C.replace('}', '');
	UID1C = Obj1C.NewObject('УникальныйИдентификатор', UID1C);
	return UID1C;
}

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

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

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

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

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

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

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

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

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

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();

Функция AddAddress:

	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);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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