Reputation: 49
I have a DBGrid which fills with access database. All I want is to iterate that data like a matrix eg cell 00 , 01 ,02 , 10, 11, 12,
Upvotes: 2
Views: 4699
Reputation: 30715
You've already had and accepted a good answer (which I've +1d, btw) to your q, but as I'd nearly finished this, I thought I might as well post it, if only to fill in a few details of how you could access a dataset in a [Row, Column] sort of way, if you really must. That's not to say it's a good idea to do that, of course.
So, the following is intended purely as a supplement to the other answer, not to "complete" with it and is subject to similar caveats:
Not all TDataSet descendants implement RecNo meaningfully
Ditto with DataSet.RecordCount (esp ones for Sql servers)
Performance will be dire a) for a dataset of any non-trivial size and b) absolutely dire if you attempt to access it by Column then Row "for" loops (because the DataSet has to jump all over the place!).
It uses a TDataArray class to wrap (and hide) the dataset but permit access to its field data like so:
{Something which can receive a variant} := DataArray[Row, Column];
Btw, it's the "default" on the class's DataProperty that allows you to avoid having to write
{Something ...} := DataArray.Data[Row, Column];
You asked about accessing a DBGrid in a matrix style by that's not really a good idea for several reasons, as mentioned in earlier comments. You might as well "cut out the middle-man" and access the dataset which is populating the grid.
Code
TForm1 = class(TForm)
CDS1: TClientDataSet;
procedure FormCreate(Sender: TObject);
private
procedure SetUp;
end;
TDataArray = class
private
FDataSet : TDataSet;
function GetData(Row, Column: Integer): Variant;
public
constructor Create(ADataSet : TDataSet);
function RowCount : Integer;
function ColumnCount : Integer;
property Data[Row, Column : Integer] : Variant read GetData; default; //NB 1-based
end;
[...]
function TDataArray.ColumnCount: Integer;
begin
Result := FDataSet.FieldCount;
end;
function TDataArray.RowCount: Integer;
begin
Result := FDataSet.RecordCount;
end;
constructor TDataArray.Create(ADataSet: TDataSet);
begin
inherited Create;
FDataSet := ADataSet;
end;
function TDataArray.GetData(Row, Column: Integer): Variant;
var
MoveBy : Integer;
begin
Assert((Row > 0) and (Row <= FDataSet.RecordCount)); // check Column, too, if you want
MoveBy := Row - FDataSet.RecNo;
if MoveBy <> 0 then begin
FDataSet.DisableControls;
try
FDataSet.MoveBy(MoveBy);
finally
FDataSet.EnableControls;
end;
end;
Result := FDataSet.Fields[Column - 1].Value;
end;
procedure TForm1.SetUp;
var
DataArray : TDataArray;
Row,
Column : Integer;
AValue : Variant;
begin
CDS1.FieldDefs.Add('ID', ftInteger);
CDS1.FieldDefs.Add('Name', ftString, 20);
CDS1.FieldDefs.Add('Value', ftString, 80);
CDS1.CreateDataSet;
CDS1.InsertRecord([1, 'A', 'A Value']);
CDS1.InsertRecord([2, 'B', 'B Value']);
CDS1.InsertRecord([3, 'C', 'C Value']);
DataArray := TDataArray.Create(CDS1);
try
for Row := 1 to DataArray.RowCount do begin
for Column := 1 to DataArray.ColumnCount do begin
AValue := DataArray[Row, Column];
end;
end;
finally
DataArray.Free;
end;
end;
Upvotes: 1
Reputation: 27377
A DBGrid is just a visual representation of the data. The native way would be to iterate over the dataset and the fields.
If your Dataset does support RecNo you might access the values using RecNo and the index of the field.(*)
Make sure not to access Rows above RecordCount - 1 and Fields above FieldCount -1
var
i: Integer;
begin
Dataset.DisableControls;
try
Dataset.First;
While not Dataset.EOF do
begin
for i := 0 to Dataset.FieldCount - 1 do
begin
//Access your Field of the current row by depending of your intention by Value/String whatever you need
//DoSomeThingWith(Dataset.Fields[i].Value); // make sure to handle NULL values
DoSomeThingWith(Dataset.Fields[i].asString);
end;
Dataset.Next;
end;
finally
Dataset.EnableControls;
end;
end;
//(*)
Function GetFieldValue(Dataset:TDataset;Row:Integer;FieldIndex:Integer):Variant;
begin
Dataset.RecNo := Row;
Result := Dataset.Fields[FieldIndex].Value;
end;
Upvotes: 7