И снова здравствуйте!
Третий день мучаюсь с экспортом контрагентов в 1C. Сам контрагент, включая название передаётся легко, но загвоздка в его деталях - адресах, ИНН и КПП.
Адреса берутся из набора данных ТС "Адреса контрагента", а ИНН и КПП - из "Платежные реквизиты" но экспортируются в самого контрагента. То есть, это, вроде, подчинённые детали, а вроде и нет.
Сейчас детали настроены как подчинённые, чтобы была связь с самим контрагентом. Скорее всего, нужно правильное ключевое поле, которое я не могу подобрать. Всякие ID не будут совпадать, т.к. разные объекты в Террасофт, а других зацепок, по сути, нет.
Кто-нибудь решал эту проблему?
Нравится
С ИНН и КПП разобрался программно, а также с произвольной строкой адреса. Теперь осталось только передавать детали адреса - Страну, Город, Улицу и т.д.
Лично у меня экспорт контрагентов всё одной настройкой...
Вот кусок с адресами. Событие 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
Спасибо, Дмитрий. Без консоли запросов я бы ещё долго бился бы об это.