Не все компании устраивает возможность заложенная в 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.
В следующих статьях я расскажу о загрузках курсов валют для некоторых стран ближнего зарубежья, Восточной Европы и будет одна изюминка - загрузка курсов валют с одного международного источника, где можно получить курс любой валюты!
Критика принимается, комментарии приветствуются.
Спасибо за внимание.