Avatar billede per2edb Ekspert
18. juli 2023 - 20:01 Der er 15 kommentarer og
2 løsninger

Udtræk automatisk daglige valutakurser fra Nationalbanken

Allerede i 2014 arbejdede jeg med dette emne her
Det virkede op til nu hvor mit internet er blevet sat til fast IP adresse
Nu virker  det ikke mere
Kan i hjælpe

Const url ="https://www.nationalbanken.dk/_vti_bin/DN/DataService.svc/CurrencyRatesXML?lang=da"

    Dim newValues, fldVArr, I, Valuta As String, Kurs As Single, ValutaId As Long

    newValues = Split(csvvaluesOfXML(url), vbCrLf)  ' <==== Se nedenfor
    If Not IsEmpty(newValues) Then
       
        For I = 1 To UBound(newValues) - 1
            fldVArr = Split(newValues(I), ",")
            Valuta = fldVArr(0)
            'Navn = fldVArr(1)
            Kurs = Replace(fldVArr(2), ".", ",")
            Select Case Valuta
              Case "USD", "EUR", "GBP", "CNY", "JPY", "SEK", "NOK", "CHF", "HKD", "PLN"
                    ValutaId = Nz(DLookup("ValutaId", "Valuta", "Valuta = '" & Valuta & "'"), 0)
                    If ValutaId > 0 Then
                      CurrentDb.Execute "UPDATE Valuta SET Kurs='" & Kurs & "' WHERE ValutaId =" & Nz(ValutaId, 0) & ";"
                    End If
            End Select
        Next
       
    End If


Function csvvaluesOfXML(url)
    'MSXML2.DOMDocument60
    Dim domIn As DOMDocument60, domStylesheet As DOMDocument60
    Set domIn = New DOMDocument60
    If domIn.loadXML(xmlresponseText(url)) Then  '<= Se nedenfor
        Set domStylesheet = New DOMDocument60
        If domStylesheet.loadXML(blob2string(1)) Then
            csvvaluesOfXML = domIn.transformNode(domStylesheet)
        Else
          xmlParsedError domStylesheet: End If
    Else
        xmlParsedError domIn: End If
    Set domStylesheet = Nothing
    Set domIn = Nothing
End Function

Function xmlresponseText(url, Optional method = "GET")
    Dim xhr
    Set xhr = CreateObject("Microsoft.XMLHTTP")
    xhr.Open method, url, False
    xhr.Send
    If xhr.Status = 200 Then
        xmlresponseText = byteArr2string(xhr.responseBody)  ' <==Se nedenfor
    Else
        Err.Raise 10000, , "network or site server error"  '<==  Går til fejl HER
End If
    Set xhr = Nothing
End Function

Function byteArr2string(bArr, Optional charset = "iso-8859-1")
    With New ADODB.Stream
            .Type = adTypeBinary
            .Open
            .Write bArr
            .Position = 0
            .Type = adTypeText
            .charset = charset
            byteArr2string = .ReadText
    End With
End Function
Avatar billede Gustav Ekspert
18. juli 2023 - 22:48 #1
Det burde ikke have noget med din IP-adresse at gøre, så jeg kan ikke sige, hvad der mon går galt.
Men du kan bruge min funktion CurrencyConvertDkk. For meget kode at poste her, men den er frit tilgængelig på GitHub:

https://github.com/GustavBrock/VBA.CurrencyExchange
Avatar billede per2edb Ekspert
19. juli 2023 - 08:54 #2
Hej Gustav
Tak for forslaget men jeg forstår det ikke helt.

1. Hvordan hentes f.eks valutakursen på USD?  CurrencyConvertDkk("USD")
2 DanishKroneCode er ikke defineret
3. Kilden http://www.nationalbanken.dk/  Hvor kommer den ind ????????

Public Function CurrencyConvertDkk( _
    ByVal IsoTo As String, _
    Optional ByVal IsoFrom As String = DanishKroneCode) _
    As Double
   
    Dim Rates()    As Variant
   
    Dim RateTo      As Double
    Dim RateFrom    As Double
    Dim Factor      As Double
    Dim Index      As Integer
   
    If IsoFrom = "" Then
        IsoFrom = DanishKroneCode
    End If
    If IsoTo = "" Then
        IsoTo = DanishKroneCode
    End If
   
    If IsoTo = NeutralCode Or IsoFrom = NeutralCode Then
        Factor = NeutralRate
    ElseIf IsoTo = IsoFrom Then
        Factor = NeutralRate
    Else
        Rates() = ExchangeRatesDkk
   
        If IsoTo = DanishKroneCode Then
            RateTo = NeutralRate
        Else
            For Index = LBound(Rates) To UBound(Rates)
                If Rates(Index, RateDetail.Code) = IsoTo Then
                    RateTo = Rates(Index, RateDetail.Rate)
                    Exit For
                End If
            Next
        End If
       
        If RateTo > NoRate Then
            If IsoFrom = DanishKroneCode Then
                RateFrom = NeutralRate
            Else
                For Index = LBound(Rates) To UBound(Rates)
                    If Rates(Index, RateDetail.Code) = IsoFrom Then
                        RateFrom = Rates(Index, RateDetail.Rate)
                        Exit For
                    End If
                Next
            End If
            Factor = RateFrom / RateTo
        End If
       
    End If
   
    CurrencyConvertDkk = Factor

End Function
Avatar billede Gustav Ekspert
19. juli 2023 - 09:21 #3
1. Du har behændigt udeladt in-line dokumentationen med alle de fine eksempler:
' Returns the current conversion factor from Danish Krone to another currency
' based on the official exchange rates published by the Danish National Bank.
'
' Optionally, the conversion factor can be calculated from any other of the
' published exchange rates. Exchange rates for other base currencies are
' calculated from DKK by triangular calculation.
'
' Source:
http://www.nationalbanken.dk/en/statistics/exchange_rates/Pages/default.aspx
'
' If an invalid or unpublished currency code is passed, a conversion factor
' of zero is returned.
'
' Examples, typical:
'  CurrencyConvertDkk("EUR")          ->  0.134062634062634
'  CurrencyConvertDkk("EUR", "DKK")    ->  0.134062634062634
'  CurrencyConvertDkk("AUD")          ->  0.21661901048436
'  CurrencyConvertDkk("AUD", "DKK")    ->  0.21661901048436
'  CurrencyConvertDkk("DKK", "AUD")    ->  4.6164
'  CurrencyConvertDkk("DKK", "EUR")    ->  7.4592
'  CurrencyConvertDkk("AUD", "EUR")    ->  1.61580452300494

'  CurrencyConvertDkk("", "EUR")      ->  7.4592
'  CurrencyConvertDkk("DKK")          ->  1
' Examples, neutral code.
'  CurrencyConvertDkk("AUD", "XXX")    ->  1
'  CurrencyConvertDkk("XXX", "AUD")    ->  1
'  CurrencyConvertDkk("XXX")          ->  1
' Examples, invalid code.
'  CurrencyConvertDkk("XYZ")          ->  0
'  CurrencyConvertDkk("EUR", "XYZ")    ->  0
'
' 2018-09-24. Gustav Brock, Cactus Data ApS, CPH.
'

Bemærk, at det er funktionen ExchangeRateDkk, der gør det "hårde" arbejde. Hvis du skal bruge flere kurser, kan du hente dem i én omgang fra den array, funktionen returnerer:
' Retrieve the current exchange rates from the National Bank of Denmark
' having DKK as the base currency.
' The rates are returned as an array and cached until the next update.
' The rates are updated once a day at about UTC 15:00.
'
' Source:
http://www.nationalbanken.dk/en/statistics/exchange_rates/Pages/default.aspx
'
' Note:
'  The exchange rates on Danmarks Nationalbank's website are indicative rates
'  that are not intended to be used in any market transaction.
'  The rates are intended for information purposes only.
'
' Defaults to English currency names.
' Optionally, setting parameter LanguageCode to "da", Danish names are retrieved.
'
' Example:
'  Dim Rates As Variant
'  Rates = ExchangeRatesDkk()
'  Rates(7, 0) -> 2018-05-30  ' Publishing date.
'  Rates(7, 1) -> "EUR"        ' Currency code.
'  Rates(7, 2) -> 7.4432      ' Exchange rate.
'  Rates(7, 3) -> "Euro"      ' Currency name, English or Danish.
'
' 2018-10-09. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function ExchangeRatesDkk( _
    Optional ByVal LanguageCode As String) _
    As Variant

2. Det er en af de definerede konstanter:
' Application constants.
'
' Currency code for Danish krone.
Public Const DanishKroneCode    As String = "DKK"
' Currency code for Euro.
Public Const EuroCode          As String = "EUR"
' Currency code for US Dollar.
Public Const USDollarCode      As String = "USD"
' Currency code for Rusian currency.
Public Const RubelCode          As String = "RUB"
' Currency code for Macedonian currency.
Public Const MKDenarCode        As String = "MKD"
' Currency code for neutral currency.
Public Const NeutralCode        As String = "XXX"
' Currency name for neutral currency.
Public Const NeutralName        As String = "No currency"
' Exchange rate for no currency.
Public Const NeutralRate        As Double = 1
' Currency code for no (invalid) currency.
Public Const NoCode            As String = ""
' Exchange rate for no (invalid) currency.
Public Const NoRate            As Double = 0
' Publishing/value date when unknown.
Public Const NoValueDate        As Date = #1/1/1970#

3. Det er baggrundsviden for den nysgerrige, der vil vide mere om, hvordan Danmarks Nationalbank håndterer valutakurser. Du kan kalde det serviceinformation.
Avatar billede per2edb Ekspert
19. juli 2023 - 09:55 #4
Jeg er helt lost

Nu har jeg tilføjet:
Public Const DanishKroneCode    As String = "DKK"
Det er ok

Men nu er disse ikke defineret:
NeutralCode og  NeutralRate
Avatar billede Gustav Ekspert
19. juli 2023 - 10:16 #5
Helt lost kan du nu ikke være, for de står lige ovenfor - sammen med DanishKroneCode, som du har fundet.

Måske er det nemmere at indsætte hele modulet. Så virker det.
Siden kan du eventuelt fjerne de funktioner, du ikke vil bruge.
Avatar billede per2edb Ekspert
19. juli 2023 - 10:57 #6
Jeg er gået total vild på siderne
Jeg har simpelheld ikke fået fat i den rigtige funktion
Det skal være vba 32 bit

Kan du sende et link eller en copy af funktionen
Avatar billede Gustav Ekspert
19. juli 2023 - 11:21 #7
Hovedlink:
https://github.com/GustavBrock/VBA.CurrencyExchange/

Hovedmodulet er ExchangeService.bas
Der er også en demo i mappen Demos.

Bemærk, at nogle af funktionerne (men ikke Dkk) bruger Json og dermed (som nævnt og linket til på forsiden) Json- modulerne fra:
https://github.com/CactusData/VBA.CVRAPI

Alt fungerer umiddelbart i Access 32-bit.
Avatar billede per2edb Ekspert
19. juli 2023 - 11:30 #8
Det må jeg opgive
Det går langt over hvad jeg kan finde ud af
Avatar billede Gustav Ekspert
19. juli 2023 - 11:49 #9
Mon dog.
Du kan hente demoen og umiddelbart skrive som test:
? CurrencyConvertDkk("USD", "DKK")
0,151055120013293
? CurrencyConvertDkk("DKK", "USD")
6,6201
Avatar billede per2edb Ekspert
19. juli 2023 - 12:11 #10
Skal tabellen og alle 7 moduler implementeres i min App
Avatar billede Gustav Ekspert
19. juli 2023 - 12:45 #11
Nej, tabellen er kun til test og til, hvis alle kurser skal gemmes. De fleste vil have deres  eget setup eller måske kun ønske at bruge én valuta.

Hvis du kun skal brug Dkk-funktionerne kan de fleste andre moduler udelades.

Den nemmeste metode til at finde ud af sådan noget er at kopiere og slette de funktioner, man ikke skal bruge én for én og kompilere hver gang. Vil koden ikke kompilere, sættes funktionen tilbage.
Dernæst kan samme metode bruges for de moduler, man mener ikke længere er nødvendige.
Avatar billede claes57 Ekspert
19. juli 2023 - 15:16 #12
jeg lavede for mange år siden en simpel valutaomregner
kører på https://1656kbh.dk/Kr

---
php-koden der er grundlagt, der henter data fra nb er her:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=ISO-8859-1">
  <title></title>
<link type="text/css" href="/templates/BasicLeftMenu/basic.css" rel="stylesheet">
</head>
  <body>
<div id="valuta" align="center">
<script type="text/javascript" language="javascript">
  var browserID = "n";
  if (navigator.appName.indexOf("Microsoft")>=0){browserID="i";}
 
  function tusindtalsseparator(tal){
    temp = parseInt(tal) + "";
    if (temp >= 999 && temp.length <= 6){
      nyttal = temp.slice(0, temp.length - 3) + "." + temp.slice(temp.length - 3, temp.length);
      return nyttal;
    } else if (temp.length > 6){
      nyttal = temp.slice(0, temp.length - 6) + "." + temp.slice(temp.length - 6, temp.length - 3) + "." + temp.slice(temp.length - 3, temp.length);
      return nyttal;
    } else {
      return temp;
    }
  }

  function fixtal(){
    if (browserID=="n"){
    frm = document.getElementById("frm");
    frav = document.getElementById("frav");
    }
    frav.value = tusindtalsseparator('' + frm.frav.value.replace( /\./g,'' ));
  }

  function regn(){
    if (browserID=="n"){
    frm = document.getElementById("frm");
    tilv = document.getElementById("tilv");
    frav = document.getElementById("frav");
    }
    var fratal = parseInt('' + frm.frav.value.replace( /\./g,'' ));
    tilv.innerHTML = tusindtalsseparator((fratal / frm.til.value) * frm.fra.value);
  }
</script>
<form method="POST" id="frm" style="display:inline;">

<?php
//----------------------
$xml = new SimpleXmlIterator('http://www.nationalbanken.dk/_vti_bin/DN/DataService.svc/CurrencyRatesXML?lang=da', null, true);
// find dato i xml
$element = $xml->xpath('dailyrates/@id');
$dato = date("d.m.Y", strtotime($element[0]));
$kode = '<table border="0" cellpadding="2" cellspacing="2">'."\n";
$kode .= '<tr><td colspan="4"><img src="images/dk.gif" width="18" height="12" /> Nationalbanken  '.$dato.'<hr></td></tr>'."\n";
$kurser = '<option value="100">DKK</option>'."\n";

// find kurser
$lande = array("EUR","USD","CAD","GBP","SEK","THB");
foreach ($lande as $land) {
    $element = $xml->xpath("dailyrates/currency[@code='$land']/@desc");
    $desc = $element[0]->desc;
    $element = $xml->xpath("dailyrates/currency[@code='$land']/@rate");
    $rate = $element[0]->rate;
    $kurs = str_replace(',','.',str_replace('.','',$rate));
    $kurser .= '<option value="'.$kurs.'">'.$land.'</option>'."\n";
    $kode .= '<tr><td><img src="images/'.strtolower($land).'.gif" width="18" height="12" />&#160;'.$land.'</td><td>'.$desc.'</td><td align="right" colspan="2">'.$rate.'</td></tr>'."\n";
}

echo $kode;
echo '<tr><td colspan="4"><hr></td></tr>';
echo '<tr><td>&#160;</td>';
echo '<td align="right" colspan="2">fra&#160;<input type="text" id="frav" value="" size="10" class="texte" style="text-align:right;" tabindex="1" onblur="fixtal();"></td>';
echo '<td><select name="fra" tabindex="2">'.$kurser.'</select></td></tr>';
echo '<tr><td>&#160;</td>';
echo '<td align="right"><input type="button" onclick="regn();" value="omregn" tabindex="4">&#160;til</td>';
echo '<td id="tilv" style="text-align:right;" width="80">&#160;</td><td><select name="til" tabindex="3">'.$kurser.'</select></td></tr>';
echo '</table></form>';
?>

  </body>
</html>
Avatar billede per2edb Ekspert
19. juli 2023 - 15:17 #13
Mange tak - Det virker

Nu er der kun en lille fejl:

Public Function UtcNow() As Date
    Dim SysTime    As SystemTime      <=========  FEJLER HER
    Dim Datetime    As Date
    ' Retrieve current UTC date/time.
    GetSystemTime SysTime
    Datetime = _
        DateSerial(SysTime.wYear, SysTime.wMonth, SysTime.wDay) + _
        TimeSerial(SysTime.wHour, SysTime.wMinute, SysTime.wSecond)
    UtcNow = Datetime
End Function
Avatar billede Gustav Ekspert
19. juli 2023 - 15:33 #14
Den ligger i toppen af modulet ZoneUtil.bas
Avatar billede per2edb Ekspert
20. juli 2023 - 09:01 #15
Hej Gustav
Det virker perfekt
Det har været en stor hjælp - TAK

Det vil måske hjælpe andre (tungnemme)  med et resume:
1 Start med at downloade Demoen som beskrevet ovenfor
2 Overfør funktionen CurrencyConvertDkk til din egen App
3 I din App kald f.eks CurrencyConvertDkk("DKK", "USD")
4  compile og der vises der mangler funktioner.
5 disse funktioner hentes over i din App fra Demoen

Sådan bliver du ved indtil compile går glat igennem
Avatar billede Gustav Ekspert
20. juli 2023 - 09:28 #16
Godt at høre. God sommer!
Avatar billede per2edb Ekspert
20. juli 2023 - 09:47 #17
I lige måde
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester