Folgende Dinge sind vorgegeben :
Auftragsbearbeitungprog.
1. Es müssen beliebig viele Währungen miteinander verarbeitet werden können.
(d.h. mal eine Rechnung in Euro, mal in DM, mal in US$ etc)
2. Kreditlimit und jegliche Auswertungen müssen in einer(!) Währung(die der
Benutzer sich aber jederzeit aussuchen kann!!!!) ausgegeben werden können.
Habe zwar eine Lösung (s.u.), doch dauert diese u.U. zu lange, ist ja auch
kein Wunder, da jedesmal für jede Zahl, die Umrechnungsfunktion durchlaufen
wird....
Also meine bisherige Lösung ist folgende :
Es gibt eine Kursumrechnungstabelle, die der Kunde beliebig ausfüllen kann :
FELDER : Datum, Währungscode (String*5), Kurs (currency)
Datum+Währungscode=PRIMÄRSCHLÜSSEL (kein ja für keine Währung an einem Tag
zwei Kurse geben)
Es gibt dann eine Abfrage, nennen wir Sie einfach mal Erlöse gibst die
Felder:
[Datum], [NettoErlöse] und [Währung], diese sind mit den jeweiligen
RgBeträgen gefüllt, jedoch in beliebigen Währungen
z.B.
01.01.98 100,00 DM
03.01.98 200,00 Euro
....
So nun habe ich ein berechnetes Feld in die Abfrage hinzugefügt mit folgedem
Inhalt:
Betrag_in_Standardwährung=[nettoErlöse]*findumfaktor([Währung];[Datum])
HIER DAZU DIE FUNKTION :
----------------------------------------------------------------------------
--------------------------
Public Function FindUmFaktor(Optional Wcode, Optional Tag) As Currency
If Wcode = StandardWährung_Mandant Then
FindUmFaktor = 1
Exit Function
End If
On Error GoTo fehler_FindUmFak
Dim datenbank As Database, DSGruppe As Recordset, DSAbfrage As String,
DSAbfrage2 As String
DSAbfrage = "SELECT Kursumrechnungen.Datum, Kursumrechnungen.Währungscode,
Kursumrechnungen.Kurs, Abs(Datediff(""d"",""" & Format$([Tag], "dd/mm/yyyy")
& """,Format$([Datum],""dd/mm/yyyy""))) AS Differenz FROM Kursumrechnungen
WHERE [Währungscode]=""" & Wcode & """ ORDER By Abs(Datediff(""d"",""" &
Format$([Tag], "dd/mm/yyyy") & """,Format$([Datum],""dd/mm/yyyy"")))"
Set datenbank = CurrentDb
Set DSGruppe = datenbank.OpenRecordset(DSAbfrage)
DSGruppe.MoveFirst
FindUmFaktor = DSGruppe![Kurs]
datenbank.Close
Exit Function
fehler_FindUmFak:
datenbank.Close
FindUmFaktor = 1
Exit Function
End Function
----------------------------------------------------------------------------
--------------------------
Hinweis : Es muß hierbei nicht jeden Tag unbedingt ein Kurs für die
jeweilige Währung erfaßt werden, die Funktion sucht sich halt den jeweils am
dichtesten Tag selber raus.
Das sollte auch nicht geändert werden. Einige Kunden geben halt täglich den
Kurs ein, anderen reicht es einen monatlichen Kurs zu erfassen.
Der Knackpunkt liegt in der Abfrage, die, scheint mir, ist wohl zu komplex
(bzw. zu langsam).
Habe schon daran gedacht, daß die Funktion das Ergebnis dauerhaft in einen
Datensatz einträgt, und nur noch so die fehlenden jedesmal berechnet werden
brauchen. Ändert man aber nachträglich den Kurs oder ändert die
Standardwährung müsste es ja eh neu berechnet werden...
Weiß jemand eine bessere Lösung ????
Sollte aber keine Einschränkung in Bezug auf die Flexibilität haben ?
Wie machen das eigentlich andere Programme ? Oder gibt es solche garnicht
...:)
Na da bin ich mal gespannt, vielleicht gibt es ja einen viel einfacheren Weg
!!!???
Cu Ramon
P.S. hoffe das ganze ist überhaupt verständlich...
> Hallo Leute.
> Mal ein komplexes Problem (zumindest umfangreich, dieses zu
> beschreiben...:) )
die Beschreibung habe ich mal ausgeschnitten.
Hast Du außer dem Primärindex auch noch Indexe auf Datum und
Währungscode einzeln liegen? Damit - speziell mit dem Index auf dem
Datum - sollte die Abfrage schon deutlich schneller laufen.
Dann würde ich das DateDiff aus der Abfrage herauslassen und
stattdessen den Recordset nach dem Datum direkt absteigend sortieren,
und nur die Daten selektieren, die die richtige Währung sind. Also in
etwa so (zur besseren Lesbarkeit ohne Anführungszeichen):
SELECT ... FROM ... WHERE [Währungscode]=WCode ORDER BY [Datum] DESC
der erste Wert dieses Recordsets ist die gesuchte Umrechnung.
> Habe schon daran gedacht, daß die Funktion das Ergebnis dauerhaft in einen
> Datensatz einträgt, und nur noch so die fehlenden jedesmal berechnet werden
> brauchen. Ändert man aber nachträglich den Kurs oder ändert die
> Standardwährung müsste es ja eh neu berechnet werden...
Du könntest ein Formular zu Beginn der Anwendung öffnen, das alle
Währungen und die Umrechnungen anzeigt. Der Benutzer kann die
Umrechnungen bei Bedarf ändern (die neuen Werte werden dann in der
Datenbank unter dem aktuellen Datum gespeichert). Anstatt das Formular
zu schließen, wird es aber nur unsichtbar gemacht, und wenn eine
Umrechnung gebraucht wird, wird der Wert aus diesem Formular
ausgelesen. Über einen Menübefehl oder Button in einem Menü-Formular
wird das Fenster wieder sichtbar gemacht, damit man wieder Änderungen
vornehmen kann.
Sascha
--
s...@gmx.de
Quote of Today :
If winning isn't important then why keep score?
Ich glaube, der Knackpunkt ist, daß für jede Zeile der eigentlichen
Abfrage einmal die Funktion aufgerufen wird, die dabei jedesmal die
DB öffnet, ein Recordset öffnet ...
Versuch mal, das alles mit Unterabfragen anstatt mit einer Funktion
zu realisieren.
Nur wenn das gar nicht geht, dann könntest du versuchen, die
DB-Variable static zu machen um nicht für jede Zeile der Abfrage
die DB erneut öffnen zu müssen.
> Habe schon daran gedacht, daß die Funktion das Ergebnis dauerhaft in einen
> Datensatz einträgt, und nur noch so die fehlenden jedesmal berechnet werden
> brauchen. Ändert man aber nachträglich den Kurs oder ändert die
> Standardwährung müsste es ja eh neu berechnet werden...
eben
> Weiß jemand eine bessere Lösung ????
Versuch's mal wie oben beschrieben.
Gf.
Ich habe eine sehr ähnliche Aufgabenstellung gehabt . Allerdings durften
mehrere Kurseinträge pro Währung und Tag erfolgen und die Standardwährung
war ein nicht vom User änderbarer Systemparameter. Der Zeitstempel erfolgte
per Now(), nicht per Date
[Kurstabelle]
[ID], Typ Autowert, Primärindex
[KursDatum], Typ Datum und Uhrzeit, Indiziert, nicht eindeutig, Absteigend
sortiert
[Paritaet],Typ Zahl, Feldgröße Double
[CurrID], Typ Zahl, Feldgröße Byte,Indiziert, nicht eindeutig,
Den aktuellen Kurs holte ich durch QueryByForm aus einer gespeicherten
Abfrage, die deutlich schneller als die Methode per SQL string zur Laufzeit
war.
Gespeicherte Abfrage [qry_Kurs]
Liefert [Kurstabelle].*
Bedingung [CurrID] = Form![HolKurs]![DieseWaehrung]
Sortierung absteigend [KursDatum] (für alle Fälle)
Das Miniformular [HolKurs] versorgte dann das jeweilige Fakturenformular
mit dem jeweils gewünschten aktuellen Währungsdatensatz.
Peter
>s...@gmx.de
>Quote of Today :
>If winning isn't important then why keep score?
Yes
>Dann würde ich das DateDiff aus der Abfrage herauslassen und
>stattdessen den Recordset nach dem Datum direkt absteigend sortieren,
>und nur die Daten selektieren, die die richtige Währung sind. Also in
>etwa so (zur besseren Lesbarkeit ohne Anführungszeichen):
> SELECT ... FROM ... WHERE [Währungscode]=WCode ORDER BY [Datum] DESC
>der erste Wert dieses Recordsets ist die gesuchte Umrechnung.
hmm...der erste Wert dieses Recodsets ist doch dann das AKTUELLSTE bzw.
neuste
Datum, oder nicht. Die Funktion bzw. die Abfrage soll aber den Kurs finden
der
am dichtesten an der Variable TAG liegt. Bei Auswerungen soll ja immer der
dazugehörige Kurs und nicht immer der aktuellste benutzt werden.
Oder mache ich jetzt einen Denkfehler ???
Cu
>
>Den aktuellen Kurs holte ich durch QueryByForm aus einer gespeicherten
>Abfrage, die deutlich schneller als die Methode per SQL string zur Laufzeit
>war.
>Gespeicherte Abfrage [qry_Kurs]
>Liefert [Kurstabelle].*
>Bedingung [CurrID] = Form![HolKurs]![DieseWaehrung]
>Sortierung absteigend [KursDatum] (für alle Fälle)
>
>Den aktuellen Kurs holte ich durch QueryByForm aus einer gespeicherten
>Abfrage, die deutlich schneller als die Methode per SQL string zur Laufzeit
>war.
>Gespeicherte Abfrage [qry_Kurs]
>Liefert [Kurstabelle].*
>Bedingung [CurrID] = Form![HolKurs]![DieseWaehrung]
>Sortierung absteigend [KursDatum] (für alle Fälle)
>
Hallöle,
die Betonung liegt hier aber wohl darauf, daß die Abfrage immer den
AKTUELLEN Kurs holt.
Meine Funktion/Abfrage soll jedoch immer den Kurs des gesuchten Tages, bzw.
der am DICHTESTEN dran ist von der übergebenen Variablen (TAG)
herraussuchen.
Dadurch muß ich doch die Abfrage während der Laufzeit generieren, oder ?
Cu
Höchstens den, dass der Kurs immer maximal gleich jung sein dürfte
als der Tag an dem die Umrechnung anfiel. Es ist ja wahrscheinlich
nicht ganz koscher, wenn z.B. ein Vorgang zum 27.04.1998 mit einem
Kurs vom 01.05.1998 umgerechnet wird anstatt mit einem Kurs vom
01.04.1998, eben weil zum 27.04.1998 kein aktuellerer Kurs bekannt
gewesen sein kann als der vom 01.04.1998. So gesehen wäre es legitim
mit nach Kursdatum absteigend und dabei aber Kursdatum <= Vorgangs-
datum zu arbeiten, anstelle von Minimum(Datumsdifferenz) - und wohl
auch wesentlich schneller.
Gf.
>
> Sascha Wostmann schrieb in Nachricht <3634e...@news.piro.net>...
>
> >Dann würde ich das DateDiff aus der Abfrage herauslassen und
> >stattdessen den Recordset nach dem Datum direkt absteigend sortieren,
> >und nur die Daten selektieren, die die richtige Währung sind. Also in
> >etwa so (zur besseren Lesbarkeit ohne Anführungszeichen):
> > SELECT ... FROM ... WHERE [Währungscode]=WCode ORDER BY [Datum] DESC
> >der erste Wert dieses Recordsets ist die gesuchte Umrechnung.
>
>
> hmm...der erste Wert dieses Recodsets ist doch dann das AKTUELLSTE bzw.
> neuste Datum, oder nicht. Die Funktion bzw. die Abfrage soll aber den Kurs finden
> der am dichtesten an der Variable TAG liegt.
das hatte ich übersehen, da in Deiner Abfrage immer mit ABS(DateDiff)
gearbeitet wurde. Ich bin davon ausgegangen, daß immer der aktuellste
Datensatz gesucht wird. BTW, dabei findet die Abfrage doch auch
Umrechnungen "in der Zukunft", hast Du das mal getestet?
Ist aber nicht weiter tragisch, füge einfach eine weitere
WHERE-Klausel ein: WHERE ... AND [Datum]<=[Tag]
Übrigens, "Tag" ist auch eine Eigenschaft von Formularen, Feldern,
etc. (=Marke). Ich wäre vorsichtig mit diesem Feldnamen.
Sascha
--
s...@gmx.de
Quote of Today :
Ein Verstand ist schrecklich, wenn man ... eeeh ... hmmm ?