Beispiel Bericht für Bestandsprognose

Fragen zum Thema InterRun
Antworten
Christian Hönnicke
Profi
Beiträge: 105
Registriert: Sa, 10 Feb, 2007 19:31

Beispiel Bericht für Bestandsprognose

Beitrag von Christian Hönnicke » Mi, 27 Jun, 2007 21:20

Hallo,

der folgende "Bericht" erlaubt eine Kontostandsprognose für ein gegebenes Konto.
Dazu muss ein Zeitraum ausgewählt werden, der die Vergleichsdaten repräsentiert. Anschließend wird versucht eine Gerade zu finden, bei der die (Summe der quadratischen) Abstände zwischen den echten Kontoständen und den theoretischen Kontoständen minimal ist. Dann wird die berechnete Gerade und die verwendeten Kontostände zur optischen Kontrolle graphisch dagestellt.
Nun ist es möglich für jeden beliebigen Tag den Kontostand vorhersagen zu lassen.

WICHTIG: Die Prognose geht davon aus, dass das (positive/negative) Wachstum des Kontostandes linear über den ganzen Zeitraum erfolgt!

Es wird ein Bericht benötigt mit folgenden Elementen:
Fläche: Flaeche1 (zur Darstellung)
Schalter: Schalter1 (Löschen der Darstellung), Schalter2 (Berechnung der Geraden), Schalter3 (Vorhersage)
Datumsfeld: Datumsfeld1 (Vergleichszeitraumsanfang), Datumsfeld2 (Vergleichszeitraumsende), Datumsfeld3 (Prognosezeitpunkt)
Zahlenfeld: Zahlenfeld1 (der Kontostand jedes Xten Tages wird verwendet)
Währungsfeld: Waehrungsfeld1 (Kontostand zum Prognosezeitpunkt)

Nun muss das "Programm-Center" geöffnet werden. Durch einen Doppelklick auf eine "Aktion" wird auf der rechten Seite der zugehörige Quellcode angezeigt. Wenn eine "Aktion" fett gedruckt ist, dann wird sie verwendet.

Alle gleich genannten "Aktionen" sollten noch NICHT als VERWENDET markiert SEIN! Falls dem nicht so ist, kann die weitere Anleitung nicht eins zu eins übernommen werden.

Mit einem Doppelklick auf die entsprechende "Aktion" wird der zugehörige Quellcode angezeigt. Die automatisch erzeugten Zeilen können bedenkenlos gelöscht werden.

Öffenen des Baums unter der "Aktion" des Kassenbuchs, in der der Bericht erstellt wurde (nicht "EuroKass").
->Modul
(siehe unter Antwort1)
->Berichte->Bericht[X]->Schalter1->Beim Klick
(siehe unter Antwort2)
->Berichte->Bericht[X]->Schalter2->Beim Klick
(siehe unter Antwort 3)
->Berichte->Bericht[X]->Schalter3->Beim Klick
(sieht unter Antwort 3)


Nun müssen noch kurz folgende Zeilen in Schalter2_OnClick angepasst werden:

| gewaehltes Konto
GewaehltesKonto = "Konten.Kurz.Postbank"
Hoehe = 424 | in pixel <- größe der Zeichenflaeche
Breite = 596 | in pixel <- größe der Zeichenflaeche

Viel Spaß beim Ausprobieren.

Gruß
Christian

Christian Hönnicke
Profi
Beiträge: 105
Registriert: Sa, 10 Feb, 2007 19:31

Modul

Beitrag von Christian Hönnicke » Mi, 27 Jun, 2007 21:21

|E:\Programme\EuroKass\Data\xxx.KAS
|Erstellt am Samstag, 23 Juni 2007 - 15:12

Var m1, n1, Y1Min, Y1Max : Double
Var ErsterTag1 : String
Var m2, n2, Y2Min, Y2Max : Double
Var ErsterTag2 : String

Procedure BerechneGerade( GewaehltesKonto : String; ErsterTag : String; Tage : Integer; XStep : Integer; Ind : Integer )

Var XQuer, XMin, XMax, XSum, YQuer, YMin, YMax, YSum, XXSum, XYSum : Double
Var X : Integer
Var Y : Double
Var m, n : Double
Var AktuellerTag : String

| Statistikteil (lineare Regression)
| Teil 1: Eckwerte berechnen
| Startwerte
| Tag 1
AktuellerTag = ErsterTag
YMin = Account( GewaehltesKonto ).TotalBalance( ErsterTag )
YMax = YMin
YSum = YMin

XMin = 1.0 | fix
XMax = Tage
XSum = 1.0

| Bestimme: YMin, YMax, YSum
| Tag 2 bis Tag n
For X = 2 To Tage
Y = Account( GewaehltesKonto ).TotalBalance( AktuellerTag )

If Y < YMin
YMin = Y
EndIf

If Y > YMax
YMax = Y
EndIf

YSum = YSum + Y
XSum = XSum + X

AktuellerTag = AddDays( AktuellerTag, XStep )
Next

YQuer = YSum / Tage
XQuer = XSum / Tage

| Teil 2: konkrete Werte berechnen
AktuellerTag = ErsterTag
XXSum = 0
XYSum = 0

For X = 1 To Tage
Y = Account( GewaehltesKonto ).TotalBalance( AktuellerTag )

XYSum = XYSum + ( ( X - XQuer ) * ( Y - YQuer ) )
XXSum = XXSum + ( ( X - XQuer ) * ( X - XQuer ) )

AktuellerTag = AddDays( AktuellerTag, XStep )
Next

| Teil 3: lineare Gleichung y = mx + n
m = XYSum / XXSum
n = YQuer - ( m * XQuer )

If Ind = 1
m1 = m
n1 = n
Y1Min = YMin
Y1Max = YMax
ErsterTag1 = ErsterTag
EndIf

If Ind = 2
m2 = m
n2 = n
Y2Min = YMin
Y2Max = YMax
ErsterTag2 = ErsterTag
EndIf

EndProcedure

Christian Hönnicke
Profi
Beiträge: 105
Registriert: Sa, 10 Feb, 2007 19:31

Schalter1_OnClick

Beitrag von Christian Hönnicke » Mi, 27 Jun, 2007 21:23

Procedure Schalter1_OnClick
|Ihre Programmzeilen
flaeche1.Refresh
EndProcedure

Christian Hönnicke
Profi
Beiträge: 105
Registriert: Sa, 10 Feb, 2007 19:31

Schalter2_OnClick

Beitrag von Christian Hönnicke » Mi, 27 Jun, 2007 21:23

Procedure Schalter2_OnClick
| lineare Regression (Methode der kleinste Quadrate)

Var Tage : Integer
|Var XQuer, XMin, XMax, XSum, YQuer, YMin, YMax, YSum : Double
Var m, n, YMin, YMax : Double
Var ErsterTag, LetzterTag, AktuellerTag : String
Var DC : Integer
Var X, XNext : Integer | X : Tag
Var Y : Double | Y : KontoStand am Tag X
Var GewaehltesKonto : String
Var Hoehe, Breite, Rand : Integer
Var XOff, YOff : Double
Var XPunkt, YPunkt, NullLinie : Double

Var iTemp : Integer

| gewaehltes Konto
GewaehltesKonto = "Konten.Kurz.Postbank"
Hoehe = 424 | in pixel
Breite = 596 | in pixel
Rand = 10 | in pixel

| Bestimme das betrachtete Zeitintervall
Tage = DateDiff( Datumsfeld1.Date , Datumsfeld2.Date )

If Tage < 0
ErsterTag = Datumsfeld2.Date
LetzterTag = Datumsfeld1.Date
Tage = ( Tage * -1) + 1
EndIf
Else
ErsterTag = Datumsfeld1.Date
LetzterTag = Datumsfeld2.Date
Tage = Tage + 1
EndElse

| Der betrachtete Zeitraum betrifft wahrscheinlich die Zukunft -> keine Daten vorhanden
If DateDiff( LetzterTag, Date ) < 0
Sm( "Der betrachtete Zeitraum liegt (teilweise) in der Zukunft." )
Exit
EndIf

| Der Abstand zwischen zwei betrachteten Zeitpunkten muss positiv und ...
If Zahlenfeld1.Value <= 0.0
Sm( "Der Abstand zwischen zwei betrachteten Kontoständen muss positiv sein." )
Exit
EndIf
| ... und ganzzahlig sein
XNext = Floor( Zahlenfeld1.Value )

| verschiebe den letzten Tag, damit die Intervalle aufgehen
iTemp = Mod( Tage, XNext )
if iTemp <> 0
iTemp = XNext - iTemp
EndIf

LetzterTag = AddDays( LetzterTag, iTemp )
Datumsfeld2.Date = LetzterTag
Datumsfeld2.Refresh

Tage = ( DateDiff( ErsterTag, LetzterTag ) + 1 ) / XNext

| Der betrachtete Zeitraum muss mehr als 10 betrachtete Zeitpunkte beinhalten
If Tage < 10
Sm( "Der betrachtete Zeitraum muss mehr als 10 betrachtete Zeitpunkte betragen, da sonst die Vorhersage zu ungenau wird." )
Exit
EndIf



BerechneGerade( GewaehltesKonto, ErsterTag, Tage, XNext, 1 )

| Rueckgabeparameter einlesen
m = m1
n = n1
YMin = Y1Min
YMax = Y1Max

| *** Darstellung ***
Dc = GetDc( Flaeche1.Handle )

| Umrechnungsfaktoren fuer die Darstellung berechnen
XOff = ( Breite - (2*Rand) ) / ( Tage - 1 ) | Pixel pro Tag
YOff = ( Hoehe - (2*Rand) ) / YMax | pixel pro EUR

| Nulllinie einzeichnen
iTemp = YMax - YMin
if iTemp > YMax
| YMax positiv, YMin negativ
Line( Dc, Rand, Hoehe - floor(( YMax/YMin )*YOff), Breite - Rand , Hoehe - floor(( YMax/YMin )*YOff),Rgb(255,255,255),2,0)
EndIf
Else
if YMax > 0
Line( Dc, Rand, Hoehe - Rand, Breite - Rand , Hoehe - Rand, Rgb(0,0,0), 2, 0 )
EndIF
if YMax <= 0
Line( Dc, Rand, Rand, Breite - Rand , Rand, Rgb(0,0,0), 2, 0 )
EndIf
EndElse

| Kontostaende einzeichnen
AktuellerTag = ErsterTag

For X = 0 To Tage-1
Y = Account( GewaehltesKonto ).TotalBalance( AktuellerTag )

XPunkt = X * XOff + Rand
YPunkt = Hoehe - ( Y * YOff )

| sm( inttostr(XPunkt))
|sm( inttostr(YPunkt))

| sm ( floattostr(YPunkt))
| sm(floattostr(YPunkt))
| Ellipse( Dc, XPunkt-5, 10+X, XPunkt+5, 20+X, RGB( 50, 100 , 100 ), RGB( 50, 100 , 100 ) )
Rectangle( Dc, XPunkt-5, YPunkt+5, XPunkt+5, YPunkt-5, RGB( 50, 100 , 100 ), RGB( 50, 100 , 100 ) )

AktuellerTag = AddDays( AktuellerTag, XNext )
Next


| Schaetzfunktion einzeichnen
Line( Dc, Rand, Hoehe - ( ( m*1 + n )*YOff ), Breite - Rand, Hoehe - ( ( m*Tage + n )*YOff ),Rgb(255,100,100),2,0)


|Flaeche1.Refresh
ReleaseDc(Flaeche1.Handle,Dc)
EndProcedure

Christian Hönnicke
Profi
Beiträge: 105
Registriert: Sa, 10 Feb, 2007 19:31

Schalter3_OnClick

Beitrag von Christian Hönnicke » Mi, 27 Jun, 2007 21:24

Procedure Schalter3_OnClick
|bestimme den Wert der Gerade zu einem gegebenen Zeitpunkt Datumsfeld 3

Var Tage : Integer

Tage = DateDiff( ErsterTag1, Datumsfeld3.Date )

Waehrungsfeld1.Value = m1*Tage + n1

EndProcedure

Benutzeravatar
Team Schauries
Site Admin
Beiträge: 1058
Registriert: Mo, 17 Jan, 2005 20:25
Wohnort: Essen

Beitrag von Team Schauries » Mi, 27 Jun, 2007 22:44

Hallo Christian,

Respekt, Respekt! Jetzt haut es mich aber von den Socken!!!
Ich werde Deine Sourcen am Wochenende mal austesten und berichten.

Erste Idee... wäre es nicht toll, wenn Du uns Deinen Bericht als Export zukommen lassen könntest, damit wir das zukünftig in ein Demokassenbuch einbetten könnten?

Gruß,
Dirk Schauries
Team Schauries

Christian Hönnicke
Profi
Beiträge: 105
Registriert: Sa, 10 Feb, 2007 19:31

Beitrag von Christian Hönnicke » Do, 28 Jun, 2007 17:34

Hallo Dirk,

> Erste Idee... wäre es nicht toll, wenn Du uns Deinen Bericht als Export zukommen lassen könntest, damit wir das zukünftig in ein Demokassenbuch einbetten könnten?

So generell hätte ich keine Einwände. Im Gegenzug hätte ich in den Scripten an erster Stelle ein Kommentar, was mich als Autor ausweist.

Im Moment bin ich noch an einer Erweiterung, dass ich Prognosen für zwei Konten gleichzeitig darstellen kann (inklusive Schnittpunktberechnung).

Bevor der Bericht für die Unbedarften freigegeben wird, müsste für folgende Zeilen noch ein schöner Automatismus gefunden werden:

GewaehltesKonto = "Konten.Kurz.Postbank"
Hoehe = 424 | in pixel <- größe der Zeichenflaeche
Breite = 596 | in pixel <- größe der Zeichenflaeche


Gruß
Christian

Hermann
Profi
Beiträge: 23
Registriert: Do, 15 Dez, 2005 15:32
Wohnort: Gaggenau

Beitrag von Hermann » So, 09 Sep, 2007 16:01

Hallo Dirk, hallo Christian.

gibt es den Bericht schon im Beispielkassenbuch? :)

Gruß
Hermann D

Christian Hönnicke
Profi
Beiträge: 105
Registriert: Sa, 10 Feb, 2007 19:31

Beitrag von Christian Hönnicke » So, 09 Sep, 2007 21:53

Hallo Hermann,

verbessert und abgegeben ist er schon.
Soweit ich es in Erinnerung hatte, waren da noch ein paar Bugfixes nötig und eine kleiner Erweiterung von Eurokass damit alles klappt.

Achja, irgendwo sind hier im Skript noch kleinere Fehler. Insofern würde ich die Zeilen hier in zwischen eher als Beispielzeilen für neue Berichte betrachten.

Mit freundlichen Grüßen
Christian Hönnicke

NoSpam
Site Admin
Beiträge: 34
Registriert: Mi, 08 Nov, 2006 21:39
Wohnort: Essen

Beitrag von NoSpam » Mo, 10 Sep, 2007 12:25

Hallo Christian,

wir haben Deinen Beispielbericht nicht vergessen! Uns fehlt nur die Zeit für ein Update.
Schön wäre noch, wenn Du uns ein komplettes Kassenbuch liefern könntest. Dieses würden wir dann ohne großen Aufwand gleich integrieren können. Geht das wohl?

Gruß und vielen Dank für Deine Bemühungen,
Joshua

Hermann
Profi
Beiträge: 23
Registriert: Do, 15 Dez, 2005 15:32
Wohnort: Gaggenau

Beitrag von Hermann » Di, 11 Sep, 2007 21:05

Hi ihr beiden,

danke für die Info. Dann übe ich mich noch in etwas Geduld.

Gruß :P
Hermann D

Antworten