Имя: Пароль:
1C
1С v8
Тип AnyType в Веб-сервисах и массив
0 Dagmanor
 
21.05.13
16:46
Доброго времени суток, Есть веб-сервис, написанный на другой конфигурации 1С (платформа 8.2). В текущей конфигурации (тоже 8.2) я создал ВС-Ссылку, все как обычно, но в одной из операций Веб-сервиса один из параметров имеет тип AnyType (изначально так писалось потому, что туда передается массив из стороннего приложения), а теперь мне необходимо передать туда массив из другой 1С, при потытке это сделать 1С ругается на несоответствие типов...

Может кто подскажет почему?
Теоретически AnyType должен принимать любой тип...
1 acsent
 
21.05.13
16:53
1совский массив передаешь что ли?
2 Dagmanor
 
21.05.13
16:54
Да
3 Dagmanor
 
21.05.13
17:15
Актуально
4 Dagmanor
 
21.05.13
17:20
Люди... реально нужна помощь... Неужели никто не знает в чем загвоздка?
5 Serginio1
 
21.05.13
17:20
А как передаешь?
Парам=СериализаторXDTO.ЗаписатьXDTO(массив)
6 Dagmanor
 
21.05.13
17:25
нет. как обычно:
"массив = новый массив" и в параметр его
7 Dagmanor
 
21.05.13
17:32
Пробовал так:    

        массив = новый Массив;
     массив.Добавить("ХХХХ");
     массив.Добавить("ХХХХ");
     массив.Добавить("ХХХХ");
     
     Парам = СериализаторXDTO.ЗаписатьXDTO(массив);
    Сервис.Операция(П1,П2,П3,П4,Парам);

====Ошибка====
Невідома помилка. Невідповідність типів XDTO:
Тип '{http://v8.1c.ru/8.1/data/core}Array' не знайдений
Тип належить пакету, що відсутній у фабриці типів XDTO
через:
Невідповідність типів XDTO:
Тип '{http://v8.1c.ru/8.1/data/core}Array' не знайдений
Тип належить пакету, що відсутній у фабриці типів XDTO
8 Dagmanor
 
21.05.13
17:33
Как мне его втулить в AnyType?
9 Fragster
 
гуру
21.05.13
17:34
пихай элементы в списокXDTO
10 acsent
 
21.05.13
17:36
ПараметрXDTO = СоздатьПараметр("GetListItems");
   
   ПараметрXDTO.listName     = ИмяСписка;
   ПараметрXDTO.rowLimit     = "500";
   
   Если ЗначениеЗаполнено(Представление) Тогда
       ПараметрXDTO.viewName = Представление;
   КонецЕсли;
   //ПараметрXDTO.query        = "";
   //ПараметрXDTO.viewFields   = "";
   //ПараметрXDTO.queryOptions = "";
   //ПараметрXDTO.webID        = "";
   
   Если ТипЗнч(Отбор) = Тип("Структура") Тогда
       
       ЗаписьXML = Новый ЗаписьXML;
       ЗаписьXML.УстановитьСтроку();
       ЗаписьXML.ЗаписатьНачалоЭлемента("Query");
       ЗаписьXML.ЗаписатьНачалоЭлемента("Where");
       
       Для каждого КлючИЗначение Из Отбор Цикл
           
           ЗаписьXML.ЗаписатьНачалоЭлемента("Eq");
           ЗаписьXML.ЗаписатьНачалоЭлемента("FieldRef");
           ЗаписьXML.ЗаписатьАтрибут("Name", КлючИЗначение.Ключ);
           ЗаписьXML.ЗаписатьКонецЭлемента(); // FieldRef
           
           ЗаписьXML.ЗаписатьНачалоЭлемента("Value");
           
           Если ТипЗнч(КлючИЗначение.Значение) = Тип("Дата") Тогда
               ЗаписьXML.ЗаписатьАтрибут("Type", "Date");
               ЗаписьXML.ЗаписатьТекст(Формат(КлючИЗначение.Значение, "ДФ=yyyy-MM-dd"));
           Иначе
               ЗаписьXML.ЗаписатьАтрибут("Type", "Text");
               ЗаписьXML.ЗаписатьТекст(КлючИЗначение.Значение);
           КонецЕсли;
           
           ЗаписьXML.ЗаписатьКонецЭлемента(); // Value
           
           ЗаписьXML.ЗаписатьКонецЭлемента(); // Gt
           
       КонецЦикла;
       
       ЗаписьXML.ЗаписатьКонецЭлемента(); // Where
       ЗаписьXML.ЗаписатьКонецЭлемента(); // Query
       
       СтрокаBatch = ЗаписьXML.Закрыть();
       
       ЧтениеXML = Новый ЧтениеXML;
       ЧтениеXML.УстановитьСтроку(СтрокаBatch);
       ОбъектBatch = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
       
       ПараметрXDTO_query = СоздатьПараметр("GetListItems_query");
       
       ПараметрXDTO.query = ПараметрXDTO_query;
       ПараметрXDTO.query.Добавить(ФормаXML.Элемент, ПространствоИмен, "Query", ОбъектBatch);
11 blopp
 
21.05.13
17:38
(10)
Отец!

А дальше с этим что делать, в свой SOAP клиент пихать?
Может тогда заодно и код приложишь?

(7)
Для того что бы массив пролез в web-сервис, у него в wsdl должен быть импортирован /data/core
12 Serginio1
 
21.05.13
17:47
(7) А по русски. А то я по хохляцки неразумею.
Ну смысл в том, что в пакете нет массива.
Тьфу. Тебе надо не СериализаторXDTO.ЗаписатьXDTO(массив);
а прокси использовать.

ТипСтрока=Фабрика.Тип("http://www.w3.org/2001/XMLSchema","string");
Фабрика=Прокси.ФабрикаXDTO;
СписокОбъектов = Фабрика.Создать(Фабрика.Тип("http://v8.1c.ru/8.1/data/core", "Array"));

Дя каждого стр из массив Цикл
Значение=Фабрика.Создать(ТипСтрока,стр);


СписокОбъектов.value.Добавить(Значение);
КонецЦикла;
13 Serginio1
 
21.05.13
17:50
(11) У него (Есть веб-сервис, написанный на другой конфигурации 1С (платформа 8.2))
14 blopp
 
21.05.13
17:51
(12)
Вот за что я люблю мисту ;)

Приведенный код сделает тоже самое что и автора (7), но гораздо более громоздко и только для строк.

Разница только в том что у автора используется глобальная фабрика, а в (12) от web-сервиса.

От web-сервиса более правильно (по сути, единственно правильно), но для встроенных типов пофигу.
15 Serginio1
 
21.05.13
17:52
(14) Есть разница между ФабрикаXDTO и Прокси.ФабрикаXDTO
16 blopp
 
21.05.13
17:53
(13) Спс. кэп, это вроде как бы следует из (0) ;)

Какое это имеет отношение к:
- коду который сам формирует XML мимо фабрики XDTO из (10)
- тому факту что в этот web-сервис не импортировано пространство имен http://v8.1c.ru/8.1/data/core и массив в него не влезет?
17 blopp
 
21.05.13
17:55
(15) Точно
Одна глобальная, а другая от web-сервиса.
И присваивать объекты созданные фабрики свойствам объектов созданных другой нельзя.

Но для встроенных в платформу пакетов (кроме current-config) разницы нету - т.е. присваивать можно
18 acsent
 
21.05.13
17:57
(16) в (10) был код как своствам XDTO устанавливать произвольную XML структуру
19 Serginio1
 
21.05.13
17:58
Но Можно копировать  

Парам = СериализаторXDTO.ЗаписатьXDTO(массив);

Фабрика=Прокси.ФабрикаXDTO;
СписокОбъектов = Фабрика.Создать(Фабрика.Тип("http://v8.1c.ru/8.1/data/core", "Array"));

Для каждого стр из массив Цикл
Тип=СериализаторXDTO.XMLТипЗнч(стр);
Значение=Фабрика.Создать(Фабрика.Тип(Тип.URIПространстваИмен, Тип.ИмяТипа),XMLСтрока(стр));
СписокОбъектов.value.Добавить(Значение);

КонецЦикла;
20 Serginio1
 
21.05.13
18:00
(17) Ты пробовал?
21 blopp
 
21.05.13
18:02
(18) Довольно странно выглядит:
- записать наколенными средствами XML
- прочитать его в anyType
- установить в качестве значения другого свйоства anyType

Почему сразу не создать нужный XDTO объект? Что бы не заморачиваться с синтаксисом методов фабрики?

(19) Это не очень работающий код
XMLСтрока - это вообще не XDTO сериализация.
Лучше уж просто записать все в XML одной фабрикой и прочитать другой

(20)
Угу.
Это местами в БСП юзается, хотя наверное зря - не документировано ведь.
22 acsent
 
21.05.13
18:03
(21) так устроены веб сервисы шарепойнт
23 acsent
 
21.05.13
18:04
(21) как создать нужный объект, если его нет в типах?
24 blopp
 
21.05.13
18:06
(22) Не оч. понятно какое-то отношение странный способ создания XDTO объекта в 1сике имеет к внешней системе - она ведь уже XML получает.
Ну да мне пофиг, если честно.

(23) Если типизированный - ни как.
Но ты ведь и создаешь не типизированный.
Создаешь anyType и добавляешь ему свойства (ну или текст заполняешь).
25 Serginio1
 
21.05.13
18:07
(17) Для встроенных платформ просто можно передавать через строку используя ЗаписатьXML ПрочитатьXML
(21) Ты пробовал?
Значение=Фабрика.Создать(Фабрика.Тип(Тип.URIПространстваИмен, Тип.ИмяТипа),XMLСтрока(стр));

Как раз и создает нужное представление. Другое дело, что может не быть такого типа в другой конфигурации.
Это работает. Я перенос между базами делаю на уровне объектовXDTO
26 acsent
 
21.05.13
18:09
(24) покажи код, как anytype создать и добавить свойства
27 acsent
 
21.05.13
18:10
(24) собственно вариант из (10) предложили 1совцы на партнерском
28 blopp
 
21.05.13
18:17
(25) XMLСтрока - это сериализация от 8.0.
Для некоторых типов (для которых есть XDTO сериалиазация) она просто не предусмотрена

(26) Под рукой нет - постараюсь вечером скинуть
Линк на ветку не сохранился случайно?
29 Serginio1
 
21.05.13
18:23
(28) В данном случае для значений (не объектов) я еще не видел такого.
30 Serginio1
 
21.05.13
18:28
29+ а вот объекты приходится копировать. Но там есть проблема с Anyref их нужно отдельно обрабатывать

Объект = Фабрика.Создать(Фабрика.Тип(ПространствоИмен, Имя));
ТипРеал=ФабрикаXDTO.Тип(ПространствоИмен,Имя);
ТекОбъект=  СериализаторXDTO.ЗаписатьXDTO(Док);
ЗаполнитьЗначенияСвойств(Объект,ТекОбъект,,"ДокументОснование");

Если ТекОбъект.ДокументОснование<>Неопределено Тогда
Тип=СериализаторXDTO.XMLТипЗнч(ТекОбъект.ДокументОснование);
Объект.ДокументОснование=Фабрика.Создать(Фабрика.Тип(Тип.URIПространстваИмен, Тип.ИмяТипа),XMLСтрока(ТекОбъект.ДокументОснование));
Иначе
Объект.ДокументОснование=СсылкаNull
КонецЕсли;
31 Serginio1
 
21.05.13
18:34
32 Serginio1
 
21.05.13
18:39
Кстати для регистров сведений СерализатоXDTO и ФабрикаXDTO по разному генерируют XML
33 Serginio1
 
21.05.13
18:52
ОбъектXDTO=СериализаторXDTO.ЗаписатьXDTO(Массив);
    ЗаписьХМЛ= Новый ЗаписьXML;
    ЗаписьХМЛ.УстановитьСтроку();

   ФабрикаXDTO.ЗаписатьXML(ЗаписьХМЛ, ОбъектXDTO);
   Стр=ЗаписьХМЛ.Закрыть();

   
   
   ЧтениеXML.УстановитьСтроку(стр);
   ЧтениеXML.ПерейтиКСодержимому();


   ТипОбъектаXDTO=Прокси.ФабрикаXDTO.Тип(ЧтениеXML.URIПространстваИмен,ЧтениеXML.Имя);
   
  Парам =Прокси.ФабрикаXDTO.ПрочитатьXML(ЧтениеXML,ТипОбъектаXDTO);
34 Fragster
 
гуру
21.05.13
19:37
(32) мне больше нравится то, что в 8.1 (а возможно и 8.2) Сериализатор.ЗаписатьXML для набора записей регистра бухгалтерии с несколькими субконто не работает
35 blopp
 
22.05.13
10:32
(26) Пример не нашел, видимо вытер когда переделывал на другую ветку.

Примерно так:
Объект = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "anyType"));
   Объект.Добавить(ФормаXML.Атрибут, "http://www.w3.org/2001/XMLSchema", "atr",
       ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string"), "Значение атрибута"));
   Объект.Добавить(ФормаXML.Элемент, "http://www.w3.org/2001/XMLSchema", "elem",
       ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string"), "Значение элемента"));
36 blopp
 
22.05.13
10:53
(30) Я не оч. понимаю для чего все это?
Почему просто весь объект не записать в XML одной фабрикой а потом прочитать другой?

(32) Пруф?
Или хотя бы пример разного XML'а?

(34) Для 8.2 точно работает, ну а 8.1..
37 Serginio1
 
22.05.13
10:58
(35) Да работает
Объект = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "anyType"));
      ЗначениеАтрибута=ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string"), "Значение атрибута");

   Объект.Добавить(ФормаXML.Атрибут, "http://www.w3.org/2001/XMLSchema", "atr",ЗначениеАтрибута);


   Объект.Добавить(ФормаXML.Элемент, "http://www.w3.org/2001/XMLSchema", "elem",ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string"), "Значение Элемента"));

     //  ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string"), "Значение элемента"));
   ЗаписьХМЛ= новый ЗаписьXML;
   ЗаписьХМЛ.УстановитьСтроку();
   ФабрикаXDTO.записатьXML(ЗаписьХМЛ,Объект);
   //записатьXML(ЗаписьХМЛ,ОтветТаблицаЦен);
   текст=Новый ТекстовыйДокумент;
   Текст.УстановитьТекст(ЗаписьХМЛ.Закрыть());
   Текст.Показать();

Выдает
<anyType xmlns="http://www.w3.org/2001/XMLSchema" xmlns:d1p1="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" d1p1:atr="Значение атрибута">
   <elem>Значение Элемента</elem>
</anyType>
38 Serginio1
 
22.05.13
11:04
(36) Вообще показаны различные техники. Необязательно заполнять массив а потом преобразовывать в ОбъектXDTO.
в 33 есть и этот вариант.
Можно просто заполняить нужный ОбъектXDTO.
Например для такой подход не срабатывает для объектов (DocumentObject,CatalogObject ...) если реквизиты
Чем больше вариантов более понятние ТК, а может и другим кто хочет разобраться.
39 Serginio1
 
22.05.13
11:12
37 если добавить
Объект.Добавить(ФормаXML.Элемент, "http://www.w3.org/2001/XMLSchema", "elem",ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string"), "Значение Элемента"));
уже появляется elem как СписокXDTO.
Спасибо буду знать.
Аналогичное решение для  "http://schemas.xmlsoap.org/wsdl/", "Array",

v8: Заполнение массива XDTO
40 Serginio1
 
22.05.13
11:28
(36) Возьми просто набор для регистров запиши через ЗаписатьXML и ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, Объект);
где объект это ОбъектXDTO
поэтому для
ОбъектXDTO=ФабрикаXDTO.ПрочитатьXML(ЧтениеXML,ФабрикаXDTO.Тип(ЧтениеXML.URIПространстваИмен,Имя));

Если Имя="InformationRegisterRecordSet.КонтактнаяИнформация" Тогда
Объект=ЗагрузитьКонтактнуюИнформацию(ОбъектXDTO)
   Иначе
Объект=СериализаторXDTO.ПрочитатьXDTO(ОбъектXDTO);
КонецЕсли;


Функция ЗагрузитьКонтактнуюИнформацию(ОбъектXDTO)
   Набор=РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
   
   Отборы=ОбъектXDTO.Filter.FilterItem;
   Для каждого стр из Отборы Цикл
   Набор.Отбор[Стр.Name].Установить(Стр.Value);
   КонецЦикла;    
   
   Записи=ОбъектXDTO.Record;
   Для каждого стр из Записи Цикл
       СтрНабор=Набор.Добавить();
       ЗаполнитьЗначенияСвойств(СтрНабор,Стр);
       
   КонецЦикла;
   
   Возврат Набор
КонецФункции

Кстати были проблемы и с для набора записей регистра бухгалтерии  как уже отмечал   Fragster в 34
41 Serginio1
 
22.05.13
12:06
(36)
Вот разница
Это формирует ФабрикаXDTO
<InformationRegisterRecordSet.КонтактнаяИнформация>
       <Filter xmlns:d3p1="http://v8.1c.ru/8.1/data/enterprise">
           <d3p1:FilterItem>
               <d3p1:Name>Объект</d3p1:Name>
               <d3p1:Value xsi:type="CatalogRef.Контрагенты">7767e9cd-50dd-11e2-9927-c86000c70663</d3p1:Value>
           </d3p1:FilterItem>
       </Filter>

А вот Сериализатор

<InformationRegisterRecordSet.КонтактнаяИнформация>
       <Filter>
           <FilterItem xmlns="http://v8.1c.ru/8.1/data/enterprise">
               <Name xsi:type="xs:string">Объект</Name>
               <Value xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config" xsi:type="d5p1:CatalogRef.Контрагенты">7767e9cd-50dd-11e2-9927-c86000c70663</Value>
           </FilterItem>
       </Filter>
42 blopp
 
22.05.13
12:22
(41) Кажется, это мелочь.
Фактически XML эквивалентен.

От того что еще пространству имен назначается еще один префикс ничего страшного не произойдет.

Приведенный XML от фабрики - это явно фрагмент.
Где-то выше должно быть написано что все записано в контексте http://v8.1c.ru/8.1/data/enterprise/current-config, т.е. типы без указания пространства имен к нему и относятся.
43 Serginio1
 
22.05.13
12:27
(42) Но вот Объект=СериализаторXDTO.ПрочитатьXDTO(ОбъектXDTO); такой текст не читает
Конечно фрагмент зачем тебе описание типов? Я привел различие. При этом справочники, документы прекрасно читаются.
Там везде стоит
ЗаписьXML.ЗаписатьОбъявлениеXML();
   
   ЗаписьXML.ЗаписатьНачалоЭлемента(XMLСтрока("Данные"));
   ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("", "http://v8.1c.ru/8.1/data/enterprise/current-config");
   ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
   ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xs", "http://www.w3.org/2001/XMLSchema");
44 Serginio1
 
22.05.13
12:29
43 в Любом случае не должно быть различий. Это баг
45 Serginio1
 
22.05.13
12:32
Вернее сериализатор не читает ОбъектXDTO.
Не помню Про ПрочитатьXML. Сейчас посмотрю.
46 blopp
 
22.05.13
12:37
(44) - да их и нет.

Как записывать все равно - просто фабрика не умеет определять не явно заданный тип.

Если типы задавать явно - будет работать все равно через что писать.

На всякий случай проверил:
   Набор = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
   Набор.Отбор.Валюта.Установить(Справочники.Валюты.ПолучитьСсылку());
   
   Запись = Новый ЗаписьXML;
   Запись.УстановитьСтроку();
   ФабрикаXDTO.ЗаписатьXML(Запись, СериализаторXDTO.ЗаписатьXDTO(Набор), , , , НазначениеТипаXML.Явное);
   СтрокаФабрики = Запись.Закрыть();
   Сообщить("Фабрика:" + Символы.ПС + СтрокаФабрики);
   
   Запись = Новый ЗаписьXML;
   Запись.УстановитьСтроку();
   СериализаторXDTO.ЗаписатьXML(Запись, Набор, НазначениеТипаXML.Явное);
   СтрокаСериализатора = Запись.Закрыть();
   Сообщить("Сериализатор:" + Символы.ПС + СтрокаСериализатора);
   
   Чтение = Новый ЧтениеXML;
   Чтение.УстановитьСтроку(СтрокаФабрики);
   Набор = СериализаторXDTO.ПрочитатьXML(Чтение);
   
   Чтение = Новый ЧтениеXML;
   Чтение.УстановитьСтроку(СтрокаСериализатора);
   Набор = СериализаторXDTO.ПрочитатьXDTO(ФабрикаXDTO.ПрочитатьXML(Чтение));
47 Serginio1
 
22.05.13
12:46
Да сейчас сам проверил на 8.3 все проходит. Видно подправили. Буду знать. было 2 года назад.
48 Serginio1
 
22.05.13
12:48
Фабрика не умеет но тип есть в Xml

Имя=ЧтениеXML.Имя;
 ОбъектXDTO=ФабрикаXDTO.ПрочитатьXML(ЧтениеXML,ФабрикаXDTO.Тип(ЧтениеXML.URIПространстваИмен,Имя));
Закон Брукера: Даже маленькая практика стоит большой теории.