Использование внешних веб-сервисов в 1С на примере загрузки курсов валют

    Знаю, что на хабре не очень-то жалуют многострадальную 1С. Хотя, с выходом платформы 8.3 (с клиентами под Linux), ее стали любить несколько больше. Кстати, так же, совсем недавно интерфейс одной из основных разработок 1С – конфигурация Управление производственным предприятием – был полностью переведен на английский язык. Много раз я встречал вопросы о том, почему здесь не пишут об 1С. Ответ на них довольно очевиден – существует множество специализированных ресурсов, где можно оперативно обсудить все вопросы и что-то почитать.

    Есть все основания полагать, что эта статья здесь не выживет, но я все же рискну, потому что в 1С есть некоторые интересные вещи, о которых стоит рассказать.

    С некоторых пор в 1С 8.х появилась возможность использования веб-сервисов: 1С может выступать как поставщиком, так и потребителем. В этой статье я покажу, как использовать 1С в качестве потребителя на примере получения курсов валют с сервера ЦБР.

    Веб-сервис


    У Центробанка существует веб-сервис для получения ежедневных данных: курсы валют, новости, динамика курсов и т.д. Описание сервиса можно найти здесь http://www.cbr.ru/scripts/Root.asp?Prtid=DWS. Нас интересует один из методов этого сервиса: GetCursOnDate(On_date) – получение курсов валют на заданную дату. В метод передается один аргумент On_date – это дата, на которую требуется получить курсы. В результате возвращается XML, содержащий таблицу ValuteCursOnDate (сами курсы и сопутствующая информация).

    Конфигурирование


    Для разработки я взял 1С 8.2 (8.2.15.317 в моем случае) и создал пустую конфигурацию. Для использования внешних веб-сервисов предусмотрен объект WS-ссылки, но использовать его не обязательно, к сервису можно обращаться динамически из кода. Я буду использовать первый вариант, а затем покажу, как можно использовать второй. В конфигурации создал обработку и назвал ее «ЗагрузкаКурсовВалютЦБР». Добавил форму (управляемую) и сделал ее основной. На форме я создал реквизиты и разместил элементы управления так, как показано на рисунке.



    Сейчас самое главное – создаем ссылку на описание веб-сервиса. В конфигурации добавляем новый объект типа WS-ссылка. В появившемся окне указываем ссылку на WSDL (описание данного формата выходит за рамки статьи, вы можете почитать о нем на Википедии): http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL.



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



    Конфигурирование на этом почти закончено, осталось сделать пару штрихов для того, чтобы наше приложение выглядело более эстетично. Кликнем правой кнопкой мыши по корню конфигурации и вызовем меню «Открыть командный интерфейс рабочего стола». В появившемся окне необходимо снять флаг «Видимость» напротив обработки «Загрузка курсов валют ЦБР». Нажмем кнопку Ок. Далее еще правый клик по корню конфигурации и вызовем меню «Открыть рабочую область рабочего стола», там сделаем настройку как на рисунке:



    Эти настройки позволят нам отобразить форму обработки прямо на рабочем столе (имеется ввиду рабочий стол программы 1С) в режиме 1С Предприятие.

    Программирование


    Теперь осталось наполнить смыслом нашу обработку: заставить ее получать курсы валют и отображать в таблице на форме. В режиме редактирования формы необходимо добавить новую команду формы, назовем ее ЗагрузитьВалюты. Эту команду необходимо связать с кнопкой, расположенной на форме. Действие для команды заполним следующим кодом (прим. автора: ничего себе, на хабре есть подсветка кода 1С, правда она работает не корректно):

    &НаКлиенте
    Процедура ЗагрузитьВалюты(Команда)
    	
    	Если НЕ ЗначениеЗаполнено(ДатаЗагрузки) Тогда 
    		Сообщить("Не выбрана дата загрузки!", СтатусСообщения.Важное);
    		Возврат;
    	КонецЕсли;
    	
    	ТаблицаКурсовВалют.Очистить();
    	ЗагрузитьКурсыВалют(ДатаЗагрузки);
    	
    КонецПроцедуры
    

    Здесь сначала проверяется, заполнена ли дата (если не заполнена, то сообщаем об этом пользователю и больше ничего не делаем). Затем очищается таблица, расположенная на форме и вызывается процедура ЗагрузитьКурсыВалют(), в которую передается дата.

    Код процедуры ЗагрузитьКурсыВалют(), пояснения данны в комментариях к коду:

    Процедура ЗагрузитьКурсыВалют(фДатаЗагрузки)
    		
    	//Создаем прокси для обращения к внешнему веб-сервису,
    	// передаем в функцию URI пространства имен, имя сервиса, имя порта.
    	Прокси = WSСсылки.CBR_DailyInfoWebServ.СоздатьWSПрокси(
                                             "http://web.cbr.ru/", "DailyInfo", "DailyInfoSoap");
    	
    	//Получаем тип параметра, который передается в метод GetCursOnDate.
    	ТипWSПараметра = Прокси.ФабрикаXDTO.Пакеты.Получить(
                                            "http://web.cbr.ru/").Получить("GetCursOnDate");
    	//Создаем параметр на основе типа и заполняем значение параметра On_Date.
    	WSПараметр	   = Прокси.ФабрикаXDTO.Создать(ТипWSПараметра);
    	WSПараметр.On_Date	= фДатаЗагрузки;
    	
    	//Вызываем метод веб-сервиса, записываем результат в переменную КурсыВалют.
    	КурсыВалют = Прокси.GetCursOnDate(WSПараметр);
    	
    	//Перебираем таблицу ValuteCursOnDate, каждое значение таблицы
    	// добавляем в таблицу на форме (колонки заполняем соответствующими значениями).
    	Для Каждого Элемент Из КурсыВалют.GetCursOnDateResult.diffgram.ValuteData.ValuteCursOnDate Цикл 
    		НоваяСтрокаТЗ = ТаблицаКурсовВалют.Добавить();
    		НоваяСтрокаТЗ.НазваниеВалюты      = Элемент.Vname;
    		НоваяСтрокаТЗ.Номинал             = Элемент.Vnom;
    		НоваяСтрокаТЗ.ЦифровойКодВалюты   = Элемент.Vcode;
    		НоваяСтрокаТЗ.СимвольныйКодВалюты = Элемент.VChCode;
    		НоваяСтрокаТЗ.КурсВалюты          = Элемент.Vcurs;
    	КонецЦикла;
    	
    КонецПроцедуры
    

    Теперь можно обновлять конфигурацию БД (F7) и запускать 1С Предприятие (F5). Если все сделали верно, то должны увидеть окно как на рисунке ниже:



    Чтобы проверить результат, нам нужно ввести дату, на которую хотим получить курсы валют и нажать на кнопку «Загрузить валюты». В случае успешного запроса, таблица на форме заполнится значениями курсов:



    Напоследок хочу показать, как можно обратиться динамически к внешнему веб-сервису, то есть без добавления объекта WS-ссылка. Таким образом, мы можем использовать такие веб-сервисы из внешних обработок без привязки к конфигурации.

    В процедуре ЗагрузитьКурсыВалют() строку

    Прокси = WSСсылки.CBR_DailyInfoWebServ.СоздатьWSПрокси("http://web.cbr.ru/", "DailyInfo", "DailyInfoSoap");
    

    необходимо заменить двумя следующими строками

    Определения = Новый WSОпределения("http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL");
    Прокси = Новый WSПрокси(Определения, "http://web.cbr.ru/", "DailyInfo", "DailyInfoSoap");
    

    Сначала мы создаем так называемые определения для веб-сервиса из его WSDL. Затем так же создаем прокси для обращения к нему.

    Как видно, использовать внешние веб-сервисы из 1С в целом довольно просто (хотя и есть некоторая сложность в понимании определения типов, у меня в том числе).

    Если данная публикация найдет здесь отклик, то есть еще несколько тем, о которых можно рассказать.

    По ссылке можно скачать конфигурацию с примером (cf-файл).
    Share post

    Similar posts

    Comments 15

      +1
      Пришлось мне как разработчику WCF REST сервисов столкнуться с 1С-разработчиками, которые реализовывали 1С-клиент (как потребителя контента). Так вот, при работе с web-ресурсами по REST, которые принимают запросы в UTF-8, 1С отправляет HTTP-запрос через создание текстового файла, записи в него тела запроса, и отправки (POST или PUT) только что созданного файла. Это я о кросс-платформенном решении (без использовании XMLHTTPRequest, т.к. через вызов COM-объекта все работает):

      HTTPСоединение = Новый HTTPСоединение(urladdress); HTTPСоединение.ОтправитьДляОбработки("c:\code\1.txt", "Service.svc/session", "c:\code\2.txt", "Content-Type:application/json" + Символы.ВК + Символы.ПС + "charset:UTF-8");

      Особенностью решения 1С-ников было то, что при отправке данных методами POST или PUT, заголовки передаются через аргументы функции, а тело — через файл. Грабли были в том, что при создании файла в кодировке UTF8 1С-ка всегда пишет BOM-символ в начале файла и web-сервис, получая запрос от 1С-клиента с неверным Content-Length'ом (встроенная функция определения длины игнорирует BOM-символ, но это можно исправить вручную) и с BOM-символом в середине тела HTTP-запроса (не в начале) впадает в ступор. Также из-за этого символа.
      Может ли автор статьи рассказать, как обстоят дела с кросс-платформенными запросами в 1С 8.3 при работе с веб-сервисами не по SOAP, а по REST? HTTP-api доработали?
        0
        К сожалению, я еще не углублялся в изучение возможностей 8.3, она вышла менее месяца назад.
          0
          Нифига они не доработали. Понимаю, что некропост, но просто сейчас занимаюсь тем же со стороны 1с, задолбало. Формировать запрос через внешний файл ПРИХОДИТСЯ, хотя в 1с есть возможность отправлять запрос без использования внешнего файла, но в этом режиме граблей раскидано ещё больше, поэтому приходится юзать файлы. А BOM-заголовок от файла можно отрезать с помощью такого извращения:

          ЗТ = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.ANSI);
          ЗТ.Закрыть();

          ЗТ = Новый ЗаписьТекста(ИмяФайла,,, Истина);
          ЗТ.Записать(ТекстПосланияСтрокой);
          ЗТ.Закрыть();

          При этом файл ИмяФайла получается в кодировке UTF-8, но без BOM-заголовка.
            0
            Спустя четыре года отвечаю:) Дела обстоят нормально. Написал целую кучу разнообразных переходников на разные АПИ, всё работает. Отправлять ПОСТ запрос можно без записи файла. Есть работа с джейсон. Бом-символы тоже настраиваются, хотя с ними не сталкивался.
            0
            Видимо и правда, целевой аудитории здесь почти нет. Ну да ладно. :-)
              0
              Ошибаетесь, есть=)
              Работа с вэб сервисами, безусловно, интересна
              Сам я давно уже не писал что — либо в 1С, но регулярно слежу за новыми изменениями и анонасами
              И изменения эти, надо сказать радуют, особенно курс на Linux.
              В свое время писал внешние компоненты и меня просто убивали некоторые вещи.
              К примеру, невозможность передать/вернуть массив из внешней компоненты, написанной на 1С Native API.
              Казалось бы очевидная вещь, но не сподобились сделать
              В итоге пришлось писать дикие грабли в виде собственной сериализации на основе строк.
              Получается, реализовать что-то серъезное в Native API просто не получится, все равно придется писать свой сервис.

                0
                Разве плохо что я в статье нашел то что мне надо и даже вопросов не возникло? К сожалению плюсануть не получится из-за давности статьи.
                0
                Пытался я написать конфигурацию по работе с WS, однако столкнулся с проблемой некорректного определения 1С пустой даты.
                На сайте форуме http://devtrainingforum.v8.1c.ru/forum/thread.jsp?id=597342#597342 никто не подсказал вариант решения. Может у Вас больше опыта и есть решение моей проблемы?
                  0
                  Похоже, вот здесь есть решение проблемы: www.mantisbt.org/forums/viewtopic.php?f=11&t=20480
                  Попробуйте, расскажите потом.
                    0
                    Он обошел тем, что сменил с типа даты, на тип строка, но это немного не то. Хотелось решить именно средствами 1С. Хотя кое-что придется поправить, указав, что это поле можеть быть пустым.
                      0
                      Здесь похоже, что 1С не может правильно обработать поле due_date. И на стороне 1С сделать ничего не получится.
                      Нужно либо сделать так, как по ссылке выше, либо так, чтобы это поле было всегда заполнено, либо вообще исключить его из пакета, если оно не нужно в 1С.
                        0
                        Как бы его только в 1С исключить?
                    0
                    Кстати, забыл спросить, а вы какую версию платформы используете?
                    Простой в 8.2.15.317 нет конструкторов WSОпределения и WSПрокси со столькими параметрами.
                    0
                    А как обновлять курсы валют, кладр, если система не имеет выхода в интернет? оффлайн версии где скачивать и как ставить7
                      0
                      С диска ИТС
                      Также файлы КЛАДРов лежат на сайте gnivc.ru

                    Only users with full accounts can post comments. Log in, please.