Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Получение котировок на драгметаллы с сайта ЦБ РФ - Мир MS Excel

Старая форма входа
  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: китин, _Boroda_  
Мир MS Excel » Вопросы и решения » Вопросы по VBA » Получение котировок на драгметаллы с сайта ЦБ РФ (Функции/Function)
Получение котировок на драгметаллы с сайта ЦБ РФ
forest1333 Дата: Пятница, 10.10.2014, 00:03 | Сообщение № 1
Группа: Пользователи
Ранг: Прохожий
Сообщений: 9
Репутация: 0 ±
Замечаний: 0% ±

Excel 2010
Здравствуйте ещё раз.

Уважаемый krosav4ig уже один раз помог мне на этом форуме, поэтому я решил обратиться за помощью ещё раз, но уже по другому вопросу.

Мне нужно выцепить цену на серебро с сайта ЦБ РФ. Вот тут есть кое-какие примеры, но для драгметаллов там выводится архив котировок за период, а мне нужно на сегодняшний день: http://www.cbr.ru/scripts/Root.asp?PrtId=SXML

Нужен модуль и функция.

Помогите, пожалуйста.
 
Ответить
СообщениеЗдравствуйте ещё раз.

Уважаемый krosav4ig уже один раз помог мне на этом форуме, поэтому я решил обратиться за помощью ещё раз, но уже по другому вопросу.

Мне нужно выцепить цену на серебро с сайта ЦБ РФ. Вот тут есть кое-какие примеры, но для драгметаллов там выводится архив котировок за период, а мне нужно на сегодняшний день: http://www.cbr.ru/scripts/Root.asp?PrtId=SXML

Нужен модуль и функция.

Помогите, пожалуйста.

Автор - forest1333
Дата добавления - 10.10.2014 в 00:03
Rioran Дата: Пятница, 10.10.2014, 10:41 | Сообщение № 2
Группа: Авторы
Ранг: Ветеран
Сообщений: 903
Репутация: 290 ±
Замечаний: 0% ±

Excel 2013
forest1333, здравствуйте.

Обязательно ли работать через XML? Предлагаю другое решение.

Первая кнопка грузит данные с сайта ЦБ РФ по металлам за сегодня. Через несколько секунд информация отображается и можно жмакнуть вторую кнопу - чтобы данные добавились в базу.

Осторожно, в качестве исторических данных использую случайно сгенерированые цифры, Вам нужно будет всё заполнять с нуля.

[vba]
Код
Sub Rio_loads_metals_from_CBR()

'Author:    Roman Rioran Voronov
'Date:      the 10-th of October, 2014
'Feedback:  voronov_rv@mail.ru

Dim shtA As Worksheet 'Load sheet
Set shtA = ThisWorkbook.Worksheets("Load")

shtA.Cells.Clear

Do While shtA.QueryTables.Count > 0
     shtA.QueryTables(1).Delete
Loop

With shtA.QueryTables.Add(Connection:="URL;http://www.cbr.ru", Destination:=shtA.Range("A1"))
     .WebSelectionType = xlSpecifiedTables
     .WebTables = "4"
     .Refresh
End With
      
End Sub

Sub Rio_adds_data_to_CBR_Argentum_Table()

Cells(1, 1).Offset(Cells(Rows.Count, 1).End(xlUp).Row, 0).Resize(1, 2).Value = [A1:B1].Value

End Sub
[/vba]
К сообщению приложен файл: Rio_Ag_Control.xlsb (23.3 Kb)


Роман, Москва, voronov_rv@mail.ru
Яндекс-Деньги: 41001312674279
 
Ответить
Сообщениеforest1333, здравствуйте.

Обязательно ли работать через XML? Предлагаю другое решение.

Первая кнопка грузит данные с сайта ЦБ РФ по металлам за сегодня. Через несколько секунд информация отображается и можно жмакнуть вторую кнопу - чтобы данные добавились в базу.

Осторожно, в качестве исторических данных использую случайно сгенерированые цифры, Вам нужно будет всё заполнять с нуля.

[vba]
Код
Sub Rio_loads_metals_from_CBR()

'Author:    Roman Rioran Voronov
'Date:      the 10-th of October, 2014
'Feedback:  voronov_rv@mail.ru

Dim shtA As Worksheet 'Load sheet
Set shtA = ThisWorkbook.Worksheets("Load")

shtA.Cells.Clear

Do While shtA.QueryTables.Count > 0
     shtA.QueryTables(1).Delete
Loop

With shtA.QueryTables.Add(Connection:="URL;http://www.cbr.ru", Destination:=shtA.Range("A1"))
     .WebSelectionType = xlSpecifiedTables
     .WebTables = "4"
     .Refresh
End With
      
End Sub

Sub Rio_adds_data_to_CBR_Argentum_Table()

Cells(1, 1).Offset(Cells(Rows.Count, 1).End(xlUp).Row, 0).Resize(1, 2).Value = [A1:B1].Value

End Sub
[/vba]

Автор - Rioran
Дата добавления - 10.10.2014 в 10:41
UltrasRW Дата: Пятница, 10.10.2014, 11:05 | Сообщение № 3
Группа: Пользователи
Ранг: Новичок
Сообщений: 13
Репутация: 5 ±
Замечаний: 0% ±

счеты деревянные
forest1333, добрый день!
К сообщению приложен файл: xml_cbr.xls (44.0 Kb)


Сообщение отредактировал UltrasRW - Пятница, 10.10.2014, 11:06
 
Ответить
Сообщениеforest1333, добрый день!

Автор - UltrasRW
Дата добавления - 10.10.2014 в 11:05
krosav4ig Дата: Пятница, 10.10.2014, 12:57 | Сообщение № 4
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
UltrasRW, зачем бегать циклом по элементам, когда есть XPath и нужный элемент можно выбрать одним запросом, и дату ЦБР вполне себе понимает в формате ДД.ММ.ГГГГ
forest1333, собственно вот мой вариант функции
[vba]
Код
Function МетЦБР#(Optional Code% = 2, Optional dDate As Date, Optional sell% = 0)
       Dim d As Object: Set d = CreateObject("msxml.DOMDocument")
       dDate = IIf(dDate, dDate, Date): d.async = 0
       d.Load ("http://www.cbr.ru/scripts/xml_metall.asp?date_req1=" & dDate & "&date_req2=" & dDate)
       МетЦБР = CDbl(d.SelectSingleNode("*/Record[@Code='" & Code & "']").ChildNodes(Abs(sell)).Text)
       Set d = Nothing
End Function
[/vba]
у функции 3 необязательных атрибута
Первый: Код металла (1-золото,2-серебро,3-платина,4-палладий), если параметр не указан, то по умолчанию берется 2
Второй: дата в текстовом формате или ссылка на ячейку с датой в числовом формате. если параметр не указан, то по умолчанию берется текущая СИСТЕМНАЯ дата (дата, установленная в компьютере, может не совпадать с фактической) в качестве разделителей между числами дня, месяца и года может использоваться любой символ из " " , "/" , "." , "-" , "," , запись даты в формате "1 янв 14" и "1 января 2014" тоже корректно распознаются
По моему курсы на покупку и продажу у ЦБР одинаковые, но на всякий случай сделал третий атрибут: тип курса банка- 0-покупка, 1-продажа, если параметр не указан, то по умолчанию берется 0
формула
Код
=МетЦБР()
вернет текущий курс банка на покупку серебра.
К сообщению приложен файл: 4807263.xls (34.0 Kb)


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460

Сообщение отредактировал krosav4ig - Пятница, 10.10.2014, 13:11
 
Ответить
СообщениеUltrasRW, зачем бегать циклом по элементам, когда есть XPath и нужный элемент можно выбрать одним запросом, и дату ЦБР вполне себе понимает в формате ДД.ММ.ГГГГ
forest1333, собственно вот мой вариант функции
[vba]
Код
Function МетЦБР#(Optional Code% = 2, Optional dDate As Date, Optional sell% = 0)
       Dim d As Object: Set d = CreateObject("msxml.DOMDocument")
       dDate = IIf(dDate, dDate, Date): d.async = 0
       d.Load ("http://www.cbr.ru/scripts/xml_metall.asp?date_req1=" & dDate & "&date_req2=" & dDate)
       МетЦБР = CDbl(d.SelectSingleNode("*/Record[@Code='" & Code & "']").ChildNodes(Abs(sell)).Text)
       Set d = Nothing
End Function
[/vba]
у функции 3 необязательных атрибута
Первый: Код металла (1-золото,2-серебро,3-платина,4-палладий), если параметр не указан, то по умолчанию берется 2
Второй: дата в текстовом формате или ссылка на ячейку с датой в числовом формате. если параметр не указан, то по умолчанию берется текущая СИСТЕМНАЯ дата (дата, установленная в компьютере, может не совпадать с фактической) в качестве разделителей между числами дня, месяца и года может использоваться любой символ из " " , "/" , "." , "-" , "," , запись даты в формате "1 янв 14" и "1 января 2014" тоже корректно распознаются
По моему курсы на покупку и продажу у ЦБР одинаковые, но на всякий случай сделал третий атрибут: тип курса банка- 0-покупка, 1-продажа, если параметр не указан, то по умолчанию берется 0
формула
Код
=МетЦБР()
вернет текущий курс банка на покупку серебра.

Автор - krosav4ig
Дата добавления - 10.10.2014 в 12:57
forest1333 Дата: Пятница, 10.10.2014, 18:24 | Сообщение № 5
Группа: Пользователи
Ранг: Прохожий
Сообщений: 9
Репутация: 0 ±
Замечаний: 0% ±

Excel 2010
Большое спасибо за помощь, ребята. Особенно krosav4ig, ваш вариант для меня наиболее подходящий оказался.

По моему курсы на покупку и продажу у ЦБР одинаковые, но на всякий случай сделал третий атрибут


У ЦБ всегда один курс на валюты и драгоценные металлы, потому что он является регулятором. Цены на покупку и продажу разнятся у остальных банков, потому что они занимаются перепродажей валюты.
 
Ответить
СообщениеБольшое спасибо за помощь, ребята. Особенно krosav4ig, ваш вариант для меня наиболее подходящий оказался.

По моему курсы на покупку и продажу у ЦБР одинаковые, но на всякий случай сделал третий атрибут


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

Автор - forest1333
Дата добавления - 10.10.2014 в 18:24
krosav4ig Дата: Суббота, 11.10.2014, 19:06 | Сообщение № 6
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
нарисовал еще одну функцию. возвращает текущую цену на драгметалл с главной страницы ЦБР
для работы необходимо подключить Microsoft HTML Object Library
[vba]
Код
Private Declare Function DeleteUrlCacheEntry& Lib "wininet" (ByVal lpszUrlName$)
Function МетЦБР2#(code)
      Application.Volatile False
      Dim oHTML As HTMLDocument, oDoc As HTMLDocument, elem As HTMLBaseElement, url$, n%, str$:
      Set oHTML = New HTMLDocument
      url = "http://www.cbr.ru/"
      DeleteUrlCacheEntry (url)
      Set oDoc = oHTML.createDocumentFromUrl(url, "")
      Do
          DoEvents
      Loop Until oDoc.readyState = "complete"
      oHTML.body.innerHTML = oDoc.getElementById("widget_metal").innerHTML
      Set oDoc = Nothing
      n = InStr(1, "_auagptpg", LCase(code)) / 2 - 1 + Val(code)
      Set elem = oHTML.getElementsByTagName("span")(n)
      МетЦБР2 = CDbl(elem.innerText)
      'With Application.Caller
      '    If Not .Comment Is Nothing Then .Comment.Delete
      '    str = oHTML.getElementsByTagName("ins")(n).ParentNode.innerText
      '    str = str & CStr(CDate(Mid(Replace(oHTML.LastModified, "/", "/" & Left(oHTML.LastModified, 3)), 7, 10)))
      '    .AddComment str & Right(oHTML.LastModified, 9)
      'End With
      Set elem = Nothing
      Set oHTML = Nothing
End Function
[/vba]
закомментированные строки кода добавляют в ячейку примечание с названием металла, его буквенным кодом, датой и временем
code - числовой или буквенный код металла: золото - 1 или "au", серебро - 2 или "ag", платина -3 или "pt", палладий - 4 или "pd"
К сообщению приложен файл: 3582330.xls (38.0 Kb)


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460

Сообщение отредактировал krosav4ig - Суббота, 11.10.2014, 19:23
 
Ответить
Сообщениенарисовал еще одну функцию. возвращает текущую цену на драгметалл с главной страницы ЦБР
для работы необходимо подключить Microsoft HTML Object Library
[vba]
Код
Private Declare Function DeleteUrlCacheEntry& Lib "wininet" (ByVal lpszUrlName$)
Function МетЦБР2#(code)
      Application.Volatile False
      Dim oHTML As HTMLDocument, oDoc As HTMLDocument, elem As HTMLBaseElement, url$, n%, str$:
      Set oHTML = New HTMLDocument
      url = "http://www.cbr.ru/"
      DeleteUrlCacheEntry (url)
      Set oDoc = oHTML.createDocumentFromUrl(url, "")
      Do
          DoEvents
      Loop Until oDoc.readyState = "complete"
      oHTML.body.innerHTML = oDoc.getElementById("widget_metal").innerHTML
      Set oDoc = Nothing
      n = InStr(1, "_auagptpg", LCase(code)) / 2 - 1 + Val(code)
      Set elem = oHTML.getElementsByTagName("span")(n)
      МетЦБР2 = CDbl(elem.innerText)
      'With Application.Caller
      '    If Not .Comment Is Nothing Then .Comment.Delete
      '    str = oHTML.getElementsByTagName("ins")(n).ParentNode.innerText
      '    str = str & CStr(CDate(Mid(Replace(oHTML.LastModified, "/", "/" & Left(oHTML.LastModified, 3)), 7, 10)))
      '    .AddComment str & Right(oHTML.LastModified, 9)
      'End With
      Set elem = Nothing
      Set oHTML = Nothing
End Function
[/vba]
закомментированные строки кода добавляют в ячейку примечание с названием металла, его буквенным кодом, датой и временем
code - числовой или буквенный код металла: золото - 1 или "au", серебро - 2 или "ag", платина -3 или "pt", палладий - 4 или "pd"

Автор - krosav4ig
Дата добавления - 11.10.2014 в 19:06
forest1333 Дата: Понедельник, 13.10.2014, 20:53 | Сообщение № 7
Группа: Пользователи
Ранг: Прохожий
Сообщений: 9
Репутация: 0 ±
Замечаний: 0% ±

Excel 2010
нарисовал еще одну функцию. возвращает текущую цену на драгметалл с главной страницы ЦБР


Да, спасибо большое. Но вот хотел на что обратить внимание.

По предыдущему варианту, что вы сделали, ваша функция отказывается корректно работать по субботам, воскресеньям и понедельникам, видимо потому, что в пятницу ЦБ устанавливает курс на 3 дня вперёд.
А недостаток второй функции заключается в том, что во второй половине дня ЦБ публикует курс серебра на завтра, и в итоге excel во второй половине дня вытягивает в таблицу не сегодняшнее значение, а завтрашнее.

Можно ли сделать так, чтобы в течение всего дня каждый день, включая субботу, воскресенье, понедельник и праздники, когда ЦБ не работает и устанавливает курс на несколько дней вперёд заранее, в таблицу вставлялся актуальный курс? Ну или курс по дате, расположенной в соседней ячейке (я там могу использовать функцию "сегодня")?
 
Ответить
Сообщение
нарисовал еще одну функцию. возвращает текущую цену на драгметалл с главной страницы ЦБР


Да, спасибо большое. Но вот хотел на что обратить внимание.

По предыдущему варианту, что вы сделали, ваша функция отказывается корректно работать по субботам, воскресеньям и понедельникам, видимо потому, что в пятницу ЦБ устанавливает курс на 3 дня вперёд.
А недостаток второй функции заключается в том, что во второй половине дня ЦБ публикует курс серебра на завтра, и в итоге excel во второй половине дня вытягивает в таблицу не сегодняшнее значение, а завтрашнее.

Можно ли сделать так, чтобы в течение всего дня каждый день, включая субботу, воскресенье, понедельник и праздники, когда ЦБ не работает и устанавливает курс на несколько дней вперёд заранее, в таблицу вставлялся актуальный курс? Ну или курс по дате, расположенной в соседней ячейке (я там могу использовать функцию "сегодня")?

Автор - forest1333
Дата добавления - 13.10.2014 в 20:53
krosav4ig Дата: Понедельник, 13.10.2014, 23:11 | Сообщение № 8
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
я правильно понял, что в пятницу ЦБ устанавливает курс, который вступает в силу с субботы и действует по понедельник включительно?
и по поводу праздников. К примеру тут написано
Цитата
1, 2, 3, 4, 5, 6 и 8 января — Новогодние каникулы;
7 января — Рождество Христово;
9 января — выходной;

это означает, что 31 декабря устанавливается курс, который вступает в силу 1 янв и действует по 12 янв включительно (1-9 янв нерабочие дни, 10 янв-суббота)?


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460

Сообщение отредактировал krosav4ig - Понедельник, 13.10.2014, 23:24
 
Ответить
Сообщениея правильно понял, что в пятницу ЦБ устанавливает курс, который вступает в силу с субботы и действует по понедельник включительно?
и по поводу праздников. К примеру тут написано
Цитата
1, 2, 3, 4, 5, 6 и 8 января — Новогодние каникулы;
7 января — Рождество Христово;
9 января — выходной;

это означает, что 31 декабря устанавливается курс, который вступает в силу 1 янв и действует по 12 янв включительно (1-9 янв нерабочие дни, 10 янв-суббота)?

Автор - krosav4ig
Дата добавления - 13.10.2014 в 23:11
forest1333 Дата: Вторник, 14.10.2014, 01:16 | Сообщение № 9
Группа: Пользователи
Ранг: Прохожий
Сообщений: 9
Репутация: 0 ±
Замечаний: 0% ±

Excel 2010
я правильно понял, что в пятницу ЦБ устанавливает курс, который вступает в силу с субботы и действует по понедельник включительно?


Да, именно так.

и по поводу праздников


Вот по поводу конкретных дат праздников ничего не могу сказать. Не проследил график работы ЦБ в этом вопросе.

Знаете, у меня есть модуль для цепляния курса валют с сайта ЦБ:

[vba]
Код
Sub ВывестиСегодняшниеКурсыВсехВалют()
     On Error Resume Next
     Set xmldoc = CreateObject("Msxml.DOMDocument"): xmldoc.async = False
     url_request = "http://www.cbr.ru/scripts/XML_daily.asp?date_req=" + Format(Now, "dd\/mm\/yyyy")
     If xmldoc.Load(url_request) <> True Then Exit Sub
     Set nodeList = xmldoc.SelectNodes("ValCurs"): Set xmlNode = nodeList.Item(0).CloneNode(True)
     Set node_attr = xmlNode.Attributes(0): strDate = node_attr.Value
     Set nodeList = xmldoc.SelectNodes("*/Valute")
     For i = 0 To nodeList.Length - 1
         Set xmlNode = nodeList.Item(i).CloneNode(True)
         Debug.Print "Курс " & xmlNode.ChildNodes(1).Text & " (установлен " & strDate & "): " & _
                     xmlNode.ChildNodes(4).Text & " рублей за " & xmlNode.ChildNodes(2).Text & _
                   " " & xmlNode.ChildNodes(3).Text
     Next
End Sub

Function GetRate(ByVal CurrencyName As String, ByVal RateDate As Date) As Single
     ' функция возвращает курс валюты CurrencyName на дату RateDate
     ' в случае ошибки (неверная дата или название валюты) возвращается 0
     On Error Resume Next
     CurrencyName = UCase(CurrencyName): If Len(CurrencyName) <> 3 Then Exit Function
     Set xmldoc = CreateObject("Msxml.DOMDocument"): xmldoc.async = False
     url_request = "http://www.cbr.ru/scripts/XML_daily.asp?date_req=" + Format(RateDate, "dd\/mm\/yyyy")

     If xmldoc.Load(url_request) <> True Then Exit Function    ' Запрос к серверу ЦБР

     ' Обработка полученного ответа
     Set nodeList = xmldoc.SelectNodes("ValCurs"): Set xmlNode = nodeList.Item(0).CloneNode(True)
     Set node_attr = xmlNode.Attributes(0): strDate = node_attr.Value
     Set nodeList = xmldoc.SelectNodes("*/Valute")
     For i = 0 To nodeList.Length - 1    ' поиск нужной валюты
         Set xmlNode = nodeList.Item(i).CloneNode(True)
         If xmlNode.ChildNodes(1).Text = CurrencyName Then
             CurrencyRate = CDbl(xmlNode.ChildNodes(4).Text)
             divisor = Val(xmlNode.ChildNodes(2).Text)
             GetRate = CurrencyRate / divisor
             Exit Function
         End If
     Next
End Function

Sub ПримерИспользованияФункции_GetRate()
     MsgBox "Сегодня курс доллара к рублю составил " & GetRate("USD", Now), vbInformation
     MsgBox "А вчера курс евро к рублю был равен " & GetRate("EUR", Now - 1), vbInformation
End Sub
[/vba]

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


Сообщение отредактировал forest1333 - Вторник, 14.10.2014, 01:16
 
Ответить
Сообщение
я правильно понял, что в пятницу ЦБ устанавливает курс, который вступает в силу с субботы и действует по понедельник включительно?


Да, именно так.

и по поводу праздников


Вот по поводу конкретных дат праздников ничего не могу сказать. Не проследил график работы ЦБ в этом вопросе.

Знаете, у меня есть модуль для цепляния курса валют с сайта ЦБ:

[vba]
Код
Sub ВывестиСегодняшниеКурсыВсехВалют()
     On Error Resume Next
     Set xmldoc = CreateObject("Msxml.DOMDocument"): xmldoc.async = False
     url_request = "http://www.cbr.ru/scripts/XML_daily.asp?date_req=" + Format(Now, "dd\/mm\/yyyy")
     If xmldoc.Load(url_request) <> True Then Exit Sub
     Set nodeList = xmldoc.SelectNodes("ValCurs"): Set xmlNode = nodeList.Item(0).CloneNode(True)
     Set node_attr = xmlNode.Attributes(0): strDate = node_attr.Value
     Set nodeList = xmldoc.SelectNodes("*/Valute")
     For i = 0 To nodeList.Length - 1
         Set xmlNode = nodeList.Item(i).CloneNode(True)
         Debug.Print "Курс " & xmlNode.ChildNodes(1).Text & " (установлен " & strDate & "): " & _
                     xmlNode.ChildNodes(4).Text & " рублей за " & xmlNode.ChildNodes(2).Text & _
                   " " & xmlNode.ChildNodes(3).Text
     Next
End Sub

Function GetRate(ByVal CurrencyName As String, ByVal RateDate As Date) As Single
     ' функция возвращает курс валюты CurrencyName на дату RateDate
     ' в случае ошибки (неверная дата или название валюты) возвращается 0
     On Error Resume Next
     CurrencyName = UCase(CurrencyName): If Len(CurrencyName) <> 3 Then Exit Function
     Set xmldoc = CreateObject("Msxml.DOMDocument"): xmldoc.async = False
     url_request = "http://www.cbr.ru/scripts/XML_daily.asp?date_req=" + Format(RateDate, "dd\/mm\/yyyy")

     If xmldoc.Load(url_request) <> True Then Exit Function    ' Запрос к серверу ЦБР

     ' Обработка полученного ответа
     Set nodeList = xmldoc.SelectNodes("ValCurs"): Set xmlNode = nodeList.Item(0).CloneNode(True)
     Set node_attr = xmlNode.Attributes(0): strDate = node_attr.Value
     Set nodeList = xmldoc.SelectNodes("*/Valute")
     For i = 0 To nodeList.Length - 1    ' поиск нужной валюты
         Set xmlNode = nodeList.Item(i).CloneNode(True)
         If xmlNode.ChildNodes(1).Text = CurrencyName Then
             CurrencyRate = CDbl(xmlNode.ChildNodes(4).Text)
             divisor = Val(xmlNode.ChildNodes(2).Text)
             GetRate = CurrencyRate / divisor
             Exit Function
         End If
     Next
End Function

Sub ПримерИспользованияФункции_GetRate()
     MsgBox "Сегодня курс доллара к рублю составил " & GetRate("USD", Now), vbInformation
     MsgBox "А вчера курс евро к рублю был равен " & GetRate("EUR", Now - 1), vbInformation
End Sub
[/vba]

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

Автор - forest1333
Дата добавления - 14.10.2014 в 01:16
krosav4ig Дата: Вторник, 14.10.2014, 03:08 | Сообщение № 10
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
ну с валютами все намного проще. ЦБ сам выдает действующий курс на запрашиваемую дату, а с металлами он этого делать не хочет :(
кстати вот переписанная мной функция, которая делает то же самое, что и GetRate, только в случае ошибки она возвращает #ЗНАЧ
[vba]
Код
Function ЦБР#(Optional Curr$, Optional dDate As Date)
     Dim d As Object, date_req$
     Set d = CreateObject("msxml.DOMDocument")
     If Not CBool(Len(Curr)) Then Curr = "USD"
     date_req = "?date_req=" & IIf(dDate, dDate, Date)
     d.async = 0: d.Load ("http://www.cbr.ru/scripts/XML_daily.asp" & date_req)
     With d.SelectSingleNode("*/Valute[CharCode='" & UCase(Curr) & "']")
         ЦБР = CDbl(.ChildNodes(4).Text) / Val(.ChildNodes(2).Text)
     End With
     Set d = Nothing
End Function
[/vba]
1 атрибут- буквенный код валюты, если не указан - по умолчанию "USD"
2 атрибут -дата (как в МетЦБР), если не указана - по умолчанию текущая системная дата

есть мысля по поводу исправления МетЦБР2, если после 14:00 мысля подтвердится, выложу исправленный код


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460

Сообщение отредактировал krosav4ig - Вторник, 14.10.2014, 03:29
 
Ответить
Сообщениену с валютами все намного проще. ЦБ сам выдает действующий курс на запрашиваемую дату, а с металлами он этого делать не хочет :(
кстати вот переписанная мной функция, которая делает то же самое, что и GetRate, только в случае ошибки она возвращает #ЗНАЧ
[vba]
Код
Function ЦБР#(Optional Curr$, Optional dDate As Date)
     Dim d As Object, date_req$
     Set d = CreateObject("msxml.DOMDocument")
     If Not CBool(Len(Curr)) Then Curr = "USD"
     date_req = "?date_req=" & IIf(dDate, dDate, Date)
     d.async = 0: d.Load ("http://www.cbr.ru/scripts/XML_daily.asp" & date_req)
     With d.SelectSingleNode("*/Valute[CharCode='" & UCase(Curr) & "']")
         ЦБР = CDbl(.ChildNodes(4).Text) / Val(.ChildNodes(2).Text)
     End With
     Set d = Nothing
End Function
[/vba]
1 атрибут- буквенный код валюты, если не указан - по умолчанию "USD"
2 атрибут -дата (как в МетЦБР), если не указана - по умолчанию текущая системная дата

есть мысля по поводу исправления МетЦБР2, если после 14:00 мысля подтвердится, выложу исправленный код

Автор - krosav4ig
Дата добавления - 14.10.2014 в 03:08
krosav4ig Дата: Вторник, 14.10.2014, 15:16 | Сообщение № 11
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
мысля подтвердилась, даю исправленную функцию[vba]
Код
Option Explicit
Private Declare Function DeleteUrlCacheEntry& Lib "wininet" (ByVal lpszUrlName$)
Function МетЦБР2#(code)
      Application.Volatile False
      Dim oHTML As HTMLDocument, oDoc As HTMLDocument, elem As HTMLBaseElement, url$, n%, str$, diff#:
      Set oHTML = New HTMLDocument
      url = "http://cbr.ru/"
      DeleteUrlCacheEntry (url)
      Set oDoc = oHTML.createDocumentFromUrl(url, "")
      Do
          DoEvents
      Loop Until oDoc.readyState = "complete"
      oHTML.body.innerHTML = oDoc.getElementById("widget_metal").innerHTML
      Set oDoc = Nothing
      n = InStr(1, "_auagptpg", LCase(code)) / 2 - 1 + Val(code)
      Set elem = oHTML.getElementsByTagName("span")(n)
      With oHTML.getElementsByTagName("i")
          If Not .Item(n + 1) Is Nothing Then diff = CDbl(.Item(n + 1).Title)
      End With
      МетЦБР2 = CDbl(elem.innerText) - diff
      'With Application.Caller
      '    If Not .Comment Is Nothing Then .Comment.Delete
      '    str = oHTML.getElementsByTagName("ins")(n).ParentNode.innerText
      '    str = str & CStr(CDate(Mid(Replace(oHTML.LastModified, "/", "/" & Left(oHTML.LastModified, 3)), 7, 10)))
      '    .AddComment str & Right(oHTML.LastModified, 9)
      'End With
      Set elem = Nothing
      Set oHTML = Nothing
End Function
[/vba]
Если при вычислении этой функции появляется окошко c предупреждением о безопасности, то нужно внести cbr.ru в доверенные узлы:
пуск->выполнить->Inetcpl.cpl->безопасность->надежные узлы->узлы->убрать галочку, ввести cbr.ru->добавить->закрыть->ОК
или
пуск->выполнить->Inetcpl.cpl->безопасность->местная интрасеть->узлы->дополнительно->убрать галочку, ввести cbr.ru->добавить->закрыть->ОК->ОК


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460

Сообщение отредактировал krosav4ig - Вторник, 14.10.2014, 15:38
 
Ответить
Сообщениемысля подтвердилась, даю исправленную функцию[vba]
Код
Option Explicit
Private Declare Function DeleteUrlCacheEntry& Lib "wininet" (ByVal lpszUrlName$)
Function МетЦБР2#(code)
      Application.Volatile False
      Dim oHTML As HTMLDocument, oDoc As HTMLDocument, elem As HTMLBaseElement, url$, n%, str$, diff#:
      Set oHTML = New HTMLDocument
      url = "http://cbr.ru/"
      DeleteUrlCacheEntry (url)
      Set oDoc = oHTML.createDocumentFromUrl(url, "")
      Do
          DoEvents
      Loop Until oDoc.readyState = "complete"
      oHTML.body.innerHTML = oDoc.getElementById("widget_metal").innerHTML
      Set oDoc = Nothing
      n = InStr(1, "_auagptpg", LCase(code)) / 2 - 1 + Val(code)
      Set elem = oHTML.getElementsByTagName("span")(n)
      With oHTML.getElementsByTagName("i")
          If Not .Item(n + 1) Is Nothing Then diff = CDbl(.Item(n + 1).Title)
      End With
      МетЦБР2 = CDbl(elem.innerText) - diff
      'With Application.Caller
      '    If Not .Comment Is Nothing Then .Comment.Delete
      '    str = oHTML.getElementsByTagName("ins")(n).ParentNode.innerText
      '    str = str & CStr(CDate(Mid(Replace(oHTML.LastModified, "/", "/" & Left(oHTML.LastModified, 3)), 7, 10)))
      '    .AddComment str & Right(oHTML.LastModified, 9)
      'End With
      Set elem = Nothing
      Set oHTML = Nothing
End Function
[/vba]
Если при вычислении этой функции появляется окошко c предупреждением о безопасности, то нужно внести cbr.ru в доверенные узлы:
пуск->выполнить->Inetcpl.cpl->безопасность->надежные узлы->узлы->убрать галочку, ввести cbr.ru->добавить->закрыть->ОК
или
пуск->выполнить->Inetcpl.cpl->безопасность->местная интрасеть->узлы->дополнительно->убрать галочку, ввести cbr.ru->добавить->закрыть->ОК->ОК

Автор - krosav4ig
Дата добавления - 14.10.2014 в 15:16
doober Дата: Вторник, 14.10.2014, 16:22 | Сообщение № 12
Группа: Друзья
Ранг: Ветеран
Сообщений: 947
Репутация: 323 ±
Замечаний: 0% ±

Excel 2010
Проверте мой вариант


 
Ответить
СообщениеПроверте мой вариант

Автор - doober
Дата добавления - 14.10.2014 в 16:22
krosav4ig Дата: Вторник, 14.10.2014, 17:52 | Сообщение № 13
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
doober, загвоздка в том, что и через soap запрос, и через xml_metall.asp цбр дает курс только в том случае, если есть курс, который вступает в силу в запрашиваемую дату. Т.е. в воскресенье и понедельник курс получить не получается
к примеру по ссылке http://www.cbr.ru/scripts....10.2014 возвращаются котировки, а по http://www.cbr.ru/scripts....10.2014 и http://www.cbr.ru/scripts....10.2014 -нет


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460
 
Ответить
Сообщениеdoober, загвоздка в том, что и через soap запрос, и через xml_metall.asp цбр дает курс только в том случае, если есть курс, который вступает в силу в запрашиваемую дату. Т.е. в воскресенье и понедельник курс получить не получается
к примеру по ссылке http://www.cbr.ru/scripts....10.2014 возвращаются котировки, а по http://www.cbr.ru/scripts....10.2014 и http://www.cbr.ru/scripts....10.2014 -нет

Автор - krosav4ig
Дата добавления - 14.10.2014 в 17:52
krosav4ig Дата: Вторник, 14.10.2014, 17:52 | Сообщение № 14
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
то же самое и с soap, у вас в функции DragMetDynamic("11.10.2014", 2) свойство xml.xml равно
а при дате = "12.10.2014" или "13.10.2014" xml.xml уже равен


ЗЫ.
[vba]
Код
    For Each x In XML.SelectNodes("//CodMet")
          If Val(x.Text) = Met Then
              DragMetDynamic = Val(x.ParentNode.ChildNodes(2).Text)
          End If
      Next
[/vba] можно заменить на

[vba]
Код
    DragMetDynamic = Val(XML.SelectSingleNode("//DrgMet[CodMet='" & Met & "']/price").Text)
[/vba]


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460

Сообщение отредактировал krosav4ig - Вторник, 14.10.2014, 17:54
 
Ответить
Сообщението же самое и с soap, у вас в функции DragMetDynamic("11.10.2014", 2) свойство xml.xml равно
а при дате = "12.10.2014" или "13.10.2014" xml.xml уже равен


ЗЫ.
[vba]
Код
    For Each x In XML.SelectNodes("//CodMet")
          If Val(x.Text) = Met Then
              DragMetDynamic = Val(x.ParentNode.ChildNodes(2).Text)
          End If
      Next
[/vba] можно заменить на

[vba]
Код
    DragMetDynamic = Val(XML.SelectSingleNode("//DrgMet[CodMet='" & Met & "']/price").Text)
[/vba]

Автор - krosav4ig
Дата добавления - 14.10.2014 в 17:52
krosav4ig Дата: Вторник, 14.10.2014, 18:56 | Сообщение № 15
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
переписал МетЦБР. Теперь работает как надо
[vba]
Код
Function МетЦБР#(Optional Code% = 2, Optional dDate As Date)
     Dim d As Object, ddate1 As Date: Set d = CreateObject("MSXML2.DOMDocument.4.0")
     dDate = IIf(dDate, dDate, Date): ddate1 = Application.EDate(dDate, -1): d.async = 0
     d.Load ("http://www.cbr.ru/scripts/xml_metall.asp?date_req1=" & ddate1 & "&date_req2=" & dDate)
     МетЦБР= CDbl(d.SelectSingleNode("*/Record[@Code='" & Code & "'][last()]/Buy").Text)
     Set d = Nothing
End Function
[/vba]


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460
 
Ответить
Сообщениепереписал МетЦБР. Теперь работает как надо
[vba]
Код
Function МетЦБР#(Optional Code% = 2, Optional dDate As Date)
     Dim d As Object, ddate1 As Date: Set d = CreateObject("MSXML2.DOMDocument.4.0")
     dDate = IIf(dDate, dDate, Date): ddate1 = Application.EDate(dDate, -1): d.async = 0
     d.Load ("http://www.cbr.ru/scripts/xml_metall.asp?date_req1=" & ddate1 & "&date_req2=" & dDate)
     МетЦБР= CDbl(d.SelectSingleNode("*/Record[@Code='" & Code & "'][last()]/Buy").Text)
     Set d = Nothing
End Function
[/vba]

Автор - krosav4ig
Дата добавления - 14.10.2014 в 18:56
forest1333 Дата: Среда, 15.10.2014, 19:08 | Сообщение № 16
Группа: Пользователи
Ранг: Прохожий
Сообщений: 9
Репутация: 0 ±
Замечаний: 0% ±

Excel 2010
переписал МетЦБР. Теперь работает как надо


Это окончательный вариант, который будет работать по выходным?
 
Ответить
Сообщение
переписал МетЦБР. Теперь работает как надо


Это окончательный вариант, который будет работать по выходным?

Автор - forest1333
Дата добавления - 15.10.2014 в 19:08
krosav4ig Дата: Среда, 15.10.2014, 19:40 | Сообщение № 17
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
Да, и по выходным, и по праздникам


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460
 
Ответить
СообщениеДа, и по выходным, и по праздникам

Автор - krosav4ig
Дата добавления - 15.10.2014 в 19:40
forest1333 Дата: Среда, 15.10.2014, 22:46 | Сообщение № 18
Группа: Пользователи
Ранг: Прохожий
Сообщений: 9
Репутация: 0 ±
Замечаний: 0% ±

Excel 2010
Да, и по выходным, и по праздникам

Отлично! Большое спасибо!
 
Ответить
Сообщение
Да, и по выходным, и по праздникам

Отлично! Большое спасибо!

Автор - forest1333
Дата добавления - 15.10.2014 в 22:46
IWI Дата: Понедельник, 15.02.2016, 01:08 | Сообщение № 19
Группа: Пользователи
Ранг: Новичок
Сообщений: 18
Репутация: 0 ±
Замечаний: 0% ±

Excel 2016
Народ, подскажите пожалуйста, почему не работает такой код по извлечению цены на золото? Или напишите рабочий вариант.
[vba]
Код
Sub GetZoloto()
Dim xmldoc, nodeList
On Error Resume Next
Set xmldoc = CreateObject("Msxml.DOMDocument"): xmldoc.async = False
    'страница выгрузки данных http://www.cbr.ru/scripts/xml_metall.asp?date_req1=12/02/2016&date_req2=12/02/2016
url_request = ("http://www.cbr.ru/scripts/xml_metall.asp?date_req1=" & _
    Format(InputBox("Введите начальную дату поиска в формате ДД.ММ.ГГГГ", "Курс Золота", Date), "dd\/mm\/yyyy") & _
     "&date_req2=" & _
    Format(InputBox("Введите конечную дату поиска в формате ДД.ММ.ГГГГ", "Курс Золота", Date), "dd\/mm\/yyyy"))
   If Not xmldoc.Load(url_request) Then Exit Sub
   Set nodeList = xmldoc.SelectNodes("*/Record[@Code='"1"'][last()]/Buy")
If nodeList.Length Then ActiveCell.Value = CDbl(nodeList.Item(0).ChildNodes(4).Text)
End Sub
[/vba]


Сообщение отредактировал IWI - Понедельник, 15.02.2016, 01:49
 
Ответить
СообщениеНарод, подскажите пожалуйста, почему не работает такой код по извлечению цены на золото? Или напишите рабочий вариант.
[vba]
Код
Sub GetZoloto()
Dim xmldoc, nodeList
On Error Resume Next
Set xmldoc = CreateObject("Msxml.DOMDocument"): xmldoc.async = False
    'страница выгрузки данных http://www.cbr.ru/scripts/xml_metall.asp?date_req1=12/02/2016&date_req2=12/02/2016
url_request = ("http://www.cbr.ru/scripts/xml_metall.asp?date_req1=" & _
    Format(InputBox("Введите начальную дату поиска в формате ДД.ММ.ГГГГ", "Курс Золота", Date), "dd\/mm\/yyyy") & _
     "&date_req2=" & _
    Format(InputBox("Введите конечную дату поиска в формате ДД.ММ.ГГГГ", "Курс Золота", Date), "dd\/mm\/yyyy"))
   If Not xmldoc.Load(url_request) Then Exit Sub
   Set nodeList = xmldoc.SelectNodes("*/Record[@Code='"1"'][last()]/Buy")
If nodeList.Length Then ActiveCell.Value = CDbl(nodeList.Item(0).ChildNodes(4).Text)
End Sub
[/vba]

Автор - IWI
Дата добавления - 15.02.2016 в 01:08
krosav4ig Дата: Понедельник, 15.02.2016, 10:33 | Сообщение № 20
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
ну дык
MSXML2.DOMDocument.4.0
и тут
"*/Record[@Code='"1"'][last()]/Buy"

кавычки лишние


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460
 
Ответить
Сообщениену дык
MSXML2.DOMDocument.4.0
и тут
"*/Record[@Code='"1"'][last()]/Buy"

кавычки лишние

Автор - krosav4ig
Дата добавления - 15.02.2016 в 10:33
Мир MS Excel » Вопросы и решения » Вопросы по VBA » Получение котировок на драгметаллы с сайта ЦБ РФ (Функции/Function)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!