Загрузка курсов валют с Европейского Центрального Банка (или ECB - European Central Bank)

Загрузка курсов валют с Европейского Центрального Банка (или ECB - European Central Bank)

Не все компании устраивает возможность заложенная в 1С: загружать курсы ЦБ Рф. Часто требуется иметь курсы валют bloomberg, ЕЦБ и тому подобное. Об одном из таких источников я и хочу рассказать: Загрузка курсов валют ECB покрывает потребность многих стран Евросоюза - Еврозоны, а это (на день публикации статьи) 19 стран, официальной валютой которых является Евро.

Не буду тянуть кота за... резину.

Итак, загрузка курсов валют с Европейского Центрального Банка (или ECB - European Central Bank).

По сути дела, нам потребуется всего лишь одна ссылка - ссылка на xml-файл с курсами валют:

https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml

На этом можно было бы статью и закончить, ибо разобрать xml и загрузить из него данные в регистр сведений Курсов валют не составит особого труда. Только необходимо учитывать одну маленькую особенность файла: в отличии от курсов ЦБ РФ, где стоимость валют выражается в единой валюте - Рублях, ECB курсы валют предоставляет в "обратном" выражении к Евро. То есть, в файле курс валюты - это стоимость ОДНОГО евро выраженного в валюте.

Да, есть и еще одна особенность: в этом файл предоставляются курсы валют за последние 90 дней. То есть не получится получить курс, скажем, 95-дневной давности... 

Да, и количество валют там сильно ограничено... И дата последнего курса всегда за вчерашний день, т.е., если получаете файл 22.05.2020 г., то последний курс в файле будет на 21.05.2020 г.

Ниже приведу формат файла для понимания.

 

 На этом опытным разработчикам можно закончить чтение этой статьи. 

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

Часть процедуры чтения из XML-файла (здесь "валюта" - это пока строковое наименование из файла):

//Создаем таблицу значений для курсов валют
        ТаблицаКурсов = Новый ТаблицаЗначений;
	ТаблицаКурсов.Колонки.Добавить("Валюта");
	ТаблицаКурсов.Колонки.Добавить("Курс");
	ТаблицаКурсов.Колонки.Добавить("Кратность");
	ТаблицаКурсов.Колонки.Добавить("Период");
	
	//Делаем загрузку по датам
	Начало = НачалоДня(НачалоПериодаЗагрузки) - 3*24*60*60;
	Конец = НачалоДня(ОкончаниеПериодаЗагрузки) - 1;
	
	XML_Документ = Новый ЧтениеXML;
	ИмяФайла = 
			//Загрузка валюты из европейского банка (только за последние 90 дней)
			"https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml";
	XML_Документ.ОткрытьФайл(
		ИмяФайла
	);
	
	ПервыйПроход = Истина;
	НачДата = Начало;
	КонДата = Конец;
	
	Пока XML_Документ.Прочитать() Цикл
		
		Если XML_Документ.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
			
			Если XML_Документ.Имя = "Cube" Тогда
				Если XML_Документ.КоличествоАтрибутов() = 1 Тогда
					СтрДата =  XML_Документ.ЗначениеАтрибута(0);
					ДатаКурса = Дата(СтрЗаменить(СтрДата,"-",""));
					
					//При первом проходе, если дата начала загрузки больше максимальной 
//(первая запись в файле) даты в файле, то грузим
//первую дату - срез последних, например,
//при загрузке в понедельник необходимо загрузить курс за пятницу...
Если Не ПервыйПроход Тогда Если ДатаКурса < НачДата или ДатаКурса > КонДата Тогда XML_Документ.Пропустить(); КонецЕсли; ИначеЕсли ДатаКурса > КонДата Тогда XML_Документ.Пропустить(); КонецЕсли; ПервыйПроход = Ложь; ИначеЕсли XML_Документ.КоличествоАтрибутов() = 2 Тогда Валюта = XML_Документ.ЗначениеАтрибута(0); Курс = XML_Документ.ЗначениеАтрибута(1); Попытка Коэф = СтрДлина(Строка(Цел(Курс))); //Вычисляем кратность валюты, т.к. в файле ее нет, а грузить всегда с кратностью 1
                                                //будет "не красиво")) 
//Да и курс в отведенные "4 знака после запятой" не "поместится"
Если Коэф > 1 Тогда Кратность = Pow(10,Коэф+1); Иначе Кратность = 1; КонецЕсли; //Вычисляем курс с учетом кратности //и с учетом того, что грузим курс к Евро, т.е нам нужен ОБРАТНЫЙ курс
//(это задача конкретного случая: мне нужно было хранить курсы именно к ЕВРО
//если кому-то нужен курс евро к валюте из файла, то 1 делить на курс не нужно Курс = Окр((1/Курс)*Кратность,4); Если ДатаКурса>=НачалоПериодаЗагрузки И ДатаКурса<=ОкончаниеПериодаЗагрузки И (Курс<>1 ИЛИ Кратность<>1) Тогда НоваяСтрока = ТаблицаКурсов.Добавить(); НоваяСтрока.Валюта = Валюта; НоваяСтрока.Период = НачалоДня(ДатаКурса); НоваяСтрока.Курс = Курс; НоваяСтрока.Кратность = Кратность; КонецЕсли; Исключение //можно вести лог, если что-то при расчетах выше пошло не так КонецПопытки; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; ТаблицаКурсов.Свернуть("Валюта,Курс,Кратность,Период");

Далее, построчно перебираем предварительную таблицу значений с курсами валют, ищем в справочнике валют по наименованию валюту и записываем в регистр сведений Курсы валют:

//ВалютыДляЗагрузки - это таблица валют из справочника Валюты курсы которых нам требуется загрузить в регистр

//Как минимум, из этого списка требуется убрать Евро - курс которой всегда = 1 (в нашем случае - Евро). Помним мои комментарии выше

Для Каждого Валюта Из ВалютыДляЗагрузки Цикл

           КраткоеНаименованиеВалюты = Валюта.Наименование;

           ДатаКурса = НачалоПериодаЗагрузки;

           Пока ДатаКурса <= ОкончаниеПериодаЗагрузки Цикл

                 //Отбор по таблице значений курсов

                 Отбор = Новый Структура("Валюта, Период",КраткоеНаименованиеВалюты,НачалоДня(ДатаКурса));

                 НайденныеСтроки = ТаблицаКурсов.НайтиСтроки(Отбор);

 

                 Если НайденныеСтроки.Количество() = 0 Тогда

                                 // здесь не совсем корректно: если на дату курса в таблице значений нет или валюты в таблице нет,
//то в регистре сведений строка с курсом удаляется, если он там был
                                 //у мена так нужно было. Если кому-то не нужно, то это "Если... КонецЕсли;" нужно удалить                             НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();                        НаборЗаписей.Отбор.Валюта.Установить(Валюта.Валюта);                        НаборЗаписей.Отбор.Период.Установить(ДатаКурса);                       НаборЗаписей.Записать();                  КонецЕсли;                    Для Каждого ИнформацияОКурсеВалюты Из НайденныеСтроки Цикл                       НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();                        НаборЗаписей.Отбор.Валюта.Установить(Валюта);                        НаборЗаписей.Отбор.Период.Установить(ДатаКурса);                       Запись = НаборЗаписей.Добавить();                       Запись.Валюта = Валюта;                       Запись.Период = ДатаКурса;                       Запись.Курс = ИнформацияОКурсеВалюты.Курс;                       Запись.Кратность = ИнформацияОКурсеВалюты.Кратность;                       НаборЗаписей.Записать();                  КонецЦикла;                         //Увеличиваем дату да 1 день и считываем курсы на следующую дату                  ДатаКурса = ДатаКурса + 24*60*60;            КонецЦикла;       КонецЦикла;

Сразу прошу прощения, если в коде попадаются не описанные ранее переменные или где-то логика не совсем понятна. Делайте скидку на то, что эти "куски" кода "выдернуты" из обработки, в которой была заложена определенная логика, которую я не счел нужным полностью выкладывать в этой статье. Задача была "слегка" специфичной. 

Но цель, надеюсь, достигнута: я изложил основной принцип - как загрузить курсы валют ECB.

В следующих статьях я расскажу о загрузках курсов валют для некоторых стран ближнего зарубежья, Восточной Европы и будет одна изюминка - загрузка курсов валют с одного международного источника, где можно получить курс любой валюты!

Критика принимается, комментарии приветствуются. 

Спасибо за внимание. 

 


Печать   E-mail