Макрос получения курсов доллара за период с сайта Банка России

Excel (Эксель) прекрасен, а мир огромен. И готов предложить для анализа много разной информации из сети под названием Интернет. Часто видел, как аналитики мужеского и женского рода просто перебивают ручками данные со страниц разных сайтов для своей работы.

Иногда целесообразнее написать небольшой макрос, который будет получать данные из интернета автоматически. Для этого уже давно придуман Microsoft XML parser (MSXML).

Для примера, я и покажу, как с его помощью, получить курсы доллара за период с сайта ЦБ.

1) Организуйте столбец с датами на одной из «Sheets» экселя. У меня это столбец «A»

2) Подключите ссылку на Microsoft XML

3) Собственно пишем процедуру

Sub GetUSDRates4Period()

Объявляем переменные и открываем окно в мир интернета:

Dim strCCY As String, strRateCCY As String, strRateSource As String

Dim xmlDoc As MSXML2.DOMDocument

Set xmlDoc = New MSXML2.DOMDocument

xmlDoc.async = False

MSXML2 – это и есть упомянутый выше Microsoft XML parser, который нужно направить на сайт Банка России

strRateSource = "http://www.cbr.ru/scripts/XML_daily.asp?date_req="

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

Dim i As Long

i = 1

Dim strDate As String

Do While Not Range("a" & i) = ""

strDate = Format(Range("a" & i), "dd\/mm\/yyyy")

Всякое бывает с сайтами или вашим интернетом, поэтому нужно проверить результаты попытка загрузки xml файла.

If xmlDoc.Load(strRateSource & strDate) <> True Then

MsgBox "Сайт ЦБ сейчас не в духе, попробуйте обратиться к нему позже..."

Exit Sub

End If

Если же загрузка прошла успешно, то начинается магия xPath. Сначала получим дату, к которой на самом деле привязан курс доллара. Она не всегда совпадает с той датой, на которую вы курс запросили. И поместим дату ЦБ в столбец «B»

Range("b" & i) = xmlDoc.selectNodes("//ValCurs")(0).Attributes(0).Text

"//ValCurs" – это и есть выражение XPath, которое может быть очень интересным и витиеватым, и которое позволяет добраться практически до любой точки xml файла. В вышеприведенном примере я взял дату валютирования из тега ValCurs.

А ниже выражение посложнее. С его помощью я нахожу валюту «доллар» среди множества других (у этой валюты ID=R01235) и прошу показать мне только курс этой валюты (там есть и другая информация: буквенный и цифровой коды валюты в соответствии с ISO 4217 и/или ОКВ, номинал, описание, - но нам нужен только курс).

strRateCCY = xmlDoc.selectNodes("//Valute[@ID='R01235']/Value")(0).Text

Далее я привожу текст с курсом к числу с учетом настроек символа разделителя разрядов.

Range("c" & i).Value = CdblLocaleIndependent(strRateCCY)

Функцию CdblLocaleIndependent в этом посте показывать не буду, пока желающих на нее посмотреть не будет достаточно.

Закругляемся с циклом и заканчиваем работу:

i = i + 1

Loop

MsgBox "Курсы сняты с сайта Банка России."

End Sub

MS, Libreoffice & Google docs

719 постов15K подписчика

Добавить пост

Правила сообщества

1. Не нарушать правила Пикабу

2. Публиковать посты соответствующие тематике сообщества

3. Проявлять уважение к пользователям

4. Не допускается публикация постов с вопросами, ответы на которые легко найти с помощью любого поискового сайта.

По интересующим вопросам можно обратиться к автору поста схожей тематики, либо к пользователям в комментариях


Важно - сообщество призвано помочь, а не постебаться над постами авторов! Помните, не все обладают 100 процентными знаниями и навыками работы с Office. Хотя вы и можете написать, что вы знали об описываемом приёме раньше, пост неинтересный и т.п. и т.д., просьба воздержаться от подобных комментариев, вместо этого предложите способ лучше, либо дополните его своей полезной информацией и вам будут благодарны пользователи.

Утверждения вроде "пост - отстой", это оскорбление автора и будет наказываться баном.

Вы смотрите срез комментариев. Показать все
Автор поста оценил этот комментарий

Чему детей учишь? Attributes(0)?! Там вполне конкретный аттрибут! Никакого колхоза!

раскрыть ветку (10)
Автор поста оценил этот комментарий

Можно и по другому:


Range("b" & i) = xmlDoc.selectNodes("//ValCurs/@Date")(0).Text


Против такой нотации возражений нет? :)

Я, в принципе, за краткость, но использование объектной модели повышает управляемость.

раскрыть ветку (9)
Автор поста оценил этот комментарий

Это та же модель xpath, просто по номеру аттрибута выбор - вообще полная дичь. Стараться везде где можно использовать исключительно полный XPath.

раскрыть ветку (8)
Автор поста оценил этот комментарий

насчет "полной дичи" - это, конечно, перебор. Но в целом замечание с указанием на то, что конкретную строчку можно сделать и по изящней - по делу.

Так что, спасибо.

раскрыть ветку (7)
Автор поста оценил этот комментарий

Забор аттрибута по номеру - это вообще неверно как бы...

раскрыть ветку (6)
Автор поста оценил этот комментарий

Осталось еще ответить на вопрос: если все так категорично, зачем такую возможность сделали в Microsoft?


Чем то напоминает мне дискуссию с одной девушкой, которая уверенно утверждала, что ручной тормоз в автомобиле придуман по ошибке :)


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

раскрыть ветку (5)
Автор поста оценил этот комментарий

Не только, твоё есть везде. Если ты не понимаешь для чего - это очень плохо. В двух словах - время выполнения селектора , это для кейсов быстрых циклов с валидированными уже данными.

раскрыть ветку (4)
Автор поста оценил этот комментарий

Ты сам противоречишь своему уже ультимативному высказыванию?: "Забор аттрибута по номеру - это вообще неверно".

раскрыть ветку (3)
Автор поста оценил этот комментарий

Ты ещё и читаешь криво...

Ясно же написано - для случаев когда цикл требующий быстроты, но xpath, и данные ПРОВЕРЕННЫЕ. Если бы они были тут ПРОВЕРЕННЫЕ - можно бы и по индексам всё брать не парясь.

раскрыть ветку (2)
Автор поста оценил этот комментарий

Я всего лишь привел твою цитату. Это значит, что не я читаю криво, а ты пишешь криво.

И еще обрати внимание на источник данных - Банк России дает проверенные данные :)

В дальнейшей дискуссии смысла не вижу, ибо от конструктива она перетекла в личные оскорбления,

увы :(

раскрыть ветку (1)
Автор поста оценил этот комментарий

Да, ты реально не от нормальной разработки.

Банк не даёт спецификации формата, всё, далее говорить не о чем.

Вы смотрите срез комментариев. Чтобы написать комментарий, перейдите к общему списку