Ciao, al lavoro dovrei avere qualcosa di simile, anche se usato all'interno della suite Kettle di Pentahoo.
Vado a memoria sperando di ricordarmi bene, in caso contrario, fammi sapere ...
select
campo1,
campo2,
campo3 NUMBER(3)
from tabella;
Sto creando una unit apposita, al momento è questa:
unit Unit_CampoComboDBGrid;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, db, Grids;
function AddDBComboBoxToGrid(NomeNuovoCampo: string; DataSet: TDataSet; CampoDataSet: string ;DataSetList: TDataSet; ChiaveLista: string; CampoLista: string): boolean;
implementation
function AddDBComboBoxToGrid(NomeNuovoCampo: string; DataSet: TDataSet; CampoDataSet: string ;DataSetList: TDataSet; ChiaveLista: string; CampoLista: string): boolean;
var
i: integer;
Field:TField;
ret: boolean;
begin
ret:=false;
try
try
DataSet.Active:=False;
for i:=0 to DataSet.FieldDefs.Count-1 do
Field:=DataSet.FieldDefs[i].CreateField(DataSet);
Field:=TStringField.Create(DataSet);
with Field do
begin
FieldName:=NomeNuovoCampo;
Dataset:=DataSet;
FieldKind := fkLookup; //QUI DICO CHE E' UNA COMBOBOX
LookupDataSet:=DataSetList; //QUI ASSEGNO IL DATASET DA CUI EREDITARE I DATI DA FAR VEDERE NELLA COMBOBOX
LookupCache:=FALSE;
LookupKeyFields:=ChiaveLista;//'CHIAVE'; //CHIAVE CHE VERRA' INSERITA NEL CAMPO Temf.KeyFields
LookupResultField:=CampoLista;//'NOME'; //VALORE CHE VEDI NELLA COMBOBOX DA SELEZIONE
ReadOnly:=FALSE; //SOLA LETTURA
ProviderFlags:=[pfInUpdate, pfInWhere];
Required:=FALSE;
KeyFields:=CampoDataSet;//'CHIAVEPV';
end;
DataSet.Active:=True;
ret:=TRUE;
finally
end;
except
on E: Exception do
begin
end;
end;
result:=ret;
end;
end.
Al momento non funziona, ma se metto tale codice all'interno della form dopo che ho aperto la query e quindi non passando per una funzione allora magicamente funziona tutto. Probabilmente qualcosa da rivedere nei parametri della funzione (puntatori). Ma appena sono + lucido la sistemo e la condivido funzionante
Ho provato il seguente codice e funziona, ma a me serve che sia una combobox e non solo un campo.
Procedure AddCalcStringField(Table1: tDataset; fName,fDisplay:String;
Size:
Integer);
{ Adds a calculated tStringField to a table at runtime}
var
f : TField;
i : integer;
begin
Table1.FieldDefs.Update;
Table1.Close;
for i := 0 to Table1.FieldDefs.Count - 1 do
if table1.FindField(table1.FieldDefs[i].Name) = nil then
table1.FieldDefs.Items[i].CreateField(Table1);
if table1.FindField(fName) <> nil then
Exit;
f := tStringField.Create(Table1);
f.Name := Table1.Name+fName;
f.FieldName := fName;
f.DisplayLabel := fDisplay;
f.Calculated := True;
f.DataSet := Table1;
Table1.Open;
end;
Allora ho provato a modificare il codice così? Ma la seguente riga
FieldKind := fkLookup; // <--ERROR
manda il loop il mio programma. Perchè?
Ecco il mio codice attuale
Procedure AddCalcStringField(fName: string;fDisplay:String;Size:Integer;Table1: tDataset; CampoDataSet: string; DataSetList: TDataSet; ChiaveLista: string; CampoLista: string);
{ Adds a calculated tStringField to a table at runtime}
var
f : TField;
i : integer;
begin
Table1.FieldDefs.Update;
Table1.Close;
for i := 0 to Table1.FieldDefs.Count - 1 do
if table1.FindField(table1.FieldDefs[i].Name) = nil then
table1.FieldDefs.Items[i].CreateField(Table1);
if table1.FindField(fName) <> nil then
Exit;
f := tStringField.Create(Table1);
with f do
begin
FieldName := Table1.Name+fName;
Name := fName;
DisplayLabel := fDisplay;
Calculated := True;
DataSet := Table1;
//FieldKind := fkLookup; //QUI DICO CHE E' UNA COMBOBOX
LookupDataSet:=DataSetList; //QUI ASSEGNO IL DATASET DA CUI EREDITARE I DATI DA FAR VEDERE NELLA COMBOBOX
LookupCache:=FALSE;
LookupKeyFields:=ChiaveLista;//'CHIAVE'; //CHIAVE CHE VERRA' INSERITA NEL CAMPO Temf.KeyFields
LookupResultField:=CampoLista;//'NOME'; //VALORE CHE VEDI NELLA COMBOBOX DA SELEZIONE
ReadOnly:=FALSE; //SOLA LETTURA
ProviderFlags:=[pfInUpdate, pfInWhere];
Required:=FALSE;
KeyFields:=CampoDataSet;//'CHIAVEPV';
end;
Table1.Open;
end;
l'arcano è tutto nella unit: Unit_CampoComboDBGrid
il codice che non va è il seguente:
function AddDBComboBoxToGrid(NomeNuovoCampo: string;DataSet: TDataSet; ...
Field:=TStringField.Create(DataSet);
with Field do
begin
...
Dataset:=DataSet;
...
end;
evidentemente il compilatore fa confusione nell'interpretare la prima occorrenza di 'DataSet' come proprietà di Field invece che come parametro..
togli il with o cambia nome al parametro ;)
Edit:
ok, ok è una cosa strana
però te la sei cercata :D :D :D