Загрузка курсов валют с сайта НБРБ

Материал из GedeminWiki
(Различия между версиями)
Перейти к: навигация, поиск
м (Правки ChileTozel (обсуждение) откачены к версии SYSDBA)
Строка 1: Строка 1:
http://www.textcavarle.com
 
 
<pre>
 
<pre>
 
option explicit
 
option explicit
  
' системные требования: Windows XP SP1, Windows 2000 SP3
+
' системные требования: Windows XP SP1, Windows 2000 SP3
 
' Windows 2003 Server
 
' Windows 2003 Server
 
'
 
'
Строка 11: Строка 10:
 
   Set Creator = New TCreator
 
   Set Creator = New TCreator
  
   ' словарь CurrCode нужен нам для двух целей:
+
   ' словарь CurrCode нужен нам для двух целей:
   ' во-первых, в нем задается список валют, курсы
+
   ' во-первых, в нем задается список валют, курсы
   ' которых мы будем загружать с сайта
+
   ' которых мы будем загружать с сайта
   ' во-вторых, в нем мы устанавливаем соответствие
+
   ' во-вторых, в нем мы устанавливаем соответствие
   ' между кодом (буквенной аббревиатурой) валюты
+
   ' между кодом (буквенной аббревиатурой) валюты
   ' используемой на сайте (Key) и кодом валюты
+
   ' используемой на сайте (Key) и кодом валюты
   ' используемым в нашей базе данных (Item). Очевидно,
+
   ' используемым в нашей базе данных (Item). Очевидно,
   ' что они могут как совпадать, так и различаться
+
   ' что они могут как совпадать, так и различаться
   ' например, доллар США на сайте может обозначаться
+
   ' например, доллар США на сайте может обозначаться
   ' как USD, а у нас в базе он будет проходить как
+
   ' как USD, а у нас в базе он будет проходить как
   ' USD NBRB, что означает курс доллара США, установленный
+
   ' USD NBRB, что означает курс доллара США, установленный
   ' Национальным банком Республики Беларусь.
+
   ' Национальным банком Республики Беларусь.
   ' Обратите внимание, что коды валют могут меняться во времени
+
   ' Обратите внимание, что коды валют могут меняться во времени
   ' например в одно время сайт может вернуть курс польского злотого
+
   ' например в одно время сайт может вернуть курс польского злотого
   ' под кодом PLZ, а в другое -- PLN
+
   ' под кодом PLZ, а в другое -- PLN
   ' в таком случае, все коды одной и той же валюты, которые
+
   ' в таком случае, все коды одной и той же валюты, которые
   ' могут использоваться на сайте, должны быть перечислены
+
   ' могут использоваться на сайте, должны быть перечислены
   ' через запятую
+
   ' через запятую
 
   Dim CurrCode
 
   Dim CurrCode
 
   Set CurrCode = CreateObject("Scripting.Dictionary")
 
   Set CurrCode = CreateObject("Scripting.Dictionary")
Строка 40: Строка 39:
 
   CurrCode.Add "GBP", "GBP"
 
   CurrCode.Add "GBP", "GBP"
  
   ' идентификатор записи валюты, относительно которой
+
   ' идентификатор записи валюты, относительно которой
   ' задаются курсы валют на сайте
+
   ' задаются курсы валют на сайте
   ' в данном случае -- это наш родной белорусский рубль
+
   ' в данном случае -- это наш родной белорусский рубль
 
   Dim BaseCurrID
 
   Dim BaseCurrID
 
   BaseCurrID = gdcBaseManager.GetIDByRUIDString("200010_17")
 
   BaseCurrID = gdcBaseManager.GetIDByRUIDString("200010_17")
  
   ' даты: с какой и по какую загружать курсы валют с сайта
+
   ' даты: с какой и по какую загружать курсы валют с сайта
   ' по какую -- возьмем текущую системную дату
+
   ' по какую -- возьмем текущую системную дату
   ' с какой -- определим следующим образом: будем искать в нашей
+
   ' с какой -- определим следующим образом: будем искать в нашей
   ' базе для каждой из заданных валют самую последнюю
+
   ' базе для каждой из заданных валют самую последнюю
   ' дату курса. из всех найденных дат возьмем наиболее раньнюю.
+
   ' дату курса. из всех найденных дат возьмем наиболее раньнюю.
 
   Dim FromDate, ToDate
 
   Dim FromDate, ToDate
 
   ToDate = Date
 
   ToDate = Date
Строка 66: Строка 65:
 
   Tr.StartTransaction
 
   Tr.StartTransaction
  
   ' уберем коды валют которых нет нашей базе или
+
   ' уберем коды валют которых нет нашей базе или
   ' которые встречаются более одного раза
+
   ' которые встречаются более одного раза
 
   q.SQL.Text =_
 
   q.SQL.Text =_
 
     "SELECT COUNT(c.code) " &_
 
     "SELECT COUNT(c.code) " &_
Строка 96: Строка 95:
 
   Next
 
   Next
  
   ' проверим, может в базе уже есть все курсы
+
   ' проверим, может в базе уже есть все курсы
 
   if ToDate < FromDate then _
 
   if ToDate < FromDate then _
 
     exit sub
 
     exit sub
  
   ' если интервал слишком большой -- ограничим его
+
   ' если интервал слишком большой -- ограничим его
 
   if (ToDate - FromDate) > (365 * 1) then _
 
   if (ToDate - FromDate) > (365 * 1) then _
 
     FromDate = ToDate - 365 * 1
 
     FromDate = ToDate - 365 * 1
  
   ' подготовим запрос для вставки курса валюты
+
   ' подготовим запрос для вставки курса валюты
 
   q.SQL.Text = _
 
   q.SQL.Text = _
 
     "INSERT INTO gd_currrate (fromcurr, tocurr, fordate, coeff) " &_
 
     "INSERT INTO gd_currrate (fromcurr, tocurr, fordate, coeff) " &_
Строка 110: Строка 109:
 
   q.ParamByName("TC").AsInteger = BaseCurrID
 
   q.ParamByName("TC").AsInteger = BaseCurrID
  
   ' подготовим запрос для поиска курса валюты на указанную дату
+
   ' подготовим запрос для поиска курса валюты на указанную дату
 
   qFind.SQL.Text =_
 
   qFind.SQL.Text =_
 
     "SELECT * " &_
 
     "SELECT * " &_
Строка 121: Строка 120:
 
   Dim strURL
 
   Dim strURL
  
   ' если объект не удается создать (например, неподходящая
+
   ' если объект не удается создать (например, неподходящая
   ' версия Windows), то просто завершаем выполнение
+
   ' версия Windows), то просто завершаем выполнение
 
   On Error Resume Next
 
   On Error Resume Next
 
   Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
 
   Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
Строка 129: Строка 128:
 
   On Error GoTo 0
 
   On Error GoTo 0
  
   ' если используется прокси для выхода в интернет
+
   ' если используется прокси для выхода в интернет
   ' откоментируйте следующую строку и укажите адрес прокси
+
   ' откоментируйте следующую строку и укажите адрес прокси
   ' последний параметр, указывает адреса, к которым подключение
+
   ' последний параметр, указывает адреса, к которым подключение
   ' будет происходить минуя прокси
+
   ' будет происходить минуя прокси
 
   ' WinHttpReq.SetProxy 2, "proxy_server:80", "*.domain.com"
 
   ' WinHttpReq.SetProxy 2, "proxy_server:80", "*.domain.com"
  
Строка 159: Строка 158:
 
     'strUrl = "http://localhost/nbrb/ratesdaily.asp.htm"
 
     'strUrl = "http://localhost/nbrb/ratesdaily.asp.htm"
  
     ' в случае если сайт не доступен -- просто
+
     ' в случае если сайт не доступен -- просто
     ' заверши процедуру
+
     ' заверши процедуру
 
     On Error Resume Next
 
     On Error Resume Next
 
    
 
    
Строка 173: Строка 172:
  
 
     For Each I in CurrCode
 
     For Each I in CurrCode
       ' для каждой валюты проверим: нет ли в базе курса на
+
       ' для каждой валюты проверим: нет ли в базе курса на
       ' указанную дату. если есть, то пропускаем эту валюту
+
       ' указанную дату. если есть, то пропускаем эту валюту
 
       qFind.ParamByName("FC").AsString = CurrCode.Item(I)
 
       qFind.ParamByName("FC").AsString = CurrCode.Item(I)
 
       qFind.ExecQuery
 
       qFind.ExecQuery
Строка 200: Строка 199:
 
                 SS = Replace(SS, Chr(160), "")
 
                 SS = Replace(SS, Chr(160), "")
  
                 ' на сайте используется точка в качестве десятичного
+
                 ' на сайте используется точка в качестве десятичного
                 ' разделителя. Заменим ее на разделитель, использующийся в нашей
+
                 ' разделителя. Заменим ее на разделитель, использующийся в нашей
                 ' системе
+
                 ' системе
 
                 SS = Replace(SS, ".", Application.DecimalSeparatorSys)
 
                 SS = Replace(SS, ".", Application.DecimalSeparatorSys)
  
 
                 if SS > "" then
 
                 if SS > "" then
                   ' в случае если строку не удается перевести в число
+
                   ' в случае если строку не удается перевести в число
                   ' или возникнет ошибка при добавлении записи --
+
                   ' или возникнет ошибка при добавлении записи --
                   ' проигнорируем их
+
                   ' проигнорируем их
 
                   On Error Resume Next
 
                   On Error Resume Next
 
                  
 
                  
Строка 230: Строка 229:
 
   Next
 
   Next
  
   ' подтверждаем запись в базу данных, только если все прошло успешно
+
   ' подтверждаем запись в базу данных, только если все прошло успешно
   ' и не возникало ошибок
+
   ' и не возникало ошибок
 
   Tr.Commit
 
   Tr.Commit
  
 
end sub
 
end sub
 
</pre>
 
</pre>

Версия 12:24, 23 мая 2009

option explicit

' системные требования: Windows XP SP1, Windows 2000 SP3
' Windows 2003 Server
'
sub Curr_LoadRates

  Dim Creator
  Set Creator = New TCreator

  ' словарь CurrCode нужен нам для двух целей:
  ' во-первых, в нем задается список валют, курсы
  ' которых мы будем загружать с сайта
  ' во-вторых, в нем мы устанавливаем соответствие
  ' между кодом (буквенной аббревиатурой) валюты
  ' используемой на сайте (Key) и кодом валюты
  ' используемым в нашей базе данных (Item). Очевидно,
  ' что они могут как совпадать, так и различаться
  ' например, доллар США на сайте может обозначаться
  ' как USD, а у нас в базе он будет проходить как
  ' USD NBRB, что означает курс доллара США, установленный
  ' Национальным банком Республики Беларусь.
  ' Обратите внимание, что коды валют могут меняться во времени
  ' например в одно время сайт может вернуть курс польского злотого
  ' под кодом PLZ, а в другое -- PLN
  ' в таком случае, все коды одной и той же валюты, которые
  ' могут использоваться на сайте, должны быть перечислены
  ' через запятую
  Dim CurrCode
  Set CurrCode = CreateObject("Scripting.Dictionary")
  CurrCode.Add "USD", "USD"
  CurrCode.Add "EUR", "EUR"
  CurrCode.Add "RUB,RUR", "RUB"
  CurrCode.Add "PLN,PLZ", "PLN"
  CurrCode.Add "UAH", "UAH"
  CurrCode.Add "LTL", "LTL"
  CurrCode.Add "LVL", "LVL"
  CurrCode.Add "GBP", "GBP"

  ' идентификатор записи валюты, относительно которой
  ' задаются курсы валют на сайте
  ' в данном случае -- это наш родной белорусский рубль
  Dim BaseCurrID
  BaseCurrID = gdcBaseManager.GetIDByRUIDString("200010_17")

  ' даты: с какой и по какую загружать курсы валют с сайта
  ' по какую -- возьмем текущую системную дату
  ' с какой -- определим следующим образом: будем искать в нашей
  ' базе для каждой из заданных валют самую последнюю
  ' дату курса. из всех найденных дат возьмем наиболее раньнюю.
  Dim FromDate, ToDate
  ToDate = Date
  FromDate = ToDate

  Dim q, qFind, Tr
  Set Tr = Creator.GetObject(Application, "TIBTransaction", "")
  Set q = Creator.GetObject(Application, "TIBSQL", "")
  Set qFind = Creator.GetObject(Application, "TIBSQL", "")

  Set Tr.DefaultDatabase = gdcBaseManager.Database
  Set q.Transaction = Tr
  Set qFind.Transaction = Tr

  Tr.StartTransaction

  ' уберем коды валют которых нет нашей базе или
  ' которые встречаются более одного раза
  q.SQL.Text =_
    "SELECT COUNT(c.code) " &_
    "FROM gd_curr c  " &_
    "WHERE c.code = :C "

  Dim I
  For Each I in CurrCode
    q.ParamByName("C").AsString = CurrCode.Item(I)
    q.ExecQuery
    if q.Fields(0).AsInteger <> 1 then _
      CurrCode.Remove(I)
    q.Close
  Next

  q.SQL.Text =_
    "SELECT MAX(r.fordate) " &_
    "FROM gd_currrate r JOIN gd_curr c ON r.fromcurr = c.id " &_
    "WHERE c.code = :FC and r.tocurr = :TC"
  q.ParamByName("TC").AsInteger = BaseCurrID

  For Each I in CurrCode
    q.ParamByName("FC").AsString = CurrCode.Item(I)
    q.ExecQuery
    if Int(q.Fields(0).AsDateTime) < FromDate then _
      FromDate = Int(q.Fields(0).AsDateTime)
    q.Close
  Next

  ' проверим, может в базе уже есть все курсы
  if ToDate < FromDate then _
    exit sub

  ' если интервал слишком большой -- ограничим его
  if (ToDate - FromDate) > (365 * 1) then _
    FromDate = ToDate - 365 * 1

  ' подготовим запрос для вставки курса валюты
  q.SQL.Text = _
    "INSERT INTO gd_currrate (fromcurr, tocurr, fordate, coeff) " &_
    "SELECT ID, :TC, :FD, :R FROM gd_curr WHERE code = :FC "
  q.ParamByName("TC").AsInteger = BaseCurrID

  ' подготовим запрос для поиска курса валюты на указанную дату
  qFind.SQL.Text =_
    "SELECT * " &_
    "FROM gd_currrate r JOIN gd_curr c ON r.fromcurr = c.id " &_
    "WHERE c.code = :FC and r.tocurr = :TC AND r.fordate = :FD"
  qFind.ParamByName("TC").AsInteger = BaseCurrID
  
  Dim strResult
  Dim WinHttpReq
  Dim strURL

  ' если объект не удается создать (например, неподходящая
  ' версия Windows), то просто завершаем выполнение
  On Error Resume Next
  Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
  if Err.Number <> 0 then _
    Exit Sub
  On Error GoTo 0

  ' если используется прокси для выхода в интернет
  ' откоментируйте следующую строку и укажите адрес прокси
  ' последний параметр, указывает адреса, к которым подключение
  ' будет происходить минуя прокси
  ' WinHttpReq.SetProxy 2, "proxy_server:80", "*.domain.com"

  Dim D, K, J, E, SS, Mo, Da, Arr, A
  For D = FromDate to ToDate Step 1
    qFind.Close
    qFind.ParamByName("FD").AsDateTime = D

    q.ParamByName("FD").AsDateTime = D
   
    if Month(D) < 10 then
      Mo = "0" & Month(D)
    else
      Mo = Month(D)
    end if

    if Day(D) < 10 then
      Da = "0" & Day(D)
    else
      Da = Day(D)
    end if

    strURL = "http://www.nbrb.by/statistics/rates/RatesDaily.asp?fromDate=" &_
      Year(D) & "-" & Mo & "-" & Da
    
    'strUrl = "http://localhost/nbrb/ratesdaily.asp.htm"

    ' в случае если сайт не доступен -- просто
    ' заверши процедуру
    On Error Resume Next
   
    WinHttpReq.Open "GET", strURL, false
    WinHttpReq.Send
    strResult = WinHttpReq.ResponseText
    
    if Err.Number <> 0 then _
      Exit Sub
    
    On Error GoTo 0

    For Each I in CurrCode
      ' для каждой валюты проверим: нет ли в базе курса на
      ' указанную дату. если есть, то пропускаем эту валюту
      qFind.ParamByName("FC").AsString = CurrCode.Item(I)
      qFind.ExecQuery
      
      if qFind.EOF then
        Arr = Split(I, ",")
      
        For Each A in Arr
          K = InStr(strResult, ">" & A & "</td>")
          
          if K > 0 then
            For J = 1 to 4
              K = InStr(K + 1, strResult, ">")
              if K = 0 then _
                Exit For
            Next
            
            if K > 0 then
              K = K + 1
              E = InStr(K, strResult, "<")

              if E > 0 then
                SS = Replace(Mid(strResult, K, E - K), " ", "")
                SS = Replace(SS, " ", "")
                SS = Replace(SS, Chr(160), "")

                ' на сайте используется точка в качестве десятичного
                ' разделителя. Заменим ее на разделитель, использующийся в нашей
                ' системе
                SS = Replace(SS, ".", Application.DecimalSeparatorSys)

                if SS > "" then
                  ' в случае если строку не удается перевести в число
                  ' или возникнет ошибка при добавлении записи --
                  ' проигнорируем их
                  On Error Resume Next
                
                  q.ParamByName("R").AsCurrency = CCur(SS)
                  q.ParamByName("FC").AsString = CurrCode.Item(I)
                  
                  if Err.Number = 0 then _
                    q.ExecQuery
                  
                  On Error GoTo 0
                end if
              end if
            end if
          end if
        Next
      end if

      qFind.Close
    Next

  Next

  ' подтверждаем запись в базу данных, только если все прошло успешно
  ' и не возникало ошибок
  Tr.Commit

end sub
Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты