我有一个填充Access数据库的DBGrid。我想要的只是像矩阵一样迭代那些数据,例如单元格00,01,02,10,11,12,
答案 0 :(得分:5)
DBGrid只是数据的直观表示。本机方式是迭代数据集和字段
如果您的数据集确实支持RecNo,您可以使用RecNo和字段索引访问这些值。(*)
确保不要访问RecordCount -1以上的行和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;
答案 1 :(得分:1)
你已经拥有并接受了一个很好的答案(我已经+ 1d,顺便说一句)给你的q,但是当我差不多完成这个时,我想 我不妨发布它,如果只是填写一些关于如何访问[Row,Column]中的数据集的细节 如果你真的必须的话。当然,这并不是说这样做是个好主意。
所以,以下内容纯粹是作为对另一个答案的补充,而不是"完成"有了它并受到类似的警告:
并非所有TDataSet后代都有意义地实现RecNo
Ditto with DataSet.RecordCount(特别是Sql服务器)
对于任何非平凡大小的数据集,性能将是可怕的a)b)如果您尝试通过列访问它,那么绝对可怕,然后行"对于"循环(因为DataSet必须遍布整个地方!)。
它使用TDataArray类来包装(和隐藏)数据集,但允许访问其字段数据,如下所示:
{Something which can receive a variant} := DataArray[Row, Column];
不过,它是"默认"在类的DataProperty中,您可以避免编写
{Something ...} := DataArray.Data[Row, Column];
你问过以矩阵样式访问DBGrid的原因并不是一个好主意,原因如前所述。你也可以"切断中间人"并访问填充网格的数据集。
代码
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;