Коллеги. Раньше не приходилось мне сталкиваться с веб-сервисами.

Подскажите правильный путь в построении данных. Нужно получить массив или готовый xml

Создал пакет xdto, веб-сервис и опубликовал его, создал WSСсылку.

В веб-сервисе создал операцию с Типом "array". Добавил ему два параметра: входящий (дата) и выходящий (array)
В операции написал функцию которая делает срез последних свободных вакансий на указанную дату и возвращает массив данных.

Далее сделал обработку где пытаюсь получить данный массив по указанной дате. Однако получаю лишь "неопределено"

Код обработки:

```1c
    Определение = Новый WSОпределения("http://1c_web/Copy_ZUP31/ws/RequestVacancy.1cws?wsdl", "Пользователь", "Пароль");
    Сервис = Новый WSПрокси(Определение, "http://it_y.he.ru/request", "RequestVacancy", "RequestVacancySoap",,,,, Ложь);
    Сервис.Пользователь = "Пользователь";
    Сервис.Пароль = "Пароль";
    Массив = Новый Массив(200, 6);
    Результат = Сервис.Вакансии(ДатаСреза, Массив);
    Если Результат = Неопределено Тогда
    Сообщить("Неопределено");
    Возврат;
    КонецЕсли;
```

Код операции веб-сервиса рабочий, но на всякий случай привожу и его:

```1c
    Функция Вакансии(ДатаСреза, Штат)
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | ШтатноеРасписание.КоличествоСтавок КАК КоличествоСтавокПоПлану,
    | ЗанятостьПозицийШтатногоРасписанияСрезПоследних.КоличествоСтавок КАК КоличествоСтавок,
    | ЗанятостьПозицийШтатногоРасписанияСрезПоследних.Сотрудник.Код КАК ТабельныйНомер,
    | ЗанятостьПозицийШтатногоРасписанияСрезПоследних.ВидЗанятостиПозиции КАК ВидЗанятостиПозиции,
    | ШтатноеРасписание.Наименование КАК ДолжностьПолная,
    | ШтатноеРасписание.Подразделение КАК Подразделение
    |ИЗ
    | РегистрСведений.ЗанятостьПозицийШтатногоРасписания.СрезПоследних(&ДатаСреза, ) КАК ЗанятостьПозицийШтатногоРасписанияСрезПоследних
    | ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ШтатноеРасписание КАК ШтатноеРасписание
    | ПО ЗанятостьПозицийШтатногоРасписанияСрезПоследних.ПозицияШтатногоРасписания = ШтатноеРасписание.Ссылка
    |ГДЕ
    | (ШтатноеРасписание.Подразделение.Код = "001110000"
    | ИЛИ ШтатноеРасписание.Подразделение.Родитель.Код = "001110000"
    | ИЛИ ШтатноеРасписание.Подразделение.Родитель.Родитель.Код = "001110000")
    | И ЗанятостьПозицийШтатногоРасписанияСрезПоследних.ВидЗанятостиПозиции <> &ВидЗанятостиПозиции
    |
    |УПОРЯДОЧИТЬ ПО
    | Подразделение,
    | ДолжностьПолная,
    | ТабельныйНомер";
    Запрос.УстановитьПараметр("ДатаСреза", КонецДня(ДатаСреза));
    Запрос.УстановитьПараметр("ВидЗанятостиПозиции", Перечисления.ВидыЗанятостиПозицийШтатногоРасписания.Свободна);
    РезультатЗапроса = Запрос.Выполнить();

    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    Штат = Новый Массив(ВыборкаДетальныеЗаписи.Количество(),6);
    Счетчик=1;
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    Штат[Счетчик][0]=ВыборкаДетальныеЗаписи.ВидЗанятостиПозиции;
    Штат[Счетчик][1]=ВыборкаДетальныеЗаписи.ТабельныйНомер;
    Штат[Счетчик][2]=ВыборкаДетальныеЗаписи.Подразделение;
    Штат[Счетчик][3]=ВыборкаДетальныеЗаписи.КоличествоСтавокПоПлану;
    Штат[Счетчик][4]=ВыборкаДетальныеЗаписи.ДолжностьПолная;
    Штат[Счетчик][5]=ВыборкаДетальныеЗаписи.КоличествоСтавок;
    Счетчик=Счетчик+1;
    КонецЦикла;
    Возврат Штат;

    КонецФункции
```

Пакет XDTO нужно сначала заполнить, нужно в веб-сервисе разделить параметры в 2 разных операции? Информации по веб-сервисам хватает, но везде абсолютно по-разному написано, и не все из них работают.
---
А тип значенияКоллеги у мну обычно фтыкают туда хранилище значений, создают новое со степенью сжатия по максимуму - и, опа, все летает!
---
Получилось таки. Возможно решение не самое элегантное. Но для первого раза, хотя бы получаю результат и уже доволен. Теперь уже буду дорабатывать и приводить в более адекватный вид.

Поменял тип возвращаемого значения у Операции веб-сервиса на ValueStorage и поменял в коде Операции:

```1c
    Функция Вакансии(ДатаСреза, Штат)
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | ШтатноеРасписание.КоличествоСтавок КАК КоличествоСтавокПоПлану,
    | ЗанятостьПозицийШтатногоРасписанияСрезПоследних.КоличествоСтавок КАК КоличествоСтавок,
    | ЗанятостьПозицийШтатногоРасписанияСрезПоследних.Сотрудник.Код КАК ТабельныйНомер,
    | ЗанятостьПозицийШтатногоРасписанияСрезПоследних.ВидЗанятостиПозиции КАК ВидЗанятостиПозиции,
    | ШтатноеРасписание.Наименование КАК ДолжностьПолная,
    | ШтатноеРасписание.Подразделение КАК Подразделение
    |ИЗ
    | РегистрСведений.ЗанятостьПозицийШтатногоРасписания.СрезПоследних(&ДатаСреза, ) КАК ЗанятостьПозицийШтатногоРасписанияСрезПоследних
    | ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ШтатноеРасписание КАК ШтатноеРасписание
    | ПО ЗанятостьПозицийШтатногоРасписанияСрезПоследних.ПозицияШтатногоРасписания = ШтатноеРасписание.Ссылка
    |ГДЕ
    | (ШтатноеРасписание.Подразделение.Код = "001110000"
    | ИЛИ ШтатноеРасписание.Подразделение.Родитель.Код = "001110000"
    | ИЛИ ШтатноеРасписание.Подразделение.Родитель.Родитель.Код = "001110000")
    | И ЗанятостьПозицийШтатногоРасписанияСрезПоследних.ВидЗанятостиПозиции <> &ВидЗанятостиПозиции
    |
    |УПОРЯДОЧИТЬ ПО
    | Подразделение,
    | ДолжностьПолная,
    | ТабельныйНомер";
    Запрос.УстановитьПараметр("ДатаСреза", КонецДня(ДатаСреза));
    Запрос.УстановитьПараметр("ВидЗанятостиПозиции", Перечисления.ВидыЗанятостиПозицийШтатногоРасписания.Свободна);
    РезультатЗапроса = Запрос.Выполнить();

    ТаблицаРезультата = РезультатЗапроса.Выгрузить();
    СериализацияТаблицы = Сериализатор.ЗаписатьXDTO(ТаблицаРезультата);

    ЗаписьJSON = Новый ЗаписьJSON;
    ПараметрЗаписи = Новый ПараметрыЗаписиJSON( ,Символы.Таб);
    ЗаписьJSON.ОткрытьФайл("C:\test\test1.json");
    ЗаписьJSON.ЗаписатьНачалоМассива();
    Для Каждого Строка из СериализацияТаблицы.row Цикл
    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[0].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка(Строка.Value[0]));
    ЗаписьJSON.ЗаписатьКонецОбъекта();

    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[1].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка(Строка.Value[1]));
    ЗаписьJSON.ЗаписатьКонецОбъекта();

    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[2].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка.Value[2]);
    ЗаписьJSON.ЗаписатьКонецОбъекта();

    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[3].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка(Строка.Value[3]));
    ЗаписьJSON.ЗаписатьКонецОбъекта();

    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[4].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка.Value[4]);
    ЗаписьJSON.ЗаписатьКонецОбъекта();

    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[5].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка(Строка.Value[5]));
    ЗаписьJSON.ЗаписатьКонецОбъекта();
    КонецЦикла;
    ЗаписьJSON.ЗаписатьКонецМассива();
    //ЗаписьJSON.Закрыть();
    //СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, СериализацияТаблицы.row, НазначениеТипаXML.Явное);

    Хранилище = Новый ХранилищеЗначения(ЗаписьJSON.Закрыть());
    Возврат Хранилище;

    КонецФункции
```

А в коде обработки:

```1c
    Определение = Новый WSОпределения("http://1c_web/Copy_ZUP31/ws/RequestVacancy.1cws?wsdl", "Пользователь", "Пароль");
    Сервис = Новый WSПрокси(Определение, "http://it_y.he.ru/request", "RequestVacancy", "RequestVacancySoap");
    Сервис.Пользователь = "Пользователь";
    Сервис.Пароль = "Пароль";

    Результат = Сервис.Vacancy(ДатаСреза);
    Если Результат = Неопределено Тогда
    Сообщить("Неопределено");
    Возврат;
    КонецЕсли;
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.ОткрытьФайл("C:\test\test1.json");
    Пока ЧтениеJSON.Прочитать() Цикл

    Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоМассива Тогда

    Пока ЧтениеJSON.Прочитать() Цикл

    Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.Строка Тогда

    ИначеЕсли ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоОбъекта Тогда

    Счётчик = 0;
    Пока ЧтениеJSON.Прочитать() Цикл

    Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.ИмяСвойства Тогда
    Продолжить;
    ИначеЕсли ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.Строка Тогда
    Если Счётчик = 0 Тогда
    Строка = ЭтотОбъект.ТЗ.Добавить();
    КонецЕсли;

    Если Счётчик = 0 Тогда
    Строка.КоличествоСтавокПоПлану = ЧтениеJSON.ТекущееЗначение;
    ИначеЕсли Счётчик = 1 Тогда
    Строка.КоличествоСтавок = ЧтениеJSON.ТекущееЗначение;
    ИначеЕсли Счётчик = 2 Тогда
    Строка.ТабельныйНомер = ЧтениеJSON.ТекущееЗначение;
    ИначеЕсли Счётчик = 3 Тогда
    Строка.ВидЗанятостиПозиции = ЧтениеJSON.ТекущееЗначение;
    ИначеЕсли Счётчик = 4 Тогда
    Строка.ДолжностьПолная = ЧтениеJSON.ТекущееЗначение;
    ИначеЕсли Счётчик = 5 Тогда
    Строка.Подразделение = ЧтениеJSON.ТекущееЗначение;
    КонецЕсли;
    Счётчик = Счётчик + 1;

    Если Счётчик = 6 Тогда
    Счётчик = 0;
    КонецЕсли;
    КонецЕсли;

    КонецЦикла;

    КонецЕсли;

    КонецЦикла;

    КонецЕсли;

    КонецЦикла;
    ЧтениеJSON.Закрыть();
```
---
Я бы лучше сериализовал этот массив в JSON и возвратил как строку. Да и от SOAP отказался в пользу HTTP сервисов.
---
Таких вариантов не встречал, но я когда пытался этот массив в файл JSON выгрузить, не получилось. В XML без проблем.
---
Да хоть и в XML, суть то одна. Тип возвращаемого значения все равно то строка. А в чем проблема с выгрузкой JSON?
---
на тот момент он мне выдавал ошибку что я пытался массив в массив запихнуть. (имеется массив должностей а в каждую должность надо было вставить массив сотрудников. А так как задача была на время, я куда быстрее это собрал в xml)
---
да я вижу что массив двумерный. и в голову б никогда не пришло что он не сериализуется. а если заменить его на таблицу значений?
SOAP сервис - это условие задачи? устаревшая же технология. попробуй REST, имхо доже проще будет
---
Нет, какой информации больше нашёл в сети, ту и пробовал реализовать.

Как писал ранее, не сталкивался с веб-сервисами. Только настройка и публикация и не более того.
---
если можно получить массив, получите массив
---
Нельзя просто взять и вернуть массив, нужно возвращать СписокXDTO, сформированный из набора данных.
---
а! ну тогда вас ждет несколько часов (по минимуму) высокого программирования
---
Да упаси хосподь......
---
хотя всегда можно просто взять и собрать xml
---
вот уж чего точно не нужно делать, так это собирать SOAP XML "вручную", если вы не любитель извращений с предподвыподвертом.....
---
ну, это вкус фломастеров
кому фабрика, тому фабрика
---
в XDTO нет ничего сверхъестественного. все довольно просто. тут на инфостарте есть статья в 3х частях, почитайте и поймете это. Единственное что мне не удалось понять - это абстрактный тип
---
меня смущает "в трех частях", сэр

нельзя просто взять и прочитать сразу три части
---
нельзя просто взять и прочитать сразу три части
Почему же нельзя? Это же не трехтомник))
---
если идти в ногу со временем, то это должен быть ролик на 30 секунд
с бодрящим музончиком
---
ага., с долби сурраундом и спецэффектами)
---
получается операцию веб-сервиса доработать и возвращать уже СписокXDTO, правильно понял?
---
```1c
    Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
    МассивСтруктур = Новый Массив;
    МассивСтруктур.Добавить(Значение);
    Возврат Сериализатор.ЗаписатьXDTO(МассивСтруктур);
```

(4) Как видите ничего сложного для мозга нет.
---
именно. Вам уже даже код готовый дали.
---
фабрики хдто - довольно сложная вещь для мозга, не фанатеющего от 1с-кастомизаций
---
Зачем так мучиться? Я всегда выгружал это через массив структур.
---
Интересно. А тип значения у Параметра в веб-сервисе так же array?
---
А тип значенияКоллеги у мну обычно фтыкают туда хранилище значений, создают новое со степенью сжатия по максимуму - и, опа, все летает!
---
Получилось таки. Возможно решение не самое элегантное. Но для первого раза, хотя бы получаю результат и уже доволен. Теперь уже буду дорабатывать и приводить в более адекватный вид.

Поменял тип возвращаемого значения у Операции веб-сервиса на ValueStorage и поменял в коде Операции:

```1c
    Функция Вакансии(ДатаСреза, Штат)
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | ШтатноеРасписание.КоличествоСтавок КАК КоличествоСтавокПоПлану,
    | ЗанятостьПозицийШтатногоРасписанияСрезПоследних.КоличествоСтавок КАК КоличествоСтавок,
    | ЗанятостьПозицийШтатногоРасписанияСрезПоследних.Сотрудник.Код КАК ТабельныйНомер,
    | ЗанятостьПозицийШтатногоРасписанияСрезПоследних.ВидЗанятостиПозиции КАК ВидЗанятостиПозиции,
    | ШтатноеРасписание.Наименование КАК ДолжностьПолная,
    | ШтатноеРасписание.Подразделение КАК Подразделение
    |ИЗ
    | РегистрСведений.ЗанятостьПозицийШтатногоРасписания.СрезПоследних(&ДатаСреза, ) КАК ЗанятостьПозицийШтатногоРасписанияСрезПоследних
    | ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ШтатноеРасписание КАК ШтатноеРасписание
    | ПО ЗанятостьПозицийШтатногоРасписанияСрезПоследних.ПозицияШтатногоРасписания = ШтатноеРасписание.Ссылка
    |ГДЕ
    | (ШтатноеРасписание.Подразделение.Код = "001110000"
    | ИЛИ ШтатноеРасписание.Подразделение.Родитель.Код = "001110000"
    | ИЛИ ШтатноеРасписание.Подразделение.Родитель.Родитель.Код = "001110000")
    | И ЗанятостьПозицийШтатногоРасписанияСрезПоследних.ВидЗанятостиПозиции <> &ВидЗанятостиПозиции
    |
    |УПОРЯДОЧИТЬ ПО
    | Подразделение,
    | ДолжностьПолная,
    | ТабельныйНомер";
    Запрос.УстановитьПараметр("ДатаСреза", КонецДня(ДатаСреза));
    Запрос.УстановитьПараметр("ВидЗанятостиПозиции", Перечисления.ВидыЗанятостиПозицийШтатногоРасписания.Свободна);
    РезультатЗапроса = Запрос.Выполнить();

    ТаблицаРезультата = РезультатЗапроса.Выгрузить();
    СериализацияТаблицы = Сериализатор.ЗаписатьXDTO(ТаблицаРезультата);

    ЗаписьJSON = Новый ЗаписьJSON;
    ПараметрЗаписи = Новый ПараметрыЗаписиJSON( ,Символы.Таб);
    ЗаписьJSON.ОткрытьФайл("C:\test\test1.json");
    ЗаписьJSON.ЗаписатьНачалоМассива();
    Для Каждого Строка из СериализацияТаблицы.row Цикл
    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[0].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка(Строка.Value[0]));
    ЗаписьJSON.ЗаписатьКонецОбъекта();

    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[1].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка(Строка.Value[1]));
    ЗаписьJSON.ЗаписатьКонецОбъекта();

    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[2].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка.Value[2]);
    ЗаписьJSON.ЗаписатьКонецОбъекта();

    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[3].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка(Строка.Value[3]));
    ЗаписьJSON.ЗаписатьКонецОбъекта();

    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[4].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка.Value[4]);
    ЗаписьJSON.ЗаписатьКонецОбъекта();

    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства(СериализацияТаблицы.column[5].Name);
    ЗаписьJSON.ЗаписатьЗначение(Строка(Строка.Value[5]));
    ЗаписьJSON.ЗаписатьКонецОбъекта();
    КонецЦикла;
    ЗаписьJSON.ЗаписатьКонецМассива();
    //ЗаписьJSON.Закрыть();
    //СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, СериализацияТаблицы.row, НазначениеТипаXML.Явное);

    Хранилище = Новый ХранилищеЗначения(ЗаписьJSON.Закрыть());
    Возврат Хранилище;

    КонецФункции
```

А в коде обработки:

```1c
    Определение = Новый WSОпределения("http://1c_web/Copy_ZUP31/ws/RequestVacancy.1cws?wsdl", "Пользователь", "Пароль");
    Сервис = Новый WSПрокси(Определение, "http://it_y.he.ru/request", "RequestVacancy", "RequestVacancySoap");
    Сервис.Пользователь = "Пользователь";
    Сервис.Пароль = "Пароль";

    Результат = Сервис.Vacancy(ДатаСреза);
    Если Результат = Неопределено Тогда
    Сообщить("Неопределено");
    Возврат;
    КонецЕсли;
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.ОткрытьФайл("C:\test\test1.json");
    Пока ЧтениеJSON.Прочитать() Цикл

    Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоМассива Тогда

    Пока ЧтениеJSON.Прочитать() Цикл

    Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.Строка Тогда

    ИначеЕсли ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоОбъекта Тогда

    Счётчик = 0;
    Пока ЧтениеJSON.Прочитать() Цикл

    Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.ИмяСвойства Тогда
    Продолжить;
    ИначеЕсли ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.Строка Тогда
    Если Счётчик = 0 Тогда
    Строка = ЭтотОбъект.ТЗ.Добавить();
    КонецЕсли;

    Если Счётчик = 0 Тогда
    Строка.КоличествоСтавокПоПлану = ЧтениеJSON.ТекущееЗначение;
    ИначеЕсли Счётчик = 1 Тогда
    Строка.КоличествоСтавок = ЧтениеJSON.ТекущееЗначение;
    ИначеЕсли Счётчик = 2 Тогда
    Строка.ТабельныйНомер = ЧтениеJSON.ТекущееЗначение;
    ИначеЕсли Счётчик = 3 Тогда
    Строка.ВидЗанятостиПозиции = ЧтениеJSON.ТекущееЗначение;
    ИначеЕсли Счётчик = 4 Тогда
    Строка.ДолжностьПолная = ЧтениеJSON.ТекущееЗначение;
    ИначеЕсли Счётчик = 5 Тогда
    Строка.Подразделение = ЧтениеJSON.ТекущееЗначение;
    КонецЕсли;
    Счётчик = Счётчик + 1;

    Если Счётчик = 6 Тогда
    Счётчик = 0;
    КонецЕсли;
    КонецЕсли;

    КонецЦикла;

    КонецЕсли;

    КонецЦикла;

    КонецЕсли;

    КонецЦикла;
    ЧтениеJSON.Закрыть();
```
---
Всем спасибо за мудрые советы и замечания