1с post запрос не сохраняет данных. Поиск объекта по полям поиска

1с post запрос не сохраняет данных. Поиск объекта по полям поиска

При разработке процедуры отправки на сайт информации из 1С с версией платформы 8.3.9.2170 столкнулся с проблемой: разработчик сайта предоставил мне возможность записывать нужную информацию только при помощи HTTP запроса методом PUT.

Недолго думая, я набросал простенький код:

Соединение = Новый HTTPСоединение("www.mysite.ru"); Заголовки = Новый Соответствие; Заголовки["Content-Type"] = "application/x-www-form-urlencoded"; Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item=30", Заголовки); Соединение.Записать(Запрос);

По результатам выполнения в соответствующей строке заказа покупателя на сайте должно было проставиться количество поступившего на склад товара.

Однако, как вы уже наверно поняли, ничего не произошло. После того как я убедился, что на сайте ошибок нет (путем отправки аналогичного запроса через плагин к Хрому), я запустил на своем локальном компьютере web-сервер и стал экспериментировать.

Сразу же выяснилась странная вещь: вышеприведенный код генерирует не PUT, а HEAD запрос!

В логах апача я увидел следующее:

127.0.0.1 - - "HEAD /api/order_items/93076?order_item=30 HTTP/1.1"

Я немного удивился (в руководстве ведь было черным по белому написано PUT), но не растерялся - можно ведь вызвать метод напрямую:

Соединение.ВызватьHTTPМетод("PUT",Запрос);

В логах то же самое:

127.0.0.1 - - "HEAD /api/order_items/93076?order_item=30 HTTP/1.1"

"Может быть я что-то не так делаю?" - задал я себе вопрос. Но в интернете и в мануалах не было никаких подсказок. Что ж, метод научного тыка еще никто не отменял. Для начала я попробовал сделать так:

Соединение.ВызватьHTTPМетод("фывфыв",Запрос);

В логах получил:

127.0.0.1 - - "?????? /api/order_items/93076?order_item=30 HTTP/1.1"

Любопытно, значит 1С заменяет конкретно метод PUT (чем же он 1С не угодил?).

После еще нескольких попыток я пришел к варианту:

Соединение.ВызватьHTTPМетод("PUT ",Запрос);

В логах получил:

127.0.0.1 - - "PUT /api/order_items/93076?order_item=30 HTTP/1.1"

И уже этот вариант отработал на сайте и все остались довольны.

Подсказал более корректное решение проблемы: необходимо задать тело запроса, любое, даже пустое. Например, сработает такой вариант:

Соединение = Новый HTTPСоединение("www.mysite.ru"); Заголовки = Новый Соответствие; Заголовки["Content-Type"] = "application/x-www-form-urlencoded"; Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item=30", Заголовки); Запрос.УстановитьТелоИзСтроки("", КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); Соединение.Записать(Запрос);

И уже совсем правильно, наверное, передавать в теле запроса сами значения параметров.

Вывод следующий: PUT запрос без тела платформа 1С считает ошибочным и заменяет метод на HEAD.

Любопытно что POST запрос без тела 1С никак не отслеживает и не превращает в GET, проверял ради спортивного интереса.

Как сказал бы всем известный Вовочка из знаменитого анекдота: "Где логика?".

Надеюсь кому-то моя публикация сбережет несколько часов жизни в поисках ответа. =)))

При разработке процедуры отправки на сайт информации из 1С с версией платформы 8.3.9.2170 столкнулся с проблемой: разработчик сайта предоставил мне возможность записывать нужную информацию только при помощи HTTP запроса методом PUT.

Недолго думая, я набросал простенький код:

Соединение = Новый HTTPСоединение("www.mysite.ru"); Заголовки = Новый Соответствие; Заголовки["Content-Type"] = "application/x-www-form-urlencoded"; Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item=30", Заголовки); Соединение.Записать(Запрос);

По результатам выполнения в соответствующей строке заказа покупателя на сайте должно было проставиться количество поступившего на склад товара.

Однако, как вы уже наверно поняли, ничего не произошло. После того как я убедился, что на сайте ошибок нет (путем отправки аналогичного запроса через плагин к Хрому), я запустил на своем локальном компьютере web-сервер и стал экспериментировать.

Сразу же выяснилась странная вещь: вышеприведенный код генерирует не PUT, а HEAD запрос!

В логах апача я увидел следующее:

127.0.0.1 - - "HEAD /api/order_items/93076?order_item=30 HTTP/1.1"

Я немного удивился (в руководстве ведь было черным по белому написано PUT), но не растерялся - можно ведь вызвать метод напрямую:

Соединение.ВызватьHTTPМетод("PUT",Запрос);

В логах то же самое:

127.0.0.1 - - "HEAD /api/order_items/93076?order_item=30 HTTP/1.1"

"Может быть я что-то не так делаю?" - задал я себе вопрос. Но в интернете и в мануалах не было никаких подсказок. Что ж, метод научного тыка еще никто не отменял. Для начала я попробовал сделать так:

Соединение.ВызватьHTTPМетод("фывфыв",Запрос);

В логах получил:

127.0.0.1 - - "?????? /api/order_items/93076?order_item=30 HTTP/1.1"

Любопытно, значит 1С заменяет конкретно метод PUT (чем же он 1С не угодил?).

После еще нескольких попыток я пришел к варианту:

Соединение.ВызватьHTTPМетод("PUT ",Запрос);

В логах получил:

127.0.0.1 - - "PUT /api/order_items/93076?order_item=30 HTTP/1.1"

И уже этот вариант отработал на сайте и все остались довольны.

Подсказал более корректное решение проблемы: необходимо задать тело запроса, любое, даже пустое. Например, сработает такой вариант:

Соединение = Новый HTTPСоединение("www.mysite.ru"); Заголовки = Новый Соответствие; Заголовки["Content-Type"] = "application/x-www-form-urlencoded"; Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item=30", Заголовки); Запрос.УстановитьТелоИзСтроки("", КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); Соединение.Записать(Запрос);

И уже совсем правильно, наверное, передавать в теле запроса сами значения параметров.

Вывод следующий: PUT запрос без тела платформа 1С считает ошибочным и заменяет метод на HEAD.

Любопытно что POST запрос без тела 1С никак не отслеживает и не превращает в GET, проверял ради спортивного интереса.

Как сказал бы всем известный Вовочка из знаменитого анекдота: "Где логика?".

Надеюсь кому-то моя публикация сбережет несколько часов жизни в поисках ответа. =)))

Возникла задача о передаче данных между 1С (разработка и настройка была отдана на аутсорсинг), которую планируется использовать как основную систему электронного документооборота (ЭДО) и B2B системой (внутренняя разработка), которая написана на PHP (Symfony) и выполняет функции первичного ввода информации в компании.

У меня уже был опыт интеграции B2B с другой B2B. Суть заключалась к передаче JSONа при помощи cURL. Затем возникла задача интеграции системы «Borlas», основанная на Oracle, где также был применен данный подход. На стороне Oracle, правда, использовался свой пакет - аналог cURL в PHP (если будет интересно, могу описать в новой статье).

Как я выяснил, 1С 8.2 тоже умеет посылать GET и POST запросы. Предположил, что если уже все настроено и работает с другими системами, значит, и тут должно сработать. JSON отвергли разработчики 1С, сказав, что формат неподходящий и они признают только XML. Комментарии о том, что это нам даст минимум в размере при передаче данных, а данных действительно получалось очень много, были отвергнуты. В итоге приступили в подготовке 2 систем на основе XML.

Cо своей стороны я написал приемщик запросов из 1С и возврат результатов. Функция по приему переменной в POST, в которой 1Сники должны были подставлять XML.
Формат примерно следующий:

123ABC456 //ключ авторизации get_last_orders //операцию что хотят выполнить 4000//лимит записей что хотят отобрать

Обработчик, который возвращает уже отобранные по условиям записи и формирует XML вида:

1 OPS 4853352 01.01.2013 1 Загружено из b2b СНИЛС 999999999 ФИО клиента МИХАЙЛОВ МИХАИЛ ЕВГЕНЬЕВИЧ Дата заявления 01.01.2013 ...

Данные могут быть переданные только через HTTPS соединение.

На первый взгляд, кажется, что все просто, но в процессе возникло несколько проблем:
1) аутсорсеры сообщили, что малознакомы с запросами такого рода, и попытались предложить старую проверенную схему:
1. импорт файла из B2B,
2. Загрузка в 1С,
3. Экспорт файла с указанием, что смогли обработать, что нет из 1С,
4. Импорт в Б2Б,
5. и с самого начала…
Схему отвергли, так как нужно быстро, и без участия человека и всяких «кнопочек».

Тогда попросили пример кода. В интернете я «нагуглил» следующий пример:

Сервер = "test.com"; Порт = "443"; Попытка НТТР = Новый HTTPСоединение(Сервер, Порт, Истина); Иначе НТТР = Новый HTTPСоединение(Сервер, Порт); КонецЕсли; АдресСкрипта = "/gateway/GetData1C/"; Попытка НТТР.ОтправитьДляОбработки(ИмяФайлаОтправки, АдресСкрипта, ИмяФайлаОтвета, ЗаголовокHTTP); Исключение Сообщить("Неудачная попытка соединения: " + ОписаниеОшибки()); Иначе ЗаписьЖурналаРегистрации("HTTPСоединение", УровеньЖурналаРегистрации.Ошибка, "Неудачная попытка соединения: " + ОписаниеОшибки()); КонецЕсли Возврат; КонецПопытки;

На сервер стали приходить данные, но пустые, то есть GET и POST были пустые. Я добавил запись что приходит в логи и успешно забыл об этом. Спустя 4 месяца мне была поставлена срочная задача - довести интеграцию до результата (так как прошло много времени, разработчики 1С работают, работают, но в ответ ничего не приходит). Мне поставили 1С и я начал «ковыряться».

Первое - решил поставить Fiddler , чтобы понять что происходит. Заметил, что соединение идет по HTTP, а затем сервер редиректит на HTTPS. Предположил, что по этой причине данные получаются пустыми. Попробовал в Chrome воспроизвести, и получил подтверждение, что данные в POST запросе теряются при редиректе.

Так как разрешать работу по HTTP нельзя, начал изучать почему, ведь указано, что:

НТТР = Новый HTTPСоединение(Сервер, Порт, Истина); Параметр «Истина» означает что использовать HTTPS, и тут дошло что срабатывает НТТР = Новый HTTPСоединение(Сервер, Порт);

В итоге это «Иначе» было выкинуто, и получил ошибку, что некорректный сертификат. Сертификат был само подписной. Разработка интеграции велась на внутренних серверах, где официально купленного сертификата от «Thawte SSL CA» в отличии от PROD сервера. Импорт сертификата во все возможные хранилища не привел к результату.

Поиск по ресурсам привел к тому, что все сертификаты корневые у 1С свои, и на основе них она уже проверяет остальные. Они лежат в тестовом виде в файле «cacert.pem», который расположен в папке «bin», где стоит 1С. Импорт, не так прост, как оказалось.

Для начала надо экспортировать нужный нам сертификат в файл (он у меня уже был в личном хранилище). Запустив «certmgr.msc», найдя сертификат, делаем его экспорт в файл *.cer.

C:\OpenSSL-Win64\bin>openssl x509 -inform der -in С:\fiddler.cer -out С:\fiddler.pem -text -fingerprint -md5 WARNING: can"t open config file: /usr/local/ssl/openssl.cnf MD5 Fingerprint=13:BF:73:43:BB:69:19:BA:22:5D:C7:2E:44:85:91:7F
MD5 сохраняем, он нам понадобится.
Далее открываем файл «cacert.pem».
Спускаемся в самый низ и добавляем сперва MD5, а потом все содержимое, что получилось в файле «fiddler.pem».
Сохраняем файл.
Перезапускаем 1С (возможно и не надо, но у меня не заработало, поэтому я перезапустил все.

Исходный файл в 1С был приведен в такой вид:

Процедура ПослатьЗапросНажатие(Элемент) Соединение = ПолучитьHTTPСоединение(); Если Соединение = Неопределено Тогда Сообщить("Не удалось подключиться к серверу, указанному в настройке обмена! Обработка прервана!"); Иначе Источник = АдресФайла; КонецЕсли; ИмяФайла = ФайлРезультат; ИмяПостФайла = ПостФайл; ФайлОтправки = Новый Файл(ИмяПостФайла); РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер()); Заголовки = Новый Соответствие(); Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded"); Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки); Попытка Соединение.ОтправитьДляОбработки(ИмяПостФайла, Источник, ИмяФайла, Заголовки); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки КонецПроцедуры Функция ПолучитьHTTPСоединение() Экспорт Попытка Соединение = Новый HTTPСоединение(HTTPСервер,"443",Истина); Исключение Сообщить(ОписаниеОшибки()); Соединение = Неопределено; КонецПопытки; Возврат Соединение; КонецФункции Процедура ПриОткрытии() HTTPСервер = "test.com"; АдресФайла = "/gateway/GetData1C"; ПостФайл = "C:\POST_1C\post.txt"; ФайлРезультат = "C:\POST_1C\result.xml"; КонецПроцедуры

После нажатия на кнопку, пошел запрос по HTTPS и на выходе был получен корректный XML.

Искал, как работает 1С по HTTPS, достаточно много материала, но вот как работать по само подписному сертификату не нашел.

Печать (Ctrl+P)

Вторая часть можно посмотреть

Общие сведения

В версии платформы 8.3.5.1068 , опубликованной в сентябре 2015 появился механизм интеграции 1С с внешними программами через технологию REST интерфейс . В качестве протокола доступа платформа использует протокол OData . Это открытый веб-протокол для запроса и обновления данных. Он позволяет оперировать данными, используя в качестве запросов HTTP-команды. Получать ответы в версии 8.3.5.1068 можно было только в формате Atom/XML . Однако, начиная с релиза 8.3.8.1652 в августе 2017 г. появился второй вариант получения данных в формате JSON(англ. JavaScript Object Notation) . По сравнению с XML он легко читается людьми занимает меньше места. Кроме этого все браузеры имеют встроенные средства для работы с JSON.

Работу с протоколом OData на платформе 1С: предприятие можно посмотреть в книге 1С: Руководства разработчика в главе 17 Механизмы интернет-сервисов , параграф 17.2.1 Cтандартный интерфейс OData. Можно также посмотреть примеры расширения поддержки протокола OData ,

Преимущество использования REST интерфейс . заключает в том, что для получения доступа к данным системы из внешнего приложения не требуется модификации кода прикладного решения (например, если прикладное решение стоит на поддержке). Для получения такого доступа необходимо особым образом опубликовать приложение на веб-сервере и указать, какие объекты конфигурации будут использоваться таким образом. После этого сторонние системы могут обращаться к вашему приложению с помощью HTTP запросов.

Публикация стандартного интерфейса OData выполняется с помощью диалога публикации на веб-сервере (Администрирование – Публикация на веб- сервере) и описано в книге 1С:Предприятие 8.3. “Руководство администратора”.
Важно! Для того чтобы объекты конфигурации стали доступны через стандартный интерфейс OData, необходимо разрешить это с помощью метода глобального контекста УстановитьСоставСтандартногоИнтерфейсаOData() .
Механизм установки состава объектов, доступных с помощью стандартного интерфейса OData, можно выполнить в виде внешней обработки. Для этого не требуется модифицировать прикладное решение.

Для взаимодействия с внешним REST- веб-сервер из 1С:Предприятия используется имеющиеся в платформе средства работы с HTTP: объекты HTTPСоединение, HTTPЗапрос и HTTPОтвет.

В этой цикле статьей я буду показывать примеры типовых операций, использующих соответствующий HTTP-метод;

  • Получение данных – метод GET ;
  • Создание объекта – метод POST ;
  • Обновление данных: метод PATCH – в этом случае можно указывать только те свойств, которые необходимо обновить; метод PUT – в этом случае необходимо указывать все свойства сущности;
  • Удаление данных – метод DELETE .

1. Примеры получения данных. HTTP-метод GET

В качестве сервера будет выступать опубликованная на веб-сервере БД с именем WebBuh (Демо-база “Бухгалтерия Предприятия 3.0”). В качестве формата обмена данных я буду использовать формат JSON. Подробнее о работе с JSON написано в документации, доступной . Для получения данных из сервера HTTP-методом GET требуется создать объект ЧтениеJSON для последовательного чтения JSON-данных из файла или строки. Для организации последовательной записи объектов и текстов на сервере HTTP-методом POST PATCH PUT требуется создать объект ЗаписьJSON. Отметим, для метода DELETE не требуется JSON.

В качестве иллюстрации потокового чтения и записи JSON при обращении к REST интерфейсу я буду вызывать следующую пользовательскую функцию общего назначения ВызватьHTTPМетодНаСервере :

&НаСервере // <Описание функции> // // Параметры: // - Строка, содержащая имя HTTP-метода для запроса ("POST"."PATCH", "PUT" ,"GET","DELETE" // - объект HTTPСоединение // <АдресРесурса> - Строка http-ресурса, к которому будет отправлен HTTP запрос. // <ОтправляемыеДанные> - Структура или соответствие, содержащие данные, отправляемые на указанный адрес для обработки // на сервер с использованием указанного HTTP-метода "POST" или "PATCH" или "PUT" // Возвращаемое значение: // Структура ответа сервера в зависимости от HTTPМетод // Функция ВызватьHTTPМетодНаСервере(HTTPМетод,HTTPСоединение,АдресРесурса,ОтправляемыеДанные = Неопределено ) // Создание HTTPЗапрос Заголовки = Новый Соответствие (); Заголовки.Вставить ("Content-Type", "application/json"); ЗапросHTTP = Новый HTTPЗапрос (АдресРесурса, Заголовки ); // ЗаписьJson толка для создания и обновление данных Если HTTPМетод = "POST" или HTTPМетод ="PATCH" или HTTPМетод ="PUT" Тогда ЗаписьJSON = Новый ЗаписьJSON ; ПараметрыJSON = Новый ПараметрыЗаписиJSON (ПереносСтрокJSON.Авто,"",Истина ); ЗаписьJSON.УстановитьСтроку (ПараметрыJSON ); ЗаписатьJSON(ЗаписьJSON , ОтправляемыеДанные ); // ОтправляемыеДанные обязательны в этом случае СтрокаДляТела = ЗаписьJSON.Закрыть (); ЗапросHTTP.УстановитьТелоИзСтроки (СтрокаДляТела ,КодировкаТекста.UTF8 , ИспользованиеByteOrderMark.НеИспользовать ); КонецЕсли; // Вызов Метода HTTPСоединение ОтветHTTP = HTTPСоединение.ВызватьHTTPМетод(HTTPМетод, ЗапросHTTP) ; СтруктураОтвета = Новый Структура ; СтруктураОтвета .Вставить ("КодСостояния ", ОтветHTTP.КодСостояния ); // ЧтениеJSON только для метода GET Если HTTPМетод= "GET" Тогда Попытка ЧтениеJSON = Новый ЧтениеJSON ; ОтветСервера = ОтветHTTP.ПолучитьТелоКакСтроку ("UTF-8"); ЧтениеJSON.УстановитьСтроку(ОтветСервера) ; Соответствие = ПрочитатьJSON(ЧтениеJSON ,Истина ); СтруктураОтвета.Вставить("ОтветСервера ", Соответствие ) ; СтруктураОтвета .Вставить ("ОтветСервераНеРасшифрованный ", ОтветСервера ); Исключение Сообщить(ОписаниеОшибки()) ; Возврат Неопределено; КонецПопытки; Конецесли ; Возврат СтруктураОтвета ; КонецФункции // ВызватьHTTPМетодНаСервере()

Для получения от сервера в формате JSON при обращении к REST интерфейсу прикладного решения нужно в адресе ресурса указать $format=json. Либо указать MIME тип “application/json” в заголовке:

Заголовки = Новый Соответствие (); Заголовки.Вставить("Content-Type", "application/json") ; АдресРесурса ="WebBuh /odata/standard.odata/?$format=json " ЗапросHTTP = Новый HTTPЗапрос(АдресРесурса, Заголовки) ;

Особенность глобального контекста ПрочитатьJSON(ЧтениеJSON, Истина )

  • Если значение второго параметра установлено Истина , чтение объекта JSON будет выполнено в Соответствие .Если установлено Ложь , объекты будут считываться в объект типа Структура .
  • При десериализации объектов JSON в структуру необходимо помнить о требованиях к ключам структуры. Если при десериализации объекта будет найдено имя свойства, недопустимое для ключа структуры, то будет вызвано исключение.

1. 1 Настройка параметров HTTP соединения

Для организации клиентской части взаимодействия с внешним REST- веб-сервер, я создал “с нуля” конфигурацию клиента на базе БСП. На этой конфигурации я создал справочник настройки параметров подключения (см Рис 1)

Рис 1 Справочник настройки параметров HTTP соединения к внешней ИБ через rest интерфейс

После нажатия кнопки Проверить ответ сервера, вызывается процедура, по которой клиент попытается получать ответ сервера. Программный код процедуры написан ниже:

&НаКлиенте Процедура ПроверитьПодключение(Команда) Адрес = Объект.АдресСервера ; Пользователь = Объект.Пользователь ; Пароль = Объект.Пароль; ИмяБазы = Объект.Наименование ; Порт = ?(Объект.Порт <> 0,Объект.Порт,80) ; HTTPСоединение = Новый HTTPСоединение(Адрес,Порт,Пользователь, Пароль) ; АдресРесурса = ИмяБазы + "/odata/standard.odata/$metadata "; //Вызов пользовательской функции СтруктураОтвета = ВызватьHTTPМетодНаСервере ("GET" ,HTTPСоединение,АдресРесурса ) ; Если СтруктураОтвета <> Неопределено Тогда ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Код состояния "+СтруктураОтвета.КодСостояния) ; Конецесли; КонецПроцедуры

Цель этой процедуры – Это проверка работы сервиса и правильно ли пользователь ввел параметры соединения. Для этого достаточно выполнить GET-запрос:
HTTPСоединение.ВызватьHTTPМетод(“GET” , ЗапросHTTP) ;
с использованием адреса ресурса:
АдресРесурса = ИмяБазы + /odata/standard.odata/ “;
Проверить работы сервиса можно также в браузере с использованием
URL
http://host/WebBuh/odata/standard.odata. В результате такого запроса получается только список сущностей. Для получения полного описания стандартного интерфейса OData (список доступных сущностей, их атрибутов и функций в виде XML-
документа.) необходимо выполнить GET-запрос с использованием параметра $metadata. URL http://host/WebBuh/odata/standard.odata/$metadata. Подробное описание документа можно получить по адресу http://www.odata.org/documentation/ (на английском языке).
Получать ответы можно в формате Atom/XML или JSON . Коды статусов ответа по протоколу HTTP можно посмотреть Ответы в диапазонах:

  • 100-199 – информационные ответы, показывающие, что запрос клиента принят и обрабатывается.
  • 200-299 – означают, что запрос клиента обработан успешно.
  • 300-399 означает, что запрос не выполнен и клиенту нужно предпринять некоторые действия для удовлетворения запроса.
  • 400-499 – информирует об ошибках на стороне клиентского приложения. Эти коды могут также означать, что от клиента требуется дополнительная информация.
  • 500-599 – информирует об ошибке на стороне сервера, показывают, что сервер столкнулся с ошибкой и, вероятно, не сможет выполнить запрос клиента.

1.2 Поиск объекта по идентификатору

Следующая функция предназначена для поиска справочника или документа по уникальному идентификатора на сервере. Если объект найден, то функция возвращает строковое значение идентификатора (Ref_Key) , иначе возвращает неопределено. В функцию передаются следующие параметры:

  • HTTPСоединение – Объект типа HTTPСоединение
  • ИмяПубликации – Имя опубликованной базы базы данных сервера
  • Элемент – идентификатор сущности объекта, например, Catalog_Организации или Document_- справочник Организации.
  • Идентификатор – Идентификатор объекта, который нужно искать на сервере, например, Организация.УникальныйИдентификатор()
&НаСервере Функция ПоискОбъектПоGUID (HTTPСоединение,ИмяПубликации,Элемент,УникальныйИдентификатор ) GUID = Строка(УникальныйИдентификатор ); // преобразуем в строку АдресРесурса = + Элемент+ "(guid""+ GUID+ "")?$format=json " ; СтруктураОтвета = В ызватьHTTPМетодНаСервере ("GET" , HTTPСоединение,АдресРесурса ) ; Если СтруктураОтвета .КодСостояния >= 400 Тогда //ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Элемент+ " Ошибка "+СтруктураОтвета.КодСостояния+ //ОбщегоНазначенияКлиентСервер.СообщитьПользователю(СтруктураОтвета.ОтветСервераНеРасшифрованный); Возврат неопределено ; КонецЕсли ; Соответствие = СтруктураОтвета. ОтветСервер а; Массив = Соответствие["value"] ; Если Массив = Неопределено Тогда Возврат Соответствие ["Ref_Key"] Иначе Возврат Массив ["Ref_Key"]; КонецЕсли; КонецФункции

Параметр АдресРесурса используется для обращения к REST-сервису. Для проверки работы сервиса можно указать ресурс в браузере таким образом

http://{АдресВебСервера}/{ИмяПубликации}/odata/standard.odata/{Элемент}?{Параметры} ,где

  • АдресВебСервера – Адрес веб-сервера, на котором опубликован сервис, например Localhost
  • ИмяПубликации – имя информационной базы указанное при публикации решения
  • /odata/standard.odata/ – Признак обращения к стандартному интерфейсу OData
  • Элемент – идентификатор ресурса или предопределенные ресурсы. Например, Catalog_Контрагент(guid’value’).
  • Параметры – параметры ресурса. Используются, например, для отбора, в принятом для HTTP-запросов: ?ключ=значение&ключ2=значение2

1.3 Поиск объекта по полям поиска

Следующая пользовательская функция предназначена для поиска объекта по полям поиска в том случае, когда объект по идентификационному номеру. Функция возражает строку Ref_Key – идентификационный номер.

&НаСервере Функция П оискОбъектПоПолямПоиска(HTTPСоединение,ИмяПубликации, Элемент,ПоляПоиска) Условие = "" ; Для Каждого КлючЗначение из ПоляПоиска Цикл Условие = Условие + КлючЗначение.Ключ + " eq "" + КлючЗначение.Значение + "" and "; КонецЦикла; ТекстЗапроса = Лев(Условие, СтрДлина(Условие)-5) ; // удаляем последние 5 символов АдресРесурса = ИмяПубликации+ "/odata/standard.odata/" +Элемент+ "?$filter=" + ТекстЗапроса + "&$format=json&$select=Ref_Key " ; //Вызов моей пользовательской функции СтруктураОтвета = ВызватьHTTPМетодНаСервере("GET " ,HTTPСоединение,АдресРесурса); Если СтруктураОтвета .КодСостояния >= 400 Тогда //ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Элемент+ " Ошибка "+СтруктураОтвета.КодСостояния); //ОбщегоНазначенияКлиентСервер.СообщитьПользователю(СтруктураОтвета.ОтветСервераНеРасшифрованный); Возврат неопределено; КонецЕсли; Соответствие = СтруктураОтвета. ОтветСервер а; Массив = Соответствие["value" ] ; Если Массив = Неопределено Тогда Возврат Соответствие ["Ref_Key" ] Иначе Возврат Массив ["Ref_Key" ]; КонецЕсли; КонецФункции

Как видно из тела процедуры П оискОбъектПоПолямПоиска , отбор начинается с ключевого слова $filter в адресе ресурса. Формальный параметр ПоляПоиска – это соответствие, которое содержит наименования и значения реквизитов.

Отметим, что наименование реквизитов порой не очевидно. Необходимо запомнить, что для справочников:

  • Code – код,
  • Description – Наименование
  • DeletionMark – пометка удаления,
  • IsFolder – признак группы,
  • Parent_Key – родитель.
  • Если реквизит ссылочного типа, к его имени следует добавить суффикс _Key, например Контрагент_Key.

Для документов:

  • Number – номер документа,
  • Date – дата документа.

Логические операции отбора

  • eq - Равно; /Catalog_Города?$filter=Наименование eq ‘Главный’;
  • ne - Не равно; /Catalog_Города?$filter=Наименование ne ‘Пермь’;
  • gt - Больше; /Catalog_Товары?$filter= Цена gt 10;
  • ge - Больше или равно; /Catalog_Товары?$filter=Цена ge 10;
  • lt - Меньше; /Catalog_Товары?$filter=Цена lt 10;
  • le - Меньше или равно; /Catalog_Товары?$filter=Цена le 10;
  • or - Логическое ИЛИ; /Catalog_ Товары ?$filter= Цена lt 10 or Цена gt 100;
  • and - Логическое И; / Catalog _Товары?$ filter =Цена g t 10 and Цена l t 100;
  • not - Отрицание; /Catalog_ Товары ?$filter=not (Цена eq 10);

Отметим, также, что значение фактического параметра Элемент (или сущность)) , который я передаю на функцию формируется по следующему правилу:

ПрефиксИмени_ИмяОбъектаКонфигурации_СуффиксИмени .

С помощью стандартного интерфейса OData можно получить доступ к следующим объектам (ПрефиксИмени ):

  • Справочник - Catalog;
  • Документ - Document;
  • Журнал документов - DocumentJournal;
  • Константа - Constant;
  • План обмена - ExchangePlan;
  • План счетов - ChartOfAccounts
  • План видов расчета - ChartOfCalculationTypes;
  • План видов характеристик - ChartOfCharacteristicTypes;
  • Регистр сведений - InformationRegister;
  • Регистр накопления - AccumulationRegister;
  • Регистр расчета - CalculationRegister;
  • Регистр бухгалтерии - AccountingRegister;
  • Бизнес-процесс - BusinessProcess;
  • Задача - Task.

ИмяОбъектаКонфигурации - свойство «Имя» объекта конфигурации так, как оно задано в конфигураторе.

СуффиксИмени - нужен для уточнения имени ресурса, необязателен, может принимать следующие значения:

  • Имя табличной части объекта;
  • Имя виртуальной таблицы объекта;
  • RowType - строка табличной части объекта;
  • RecordType - отдельная запись регистра.

Параметры обращения к ресурсам

После формирования имени ресурса нужно определить параметры обращения к ресурсу, например, ?$filter=Значение &$format =json&$select= Ref_Key ,

  • $filter - отбор при получении данных
  • $format - указывает формат возвращаемых данных,
  • $select - перечисление свойств сущности, которые попадут в результат запроса;
  • $metadata - возвращает описание стандартного интерфейса OData (используется без указания суффикса имени, пример на одном из изображений выше);
  • $top - ограничение количества возвращаемых записей;
  • $skip - убирает из результата запроса указанное количество записей;
  • $count - возвращает количество записей в выборке запроса;
  • $inlinecount=allpage(=none) - добавляет в результат запроса информацию о количестве записей
  • $orderby=<Реквизит1> asc, <Реквизит2> desc - сортировка результата запроса
  • alloweOnly - только разрешенные (используется без знака «$»).

1.4 Получить массив записей регистра сведений

Посмотрим пример получения массив записей регистра сведения ФИОФизическихЛиц, например историю изменения ФИО физического лица

ИмяПубликации =" WebBuh"; Элемент = "InformationRegister_ФИОФизическихЛиц"; Период = Неопределено ; ДанныеСсылочногоТипа = Новый Структура (); ДанныеСсылочногоТипа .Вставить ("ФизическоеЛицо",ФизическоеЛицо_Key); ДанныеНЕСылочногоТипа = Новый Структура (); ДанныеНЕСылочногоТипа .Вставить ("ФизическоеЛицо_Type", "StandardODATA.Catalog_ФизическиеЛица") Массив = ПолучитьНаборЗаписиРегистраСведений (HTTPСоединение ,ИмяПубликации ,Элемент , Период ,ИзмеренияСсылочногоТипа , ИзмеренияНЕСылочногоТипа )

Тело функции ПолучитьНаборЗаписиРегистраСведений, которая вызывается в этом примере показано ниже

&НаСервере Функция ПолучитьНаборЗаписиРегистраСведений (HTTPСоединение ,ИмяПубликации ,Элемент , Период =Неопределено ,ИзмеренияСсылочногоТипа = Неопределено , ИзмеренияНЕСылочногоТипа = Неопределено ) ТекстЗапроса ="" ; Если Период <> Неопределено Тогда ФорматированныйПериод = Формат (Период ,"ДФ=yyyy-MM-ddTHH:mm:ss"); ТекстЗапроса = "Period = datetime""+ ФорматированныйПериод + """ ; КонецЕсли; Если ИзмеренияСсылочногоТипа <> Неопределено Тогда Для Каждого КлючЗначени е из ИзмеренияСсылочногоТипа Цикл Запитая = ? (ЗначениеЗаполнено (ТекстЗапроса ), "," ,""); ТекстЗапроса = ТекстЗапроса + Запитая + КлючЗначение.Ключ + "=guid(""+ КлючЗначение.Значение + "")"; КонецЦикла; КонецЕсли; Если ИзмеренияНЕСылочногоТипа <> Неопределено Тогда Для Каждого КлючЗначение из ИзмеренияНЕСылочногоТипа Цикл Запитая = ? (ЗначениеЗаполнено (ТекстЗапроса ), "," ,""); ТекстЗапроса = ТекстЗапроса + Запитая + КлючЗначение.Ключ + "=" + КлючЗначение.Значение ; КонецЦикла; КонецЕсли; АдресРесурса= ИмяПубликации + "/odata/standard.odata/" + Элемент + "("+ ТекстЗапроса + + ") ?$format=json "; //Вызов моей пользовательской функции СтруктураОтвета = ВызватьHTTPМетодНаСервере ("GET",HTTPСоединение ,АдресРесурса ); Если СтруктураОтвета .КодСостояния >= 400 Тогда //ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Элемент+ " Ошибка "+СтруктураОтвета.КодСостояния); //ОбщегоНазначенияКлиентСервер.СообщитьПользователю(СтруктураОтвета.ОтветСервераНеРасшифрованный); Возврат неопределено; КонецЕсли; Соответствие = 0