There are many services around offering the currency rates for free.
If your goal is to get/convert the rates with an UDF, then consider caching the rates to avoid being kicked off by the service due to too many requests.
Here's an UDF using caching to efficiently convert a currency with the rates from the European Central Bank (daily updated):
''
' UDF to convert a currency using the daily updated rates fron the European Central Bank '
' =ConvCurrency(1, "USD", "GBP") '
''
Public Function ConvCurrency(Value, fromSymbol As String, toSymbol As String)
Static rates As Collection, expiration As Date ' cached / keeps the value between calls '
If DateTime.Now > expiration Then
Dim xhr As Object, node As Object
expiration = DateTime.Now + DateTime.TimeSerial(1, 0, 0) ' + 1 hour '
Set rates = New Collection
rates.Add 1#, "EUR"
Set xhr = CreateObject("Msxml2.ServerXMLHTTP.6.0")
xhr.Open "GET", "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml", False
xhr.Send
For Each node In xhr.responseXML.SelectNodes("//*[@rate]")
rates.Add Conversion.Val(node.GetAttribute("rate")), node.GetAttribute("currency")
Next
End If
ConvCurrency = (Value / rates(fromSymbol)) * rates(toSymbol)
End Function
If you prefer the mid-market live rates, this example takes the rates from www.freeforexapi.com
''
' UDF to convert a currency using the mid-market live rates from www.freeforexapi.com '
' =ConvCurrency(1, "USD", "GBP") '
''
Public Function ConvCurrency(Value, fromSymbol As String, toSymbol As String)
Static rates As Collection, expiration As Date ' cached / keeps the value between calls '
Const SYMBOLS = "AED,AFN,ALL,AMD,ANG,AOA,ARS,ATS,AUD,AWG,AZM,AZN,BAM,BBD,BDT,BEF,BGN,BHD,BIF,BMD,BND,BOB,BRL,BSD,BTN,BWP,BYN,BYR,BZD,CAD,CDF,CHF,CLP,CNH,CNY,COP,CRC,CUC,CUP,CVE,CYP,CZK,DEM,DJF,DKK,DOP,DZD,EEK,EGP,ERN,ESP,ETB,EUR,FIM,FJD,FKP,FRF,GBP,GEL,GGP,GHC,GHS,GIP,GMD,GNF,GRD,GTQ,GYD,HKD,HNL,HRK,HTG,HUF,IDR,IEP,ILS,IMP,INR,IQD,IRR,ISK,ITL,JEP,JMD,JOD,JPY,KES,KGS,KHR,KMF,KPW,KRW,KWD,KYD,KZT,LAK,LBP,LKR,LRD,LSL,LTL,LUF,LVL,LYD,MAD,MDL,MGA,MGF,MKD,MMK,MNT,MOP,MRO,MRU,MTL,MUR,MVR,MWK,MXN,MYR,MZM,MZN,NAD,NGN,NIO,NLG,NOK,NPR,NZD,OMR,PAB,PEN,PGK,PHP,PKR,PLN,PTE,PYG,QAR,ROL,RON,RSD,RUB,RWF,SAR,SBD,SCR,SDD,SDG,SEK,SGD,SHP,SIT,SKK,SLL,SOS,SPL,SRD,SRG,STD,STN,SVC,SYP,SZL,THB,TJS,TMM,TMT,TND,TOP,TRL,TRY,TTD,TVD,TWD,TZS,UAH,UGX,USD,UYU,UZS,VAL,VEB,VEF,VES,VND,VUV,WST,XAF,XAG,XAU,XBT,XCD,XDR,XOF,XPD,XPF,XPT,YER,ZAR,ZMK,ZMW,ZWD"
If DateTime.Now > expiration Then
Dim xhr As Object, re As Object, match As Object
expiration = DateTime.Now + DateTime.TimeSerial(0, 1, 0) ' + 1 minute '
Set rates = New Collection
Set xhr = CreateObject("Msxml2.ServerXMLHTTP.6.0")
xhr.Open "GET", "https://www.freeforexapi.com/api/live?pairs=USD" & Replace(SYMBOLS, ",", ",USD"), False
xhr.Send
Set re = CreateObject("VBScript.RegExp")
re.Global = True
re.Pattern = """USD([A-Z]{3})"".*?""rate"":([\d.]+)"
For Each match In re.Execute(xhr.responseText)
rates.Add Conversion.Val(match.SubMatches.Item(1)), match.SubMatches.Item(0)
Next
End If
ConvCurrency = (Value / rates(fromSymbol)) * rates(toSymbol)
End Function