Reputation: 49
I'm programming a simple cash flow app, using Delphi 7, firebird 2.5 with InterBase components. The table in question was created like this:
create table movimentos
(
id d_inteiro not null,
date_start d_data not null,
date_end d_data,
value d_valor,
user d_inteiro,
tipo_movimento d_inteiro not null, -- Indicates if it is Debit or Credit
primary key(id),
foreign key(user) references usuarios(id),
foreign key(tipo_movimento) references tipoMovimento(id)
)
I added a calculated field in the query inside my DM and connected a DBGrid to it. What it basically has to do is to show my balance, using sum when the entry is credit( especified in the db) and sub when debit( duh).
For this, I have to get the value of the LAST balance row, sum(or sub) the value of the new entry and put this new ammount in the new insertion.
Well, I know how to calculate values in the same row and put it in another column, but cannot find anything about getting previous row value and using it in the next.
What would be the simpler way to accomplish that?
Edited: Complementing my question. What I would like to do is somehting like this(simplifying the table a little bit):
Id date_start value balance
1 03/05/15 +200 200
2 03/08/15 +1000 1200
3 03/09/15 -300 900
Now, if I added a new entry for date 03/06/15
all the rows would have to be recalculated, like this:
Id date_start value balance
1 03/05/15 +200 200
4 03/06/15 +500 700
2 03/08/15 +1000 1700
3 03/09/15 -300 1400
How to create, calculate and show this BALANCE
column is basically what i'm looking for.
Thanks Again.
Upvotes: 0
Views: 967
Reputation: 1590
InterBase components do not support InternalCalc
fields, which are suitable for such client-side calculations. Although it is better to do that server-side.
In Firebird you can use context variables to calculate running totals:
SELECT m.*,
CAST(rdb$get_context('USER_TRANSACTION', 'BALANCE') AS d_valor) AS BALANCE,
rdb$set_context('USER_TRANSACTION', 'BALANCE', COALESCE(CAST(rdb$get_context('USER_TRANSACTION', 'BALANCE') AS d_valor), 0) + m.value) AS DUMMY
FROM movimentos m
ORDER BY date_start
Another solutions would be doing your desired calculations inside a stored procedure using a FOR SELECT
and iterating over data.
BALANCE = 0;
FOR SELECT id, data_start, value
FROM movimentos
ORDER BY date_start
INTO :ID, :DATA_START, :VALUE
DO
BEGIN
BALANCE = BALANCE + VALUE;
SUSPEND;
END
To apply Debit/Credit use IIF
to convert tipo_movimento
to +1/-1, if it is not:
value * IIF(tipo_movimento = ?, +1, -1)
Upvotes: 1