17 янв. 2013 г.

Загрузка курсов валют через web-сервисы cbr.ru

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

Нам понадобится создать:
- периодический регистр сведений КурсыВалют, периодичность - день;
- константу, в которой мы будем хранить список валют, курс которых нас интересует;
- общий модуль УправлениеВалютами, в который поместим все необходимые процедуры и функции.

Для загрузки будем использовать web-сервис DailyInfo, метод GetCursOnDate. Входным параметром для этого метода служит дата, на которую мы хотим получить данные.

Создаем регистр КурсыВалют, измерения Валюта (тип справочник Валюты), ресурс Курс (число 15, 4), периодичность - день. Так же создаем форму списка, в дальнейшем разместим на ней команду вызова процедуры обновления.


Создаем константу ИспользуемыеВалюты, тип ХранилищеЗначений. Создаем форму констант, размещаем на ней реквизит ИспользуемыеВалюты (тип СписокЗначений, тип значения СправочникСсылка.Валюты). Прописываем в модуле формы чтение/сохранение нашей константы.

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

&НаСервере
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
 
 ХранилищеВалют = ?(ИспользуемыеВалюты.Количество() = 0, Неопределено, Новый ХранилищеЗначения(ИспользуемыеВалюты));
 Константы.ИспользуемыеВалюты.Установить(ХранилищеВалют);
 
КонецПроцедуры 

Создаем общий модуль УправлениеВалютами, в свойствах устанавливаем Сервер и Вызов сервера

Процедура ЗагрузкаКурсовВалют(ДатаЗагрузки = Неопределено) Экспорт
 
 ДатаЗагрузки = ?(ДатаЗагрузки = Неопределено, ТекущаяДата(), ДатаЗагрузки);
 
 СервКурс = WSСсылки.Daily.СоздатьWSПрокси("http://web.cbr.ru/", "DailyInfo", "DailyInfoSoap");
 ТипКурс = СервКурс.ФабрикаXDTO.Тип("http://web.cbr.ru/", "GetCursOnDate");
 ПараметрыКурс = СервКурс.ФабрикаXDTO.Создать(ТипКурс);
 ПараметрыКурс.On_date= ДатаЗагрузки;
 
 ДанныеКурс = СервКурс.GetCursOnDate(ПараметрыКурс);
 
 СписокКурс = ДанныеКурс.GetCursOnDateResult.diffgram.ValuteData.ValuteCursOnDate;
 
 Если СписокКурс.Количество() = 0 Тогда
  Возврат;
 КонецЕсли;
 
 НаборЗаписейКурс = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
 НаборЗаписейКурс.Отбор.Период.Значение = ДатаЗагрузки;
 НаборЗаписейКурс.Отбор.Период.Использование = Истина;
 НаборЗаписейКурс.Прочитать();
 НаборЗаписейКурс.Очистить();
 
 //при чтении хранилища значений мы получаем либо список валют, либо Неопределено
 //при поиске валюты по коду будем использовать сравнение по типу для определения признака фильтрации
 СписокВалют = Константы.ИспользуемыеВалюты.Получить().Получить();
 
 Для Каждого Элемент Из СписокКурс Цикл
  
  Валюта = ПолучитьВалютуПоКоду(Элемент.VchCode, СписокВалют);
  Если Валюта = Неопределено Тогда
   Продолжить;
  КонецЕсли;
  
  ЗаписьКурс = НаборЗаписейКурс.Добавить();
  ЗаписьКурс.Период = ДатаЗагрузки;
  ЗаписьКурс.Валюта = Валюта;
  ЗаписьКурс.Курс = Число(Элемент.Vcurs);
  
 КонецЦикла;
 
 НаборЗаписейКурс.Записать();
 
КонецПроцедуры

Функция ПолучитьВалютуПоКоду(VcharCode, СписокВалют = Неопределено) Экспорт
 
 Перем Валюта;
 
 Запрос = Новый Запрос;
 Запрос.Текст = 
  "ВЫБРАТЬ
  | Валюты.Ссылка
  |ИЗ
  | Справочник.Валюты КАК Валюты
  |ГДЕ
  | Валюты.VcharCode = &VcharCode
  | И ВЫБОР
  |   КОГДА &ФильтрВалют
  |    ТОГДА Валюты.Ссылка В (&СписокВалют)
  |   ИНАЧЕ ИСТИНА
  |  КОНЕЦ";

 Запрос.УстановитьПараметр("VcharCode", СокрЛП(VcharCode));
 Запрос.УстановитьПараметр("СписокВалют", СписокВалют);
 //используем проверку на СписокЗначений на случай, если вдруг передадут параметр,
 //отличный от Неопределено и от СписокЗначений
 Запрос.УстановитьПараметр("ФильтрВалют", ТипЗнч(СписокВалют) = Тип("СписокЗначений"));

 Результат = Запрос.Выполнить().Выбрать();

 Если Результат.Следующий() Тогда
  Валюта = Результат.Ссылка;
 КонецЕсли;
 
 Возврат Валюта;
 
КонецФункции
 
Теперь создаем и размещаем команду ЗагрузитьКурсы в форме списка регистра КурсыВалют

&НаКлиенте
Процедура ЗагрузитьКурсы(Команда)
 
 УправлениеВалютами.ЗагрузкаКурсовВалют();
 Элементы.Список.Обновить();
 
КонецПроцедуры
 
Запускаем нашу конфигурацию в режиме 1С: Предприятие, заполняем список валют. Если список оставить пустым, то загрузятся курсы всех валют, зарегистрированных в системе.

Переходим в список курсов валют, выполняем загрузку курсов.

Напоследок, можно еще добавить регламентное задание ЗагрузкаКурсовВалют, в качестве метода указываем УправлениеВалютами.ЗагрузкаКурсовВалют, расписание: каждый  день; с 7:00:00 один раз в день.

Скачать конфигурацию (1Cv8_wsdl.cf)

3 комментария:

  1. Здравствуйте, очень помогла ваша статья загрузки курсов валют. Всё прекрасно получилось всё работало а потом в один момент появилась ошибка, может ли быть из-за того что слишком часто загружал курсы ?? Я просто проверял и раз 5 а то и выше удалял загруженные и снова загружал

    {Справочник.Валюты.Форма.ФормаСписка.Форма(10)}: Ошибка при вызове метода контекста (EnumValutes)
    ДанныеВалюта = СервВалюты.EnumValutes(ЗначениеБулево);
    по причине:
    При вызове веб-сервиса произошла ошибка. Ошибка вызова операции сервиса: {http://web.cbr.ru/}:DailyInfo:EnumValutes()
    по причине:
    При вызове веб-сервиса произошла ошибка. Неизвестная ошибка. Ошибка работы с Интернет: Number of redirects hit maximum amount
    по причине:
    Ошибка работы с Интернет: Number of redirects hit maximum amount

    ОтветитьУдалить
  2. Человек!!! Ты просто Великолепен!!! Невероятно огромное Тебе СПАСИБО!!!!
    Все так четко, просто и понятно!!!!!
    СПАСИБО!!!!!!

    ОтветитьУдалить
  3. Хороший и полезный сайт. Рад что наткнулся на него ))

    ОтветитьУдалить