4.3. Výpočet průběžných součtů

Mnohé, zejména ekonomické aplikace, vyžadují výpočet průběžných součtů všech položek až po aktuální. Typických příkladem je průběh příjmů a výdajů ekonomické jednotky během účetního období (roku). Zdrojem bude objekt MesicniVykaz (nejspíš agregační dotaz), který sečte příjmy a výdaje podle měsíců:

Mesic

Prijmy

Vydaje

1

10 121,00 Kč

12 154,00 Kč

2

12 158,00 Kč

14 158,00 Kč

3

15 650,00 Kč

12 014,00 Kč

4

16 125,00 Kč

14 100,00 Kč

5

15 349,00 Kč

16 852,00 Kč

6

14 589,00 Kč

10 025,00 Kč

7

12 258,00 Kč

10 235,00 Kč

8

14 089,00 Kč

16 987,00 Kč

9

12 678,00 Kč

15 890,00 Kč

Do tiskové sestavy požadujeme pro každý měsíc součet všech měsíců až po aktuální. Pro lepší prezentaci aktuálního stavu požadujeme také zobrazení rozdílu a grafické znázornění aktuálního rozdílu, viz obr. 23.

Obr. 23. Požadovaná výstupní sestava průběhu příjmů a výdajů

Sestavu můžeme realizovat dvěma způsoby:

1. Jako zdroj použít přímo objekt MesicniVykaz a všechny výpočty realizovat v sestavě při formátování jednotlivých sekcí:

Option Compare Database
Option Explicit
Dim SPr As Double, SVy As Double, RozMax As Double, RozMin As Double, Roz As Double
Private Sub Tělo_Format(Cancel As Integer, FormatCount As Integer)
    Dim Dp As Double
    SPr = SPr + Me.Prijmy
    SVy = SVy + Me.Vydaje
    Roz = SPr - SVy
    Me.SPrijmy = SPr
    Me.SVydaje = SVy
    Me.SRozdil = Roz
    If Roz < 0 Then
        Me.Index.Width = 1
        Dp = ((RozMin - Roz) / RozMin) * 3.5
        Me.Index.Left = (Dp + 9) * 567
        Me.Index.Width = (3.5 - Dp) * 567
        Me.Index.BackColor = 255
        Me.Index.BorderColor = 255
    Else
        Me.Index.Width = 1
        Dp = ((Roz) / RozMax) * 3.5
        Me.Index.Left = (3.5 + 9) * 567
        Me.Index.Width = Dp * 567
        Me.Index.BackColor = 16711680
        Me.Index.BorderColor = 16711680
    End If
End Sub

Private Sub ZáhlavíSestavy_Format(Cancel As Integer, FormatCount As Integer)
    Dim D As Database, R As Recordset, S As Double
    SPr = 0
    SVy = 0
    RozMin = 0
    RozMax = 0
    Set D = DBEngine(0)(0)
    Set R = D.OpenRecordset(Me.RecordSource, dbOpenSnapshot)
    Do Until R.EOF
        SPr = SPr + R!Prijmy
        SVy = SVy + R!Vydaje
        S = SPr - SVy
        If S > RozMax Then RozMax = S
        If S < RozMin Then RozMin = S
        R.MoveNext
    Loop
    If Abs(RozMax) > Abs(RozMin) Then RozMin = -RozMax
    If Abs(RozMax) < Abs(RozMin) Then RozMax = -RozMin
    SPr = 0
    SVy = 0
End Sub

2. Nebo můžeme nejprve dotazem získat potřebné údaje a ty zobrazit v sestavě (pokud bychom nepotřebovali grafické zobrazení aktuálního rozdílu příjmů a výdajů, nepotřebovala by sestava žádnou programovou obsluhu).

Dotaz využije spojení přes nerovnost dvakrát vloženého objektu MesicniVykaz. Z jedné instance použijeme položku Mesic, z druhé součet položek Prijmy a Vydaje. Obě instance spojíme přes nerovnost položek Mesic:

SELECT MesicniVykaz.Mesic, Sum(MesicniVykaz_1.Prijmy) AS Prijmy, Sum(MesicniVykaz_1.Vydaje) AS Vydaje, [Prijmy]-[Vydaje] AS Rozdil
FROM MesicniVykaz INNER JOIN MesicniVykaz AS MesicniVykaz_1 ON MesicniVykaz.Mesic > MesicniVykaz_1.Mesic
GROUP BY MesicniVykaz.Mesic;

Díky spojení přes nerovnost položek není možno dotaz vytvořit jinak než ve tvaru SQL. Pro zformátování sestavy se pak situace velmi zjednoduší:

Option Compare Database
Option Explicit
Dim RozMax As Double, RozMin As Double

Private Sub Tělo_Format(Cancel As Integer, FormatCount As Integer)
    Dim Dp As Double
    If Me.SRozdil < 0 Then
        Me.Index.Width = 1
        Dp = ((RozMin - Me.SRozdil) / RozMin) * 3.5
        Me.Index.Left = (Dp + 9) * 567
        Me.Index.Width = (3.5 - Dp) * 567
        Me.Index.BackColor = 255
        Me.Index.BorderColor = 255
    Else
        Me.Index.Width = 1
        Dp = ((Me.SRozdil) / RozMax) * 3.5
        Me.Index.Left = (3.5 + 9) * 567
        Me.Index.Width = Dp * 567
        Me.Index.BackColor = 16711680
        Me.Index.BorderColor = 16711680
    End If
End Sub

Private Sub ZáhlavíSestavy_Format(Cancel As Integer, FormatCount As Integer)
    Dim D As Database, R As Recordset, S As Double
    RozMin = 0
    RozMax = 0
    Set D = DBEngine(0)(0)
    Set R = D.OpenRecordset(Me.RecordSource, dbOpenSnapshot)
    Do Until R.EOF
        S = R!Prijmy - R!Vydaje
        If S > RozMax Then RozMax = S
        If S < RozMin Then RozMin = S
        R.MoveNext
    Loop
    If Abs(RozMax) > Abs(RozMin) Then RozMin = -RozMax
    If Abs(RozMax) < Abs(RozMin) Then RozMax = -RozMin
End Sub

Datum zveřejnění: 24. 9. 1999