Среда разработки: CodeGear, delphi 2010, Windows 7
Исходничек:
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,DB, StdCtrls, OleCtnrs, DBClient;
type
TForm1 = class(TForm)
ClientDataSet1: TClientDataSet;
ClientDataSet1id: TIntegerField;
ClientDataSet1LastName: TStringField;
ClientDataSet1Name: TStringField;
ClientDataSet1Patronymic: TStringField;
ClientDataSet1Post: TStringField;
ClientDataSet1Salary: TFloatField;
DataSource1: TDataSource;
ClientDataSet2: TClientDataSet;
ClientDataSet2id: TIntegerField;
ClientDataSet2Processor: TStringField;
ClientDataSet2Cores: TIntegerField;
ClientDataSet2Memory: TFloatField;
DataSource3: TDataSource;
Label1: TLabel;
ListBox2: TListBox;
OleContainer1: TOleContainer;
ListBox1: TListBox;
OpenDialog1: TOpenDialog;
Button2: TButton;
procedure ListBox2Enter(Sender: TObject);
procedure CreateDataSourceList(lParent: TComponent);
private
{ Private declarations }
public
{ Public declarations }
end;
type
DataSourceData = record
Tag: LongInt;
FieldsCount: integer;
FieldDisplayLabels: array [0..500] of string[70];
IsVisible: array [0..500] of boolean;
end;
var
dsRecord: array [0..99] of DataSourceData;
DataSourceCount: integer;
DataSourceNames: array[0..99] of string;
Form1: TForm1;
implementation
{$R *.dfm}
procedure Tform1.CreateDataSourceList(lParent: TComponent);
var DS: TDataSource;
i,j,k:integer;
lIndex:integer;
sstring:string;
begin
Listbox2.clear;
DataSourceCount:=0;
for k := 0 to lParent.ComponentCount - 1 do
if lParent.Components[k] is TDataSource then
begin
DataSourceNames[DataSourceCount]:={lParent.Name+'.'+}lParent.components[k].name;
inc(DataSourceCount);
ListBox2.Items.Add(lparent.Components[k].name);
end;
if (ListBox2.Items.Count=0) or (DataSourceCount=0) then exit;
for I := 0 to ListBox2.Items.Count - 1 do
begin
DS := TDataSource(DataSourceNames[i]);
k:=i;
sstring:=DataSourceNames[i]+' '+inttostr(i);
if Assigned(DS) then k:=i else continue;
dsRecord[i].Tag:=DS.Tag;
dsRecord[i].FieldsCount:=0;
for j := 0 to DS.DataSet.Fields.Count-1 do
begin
dsRecord[i].FieldDisplayLabels[dsRecord[i].FieldsCount]:=DS.DataSet.Fields.Fields[j].DisplayLabel;
inc(dsRecord[i].FieldsCount);
dsRecord[i].IsVisible[j]:=false;
end;
end;
end;
procedure TForm1.ListBox2Enter(Sender: TObject);
begin
CreateDataSourceList(form1);
end;
end.
Описание проблемы:
В итоге на форме имеем 2 DataSource с именами DataSource1 и DataSource3.
Вот в этом месте:
Код:
for I := 0 to ListBox2.Items.Count - 1 do
begin
DS := TDataSource(DataSourceNames[i]);
на первой итерации естественно выбирается DataSource1, НО ПОЧЕМУ ТО в массив здесь:
Код:
for j := 0 to DS.DataSet.Fields.Count-1 do
begin
dsRecord[i].FieldDisplayLabels[dsRecord[i].FieldsCount]:=DS.DataSet.Fields.Fields[j].DisplayLabel;
на этой же, первой итерации записываются дисплейлабелы ВТОРОГО DataSource, то есть DataSource3.
А на второй итерации при выборе DataSource3 на строчке
Код:
for j := 0 to DS.DataSet.Fields.Count-1 do
выскакивает ошибка Access violation.
Подскажите в чем дело? Я как то не правильно присваиваю переменной DS конкретный DataSource?