Title: Populating a StringGrid
Question: The problem was that when querying our Opera account system, because it is not a client-server system, access to account details was sometimes slow. I decided to replace the DBgrid with a stringgrid, and to populate it from the query which displayed detailed transactions from Opera. So two queries were replaced by one, and delays halved.
Answer:
I hope the explanations in the code are clear. I am submitting this because it took me a while to find out how to do this, and guess there may be others who might find this useful.
procedure TfmRegistration.BalanceSummary;
var
Balance: array of real;
YearQuarter: array of String;
i, j: integer;
stored: Boolean;
begin
// First, create two dynamic arrays, one of outstanding balances and
// the other of the relevant period (year + quarter), and store all
// outstanding balances by reading through the transactions
dmAccounts.quOperaAllTransactions.first;
j := 0;
With dmAccounts.quOperaAllTransactions do begin
while not EOF do begin
stored := false;
// if this is not the first O/S balance for this period
// add it to the running total for the period
if FieldByname('ST_TRBAL').asFloat 0 then begin
for i := Low(yearQuarter) to High(yearQuarter) do begin
if YearQuarter[i] = IntToStr(FieldByName('KL_YEAR').asInteger) + IntToStr(FieldByName('KL_QTR').asInteger) then begin
Balance[i] := Balance[i] + FieldByName('ST_TRBAL').asFloat;
stored:= True;
end;
end;
if stored = False then begin
// If this is the first O/S balance for the period,
// creat a fresh entry in the array
// Because dynamic arrays do not have a fixed size/length
// I use SetLength to allocate memory as required
inc(j);
setLength(balance,j);
setlength(YearQuarter,j);
YearQuarter[j - 1] := IntToStr(FieldByName('KL_YEAR').asInteger) + IntToStr(FieldByName('KL_QTR').asInteger);
Balance[j - 1] := FieldByName('ST_TRBAL').asFloat;
end;
end;
next;
end;
end;
// I use High to check if there are any entries in the array
if high(yearQuarter) osBalgrid.visible := False;
end
else begin
// I dynamically set the number of rows in the grid,
// label the columns, and populate the cells from the data
osBalgrid.visible := True;
osbalGrid.Cells[0,0] := 'Year';
osbalGrid.Cells[1,0] := 'Quarter';
osbalGrid.Cells[2,0] := 'Balance';
osbalgrid.RowCount := j + 1;
osbalGrid.Height := ((osbalgrid.DefaultRowHeight + 3) * osbalgrid.RowCount);
for i := Low(yearQuarter) to High(yearQuarter) do begin
osBalGrid.Cells[0,i + 1] := Copy(YearQuarter[i],1,4);
osBalGrid.Cells[1,i + 1] := Copy(YearQuarter[i],5,1);
osBalGrid.Cells[2,i + 1] := FloatToStr(Balance[i]);
end
end;
// before finally tidying up dynamic array
setLength(Balance,0);
setLength(YearQuarter,0);
end;