834 lines
20 KiB
ObjectPascal
834 lines
20 KiB
ObjectPascal
|
|
{******************************************}
|
|
{ }
|
|
{ FastReport FMX v1.0 }
|
|
{ Custom TDataSet-based classes }
|
|
{ for enduser DB components }
|
|
{ }
|
|
{ Copyright (c) 1998-2013 }
|
|
{ by Alexander Tzyganenko, }
|
|
{ Fast Reports Inc. }
|
|
{ }
|
|
{******************************************}
|
|
|
|
unit FMX.frxCustomDB;
|
|
|
|
interface
|
|
|
|
{$I frx.inc}
|
|
|
|
uses
|
|
System.Classes, System.SysUtils, Data.DB, FMX.frxClass, FMX.frxDBSet,
|
|
FMX.ListBox, System.Variants, System.Types, FMX.Types
|
|
{$IFDEF QBUILDER}
|
|
, FMX.fqbClass
|
|
{$ENDIF}
|
|
{$IFDEF DELPHI19}
|
|
, FMX.Graphics
|
|
{$ENDIF};
|
|
|
|
|
|
type
|
|
TfrxCustomDataset = class(TfrxDBDataSet)
|
|
private
|
|
FDBConnected: Boolean;
|
|
FDataSource: TDataSource;
|
|
FMaster: TfrxDBDataSet;
|
|
FMasterFields: String;
|
|
procedure SetActive(Value: Boolean);
|
|
procedure SetFilter(const Value: String);
|
|
procedure SetFiltered(Value: Boolean);
|
|
function GetActive: Boolean;
|
|
function GetFields: TFields;
|
|
function GetFilter: String;
|
|
function GetFiltered: Boolean;
|
|
procedure InternalSetMaster(const Value: TfrxDBDataSet);
|
|
procedure InternalSetMasterFields(const Value: String);
|
|
protected
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
procedure SetParent(AParent: TfrxComponent); override;
|
|
procedure SetUserName(const Value: String); override;
|
|
procedure SetMaster(const Value: TDataSource); virtual;
|
|
procedure SetMasterFields(const Value: String); virtual;
|
|
property DataSet;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure OnPaste; override;
|
|
property DBConnected: Boolean read FDBConnected write FDBConnected;
|
|
property Fields: TFields read GetFields;
|
|
property MasterFields: String read FMasterFields write InternalSetMasterFields;
|
|
property Active: Boolean read GetActive write SetActive default False;
|
|
published
|
|
property Filter: String read GetFilter write SetFilter;
|
|
property Filtered: Boolean read GetFiltered write SetFiltered default False;
|
|
property Master: TfrxDBDataset read FMaster write InternalSetMaster;
|
|
end;
|
|
|
|
TfrxCustomTable = class(TfrxCustomDataset)
|
|
protected
|
|
function GetIndexFieldNames: String; virtual;
|
|
function GetIndexName: String; virtual;
|
|
function GetTableName: String; virtual;
|
|
procedure SetIndexFieldNames(const Value: String); virtual;
|
|
procedure SetIndexName(const Value: String); virtual;
|
|
procedure SetTableName(const Value: String); virtual;
|
|
property DataSet;
|
|
published
|
|
property MasterFields;
|
|
property TableName: String read GetTableName write SetTableName;
|
|
property IndexName: String read GetIndexName write SetIndexName;
|
|
property IndexFieldNames: String read GetIndexFieldNames write SetIndexFieldNames;
|
|
end;
|
|
|
|
TfrxParamItem = class(TCollectionItem)
|
|
private
|
|
FDataType: TFieldType;
|
|
FExpression: String;
|
|
FName: String;
|
|
FValue: Variant;
|
|
public
|
|
procedure Assign(Source: TPersistent); override;
|
|
property Value: Variant read FValue write FValue;
|
|
published
|
|
property Name: String read FName write FName;
|
|
property DataType: TFieldType read FDataType write FDataType;
|
|
property Expression: String read FExpression write FExpression;
|
|
end;
|
|
|
|
TfrxParams = class(TCollection)
|
|
private
|
|
FIgnoreDuplicates: Boolean;
|
|
function GetParam(Index: Integer): TfrxParamItem;
|
|
public
|
|
constructor Create;
|
|
function Add: TfrxParamItem;
|
|
function Find(const Name: String): TfrxParamItem;
|
|
function IndexOf(const Name: String): Integer;
|
|
procedure UpdateParams(const SQL: String);
|
|
property Items[Index: Integer]: TfrxParamItem read GetParam; default;
|
|
property IgnoreDuplicates: Boolean read FIgnoreDuplicates write FIgnoreDuplicates;
|
|
end;
|
|
|
|
|
|
TfrxCustomQuery = class(TfrxCustomDataset)
|
|
private
|
|
FParams: TfrxParams;
|
|
FSaveOnBeforeOpen: TDataSetNotifyEvent;
|
|
FSaveOnChange: TNotifyEvent;
|
|
FSQLSchema: String;
|
|
procedure ReadData(Reader: TReader);
|
|
procedure SetParams(Value: TfrxParams);
|
|
procedure WriteData(Writer: TWriter);
|
|
function GetIgnoreDupParams: Boolean;
|
|
procedure SetIgnoreDupParams(const Value: Boolean);
|
|
protected
|
|
procedure DefineProperties(Filer: TFiler); override;
|
|
procedure OnBeforeOpen(DataSet: TDataSet); virtual;
|
|
procedure OnChangeSQL(Sender: TObject); virtual;
|
|
procedure SetSQL(Value: TStrings); virtual;
|
|
function GetSQL: TStrings; virtual;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure UpdateParams; virtual;
|
|
function ParamByName(const Value: String): TfrxParamItem;
|
|
{$IFDEF QBUILDER}
|
|
function QBEngine: TfqbEngine; virtual;
|
|
{$ENDIF}
|
|
published
|
|
property IgnoreDupParams: Boolean read GetIgnoreDupParams write SetIgnoreDupParams;
|
|
property Params: TfrxParams read FParams write SetParams;
|
|
property SQL: TStrings read GetSQL write SetSQL;
|
|
property SQLSchema: String read FSQLSchema write FSQLSchema;
|
|
end;
|
|
|
|
{ emulates work of DBLookupComboBox in VCL, for back compatibility only }
|
|
TfrxDBLookupComboBox = class(TfrxDialogControl)
|
|
private
|
|
FDataSet: TfrxDBDataSet;
|
|
FDataSetName: String;
|
|
FComboBox: TComboBox;
|
|
FAutoOpenDataSet: Boolean;
|
|
FIsFilled: Boolean;
|
|
FListField: String;
|
|
FKeyField: String;
|
|
FValue: Variant;
|
|
function GetDataSetName: String;
|
|
function GetKeyField: String;
|
|
function GetKeyValue: Variant;
|
|
function GetListField: String;
|
|
function GetText: String;
|
|
procedure SetDataSet(const Value: TfrxDBDataSet);
|
|
procedure SetDataSetName(const Value: String);
|
|
procedure SetKeyField(Value: String);
|
|
procedure SetKeyValue(const Value: Variant);
|
|
procedure SetListField(Value: String);
|
|
procedure UpdateDataSet;
|
|
procedure OnOpenDS(Sender: TObject);
|
|
function GetDropDownWidth: Integer;
|
|
procedure SetDropDownWidth(const Value: Integer);
|
|
function GetDropDownRows: Integer;
|
|
procedure SetDropDownRows(const Value: Integer);
|
|
procedure DoOnChange(Sender: TObject);
|
|
procedure FillWithData;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
class function GetDescription: String; override;
|
|
procedure BeforeStartReport; override;
|
|
property ComboBox: TComboBox read FComboBox;
|
|
property KeyValue: Variant read GetKeyValue write FValue;
|
|
property Text: String read GetText;
|
|
procedure PaintControl(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
|
|
published
|
|
property AutoOpenDataSet: Boolean read FAutoOpenDataSet write FAutoOpenDataSet default False;
|
|
property DataSet: TfrxDBDataset read FDataSet write SetDataSet;
|
|
property DataSetName: String read GetDataSetName write SetDataSetName;
|
|
property ListField: String read GetListField write SetListField;
|
|
property KeyField: String read GetKeyField write SetKeyField;
|
|
property DropDownWidth: Integer read GetDropDownWidth write SetDropDownWidth;
|
|
property DropDownRows: Integer read GetDropDownRows write SetDropDownRows;
|
|
property OnClick;
|
|
property OnDblClick;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnKeyDown;
|
|
property OnKeyPress;
|
|
property OnKeyUp;
|
|
property OnMouseDown;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
end;
|
|
|
|
|
|
procedure frxParamsToTParams(Query: TfrxCustomQuery; Params: TParams);
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFNDEF NO_EDITORS}
|
|
FMX.frxCustomDBEditor,
|
|
{$ENDIF}
|
|
FMX.frxCustomDBRTTI, FMX.frxDsgnIntf, FMX.frxUtils, FMX.frxRes;
|
|
|
|
|
|
{ TfrxParamItem }
|
|
|
|
procedure TfrxParamItem.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TfrxParamItem then
|
|
begin
|
|
FName := TfrxParamItem(Source).Name;
|
|
FDataType := TfrxParamItem(Source).DataType;
|
|
FExpression := TfrxParamItem(Source).Expression;
|
|
FValue := TfrxParamItem(Source).Value;
|
|
end;
|
|
end;
|
|
|
|
{ TfrxParams }
|
|
|
|
constructor TfrxParams.Create;
|
|
begin
|
|
inherited Create(TfrxParamItem);
|
|
FIgnoreDuplicates := False;
|
|
end;
|
|
|
|
function TfrxParams.Add: TfrxParamItem;
|
|
begin
|
|
Result := TfrxParamItem(inherited Add);
|
|
end;
|
|
|
|
function TfrxParams.GetParam(Index: Integer): TfrxParamItem;
|
|
begin
|
|
Result := TfrxParamItem(inherited Items[Index]);
|
|
end;
|
|
|
|
function TfrxParams.Find(const Name: String): TfrxParamItem;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
i := IndexOf(Name);
|
|
if i <> -1 then
|
|
Result := Items[i] else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TfrxParams.IndexOf(const Name: String): Integer;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := -1;
|
|
for i := 0 to Count - 1 do
|
|
if CompareText(Items[i].Name, Name) = 0 then
|
|
begin
|
|
Result := i;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrxParams.UpdateParams(const SQL: String);
|
|
var
|
|
i, j: Integer;
|
|
QParams: TParams;
|
|
NewParams: TfrxParams;
|
|
begin
|
|
{ parse query params }
|
|
QParams := TParams.Create;
|
|
QParams.ParseSQL(SQL, True);
|
|
|
|
{ create new TfrxParams object and copy all params to it }
|
|
NewParams := TfrxParams.Create;
|
|
for i := 0 to QParams.Count - 1 do
|
|
if not ((NewParams.IndexOf(QParams[i].Name) <> -1) and FIgnoreDuplicates) then
|
|
with NewParams.Add do
|
|
begin
|
|
Name := QParams[i].Name;
|
|
j := IndexOf(Name);
|
|
if j <> -1 then
|
|
begin
|
|
DataType := Items[j].DataType;
|
|
Value := Items[j].Value;
|
|
Expression := Items[j].Expression;
|
|
end;
|
|
end;
|
|
Assign(NewParams);
|
|
QParams.Free;
|
|
NewParams.Free;
|
|
end;
|
|
|
|
{ TfrxCustomDataset }
|
|
|
|
constructor TfrxCustomDataset.Create(AOwner: TComponent);
|
|
begin
|
|
Component := Dataset;
|
|
inherited;
|
|
CloseDataSource := True;
|
|
FDataSource := TDataSource.Create(nil);
|
|
SetMaster(FDataSource);
|
|
end;
|
|
|
|
destructor TfrxCustomDataset.Destroy;
|
|
begin
|
|
FDataSource.Free;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.Notification(AComponent: TComponent;
|
|
Operation: TOperation);
|
|
begin
|
|
inherited;
|
|
if Operation = opRemove then
|
|
if AComponent = FMaster then
|
|
Master := nil
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.SetParent(AParent: TfrxComponent);
|
|
begin
|
|
inherited;
|
|
if (AParent <> nil) and (Report <> nil) then
|
|
begin
|
|
if IsDesigning and (Report.DataSets.Find(Self) = nil) then
|
|
begin
|
|
Report.DataSets.Add(Self);
|
|
if Report.Designer <> nil then
|
|
Report.Designer.UpdateDataTree;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.SetUserName(const Value: String);
|
|
begin
|
|
inherited;
|
|
if (Report <> nil) and (Report.Designer <> nil) then
|
|
Report.Designer.UpdateDataTree;
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.OnPaste;
|
|
var
|
|
i: Integer;
|
|
sl: TStringList;
|
|
begin
|
|
if Report = nil then Exit;
|
|
|
|
if Report.DataSets.Find(Self) = nil then
|
|
Report.DataSets.Add(Self);
|
|
|
|
sl := TStringList.Create;
|
|
|
|
Report.GetDatasetList(sl);
|
|
for i := 0 to sl.Count - 1 do
|
|
if (sl.Objects[i] <> Self) and (CompareText(sl[i], UserName) = 0) then
|
|
begin
|
|
if Name <> '' then
|
|
UserName := Name;
|
|
break;
|
|
end;
|
|
sl.Free;
|
|
|
|
Report.Designer.UpdateDataTree;
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.SetActive(Value: Boolean);
|
|
begin
|
|
Dataset.Active := Value;
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.SetFilter(const Value: String);
|
|
begin
|
|
Dataset.Filter := Value;
|
|
end;
|
|
|
|
function TfrxCustomDataset.GetActive: Boolean;
|
|
begin
|
|
Result := Dataset.Active;
|
|
end;
|
|
|
|
function TfrxCustomDataset.GetFields: TFields;
|
|
begin
|
|
Result := Dataset.Fields;
|
|
end;
|
|
|
|
function TfrxCustomDataset.GetFilter: String;
|
|
begin
|
|
Result := Dataset.Filter;
|
|
end;
|
|
|
|
function TfrxCustomDataset.GetFiltered: Boolean;
|
|
begin
|
|
Result := Dataset.Filtered;
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.SetFiltered(Value: Boolean);
|
|
begin
|
|
Dataset.Filtered := Value;
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.InternalSetMaster(const Value: TfrxDBDataSet);
|
|
begin
|
|
FMaster := Value;
|
|
if FMaster <> nil then
|
|
FDataSource.DataSet := FMaster.GetDataSet
|
|
else
|
|
FDataSource.DataSet := nil;
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.InternalSetMasterFields(const Value: String);
|
|
var
|
|
sl: TStringList;
|
|
s: String;
|
|
i: Integer;
|
|
|
|
function ConvertAlias(const s: String): String;
|
|
begin
|
|
if FMaster <> nil then
|
|
Result := FMaster.ConvertAlias(s)
|
|
else
|
|
Result := s;
|
|
end;
|
|
|
|
begin
|
|
FMasterFields := Value;
|
|
|
|
sl := TStringList.Create;
|
|
frxSetCommaText(Value, sl);
|
|
s := '';
|
|
for i := 0 to sl.Count - 1 do
|
|
s := s + ConvertAlias(sl.Values[sl.Names[i]]) + ';';
|
|
s := Copy(s, 1, Length(s) - 1);
|
|
|
|
SetMasterFields(s);
|
|
|
|
s := '';
|
|
for i := 0 to sl.Count - 1 do
|
|
s := s + ConvertAlias(sl.Names[i]) + ';';
|
|
s := Copy(s, 1, Length(s) - 1);
|
|
|
|
if Self is TfrxCustomTable then
|
|
TfrxCustomTable(Self).SetIndexFieldNames(s);
|
|
|
|
sl.Free;
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.SetMaster(const Value: TDataSource);
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
procedure TfrxCustomDataset.SetMasterFields(const Value: String);
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
|
|
{ TfrxCustomTable }
|
|
|
|
function TfrxCustomTable.GetIndexFieldNames: String;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TfrxCustomTable.GetIndexName: String;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TfrxCustomTable.GetTableName: String;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
procedure TfrxCustomTable.SetIndexFieldNames(const Value: String);
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
procedure TfrxCustomTable.SetIndexName(const Value: String);
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
procedure TfrxCustomTable.SetTableName(const Value: String);
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
|
|
{ TfrxCustomQuery }
|
|
|
|
constructor TfrxCustomQuery.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
FParams := TfrxParams.Create;
|
|
FSaveOnBeforeOpen := DataSet.BeforeOpen;
|
|
DataSet.BeforeOpen := OnBeforeOpen;
|
|
FSaveOnChange := TStringList(SQL).OnChange;
|
|
TStringList(SQL).OnChange := OnChangeSQL;
|
|
end;
|
|
|
|
destructor TfrxCustomQuery.Destroy;
|
|
begin
|
|
FParams.Free;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TfrxCustomQuery.DefineProperties(Filer: TFiler);
|
|
begin
|
|
inherited;
|
|
Filer.DefineProperty('Parameters', ReadData, WriteData, True);
|
|
end;
|
|
|
|
procedure TfrxCustomQuery.ReadData(Reader: TReader);
|
|
begin
|
|
frxReadCollection(FParams, Reader, Self);
|
|
UpdateParams;
|
|
end;
|
|
|
|
procedure TfrxCustomQuery.WriteData(Writer: TWriter);
|
|
begin
|
|
frxWriteCollection(FParams, Writer, Self);
|
|
end;
|
|
|
|
procedure TfrxCustomQuery.OnBeforeOpen(DataSet: TDataSet);
|
|
begin
|
|
UpdateParams;
|
|
if Assigned(FSaveOnBeforeOpen) then
|
|
FSaveOnBeforeOpen(DataSet);
|
|
end;
|
|
|
|
procedure TfrxCustomQuery.OnChangeSQL(Sender: TObject);
|
|
begin
|
|
if Assigned(FSaveOnChange) then
|
|
FSaveOnChange(Sender);
|
|
FParams.UpdateParams(SQL.Text);
|
|
end;
|
|
|
|
procedure TfrxCustomQuery.SetParams(Value: TfrxParams);
|
|
begin
|
|
FParams.Assign(Value);
|
|
end;
|
|
|
|
function TfrxCustomQuery.ParamByName(const Value: String): TfrxParamItem;
|
|
begin
|
|
Result := FParams.Find(Value);
|
|
if Result = nil then
|
|
raise Exception.Create('Parameter "' + Value + '" not found');
|
|
end;
|
|
|
|
procedure TfrxCustomQuery.SetSQL(Value: TStrings);
|
|
begin
|
|
//
|
|
end;
|
|
|
|
function TfrxCustomQuery.GetSQL: TStrings;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TfrxCustomQuery.UpdateParams;
|
|
begin
|
|
//
|
|
end;
|
|
|
|
{$IFDEF QBUILDER}
|
|
function TfrxCustomQuery.QBEngine: TfqbEngine;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
{ frxParamsToTParams }
|
|
|
|
procedure frxParamsToTParams(Query: TfrxCustomQuery; Params: TParams);
|
|
var
|
|
i: Integer;
|
|
Item: TfrxParamItem;
|
|
begin
|
|
for i := 0 to Params.Count - 1 do
|
|
if Query.Params.IndexOf(Params[i].Name) <> -1 then
|
|
begin
|
|
Item := Query.Params[Query.Params.IndexOf(Params[i].Name)];
|
|
Params[i].Clear;
|
|
Params[i].DataType := Item.DataType;
|
|
{ Bound should be True in design mode }
|
|
if not (Query.IsLoading or Query.IsDesigning) then
|
|
Params[i].Bound := False
|
|
else
|
|
begin
|
|
if Item.Expression <> '' then
|
|
Params[i].Value := 0;
|
|
Params[i].Bound := True;
|
|
end;
|
|
|
|
if Trim(Item.Expression) <> '' then
|
|
if not (Query.IsLoading or Query.IsDesigning) then
|
|
if Query.Report <> nil then
|
|
begin
|
|
Query.Report.CurObject := Query.Name;
|
|
Item.Value := Query.Report.Calc(Item.Expression);
|
|
end;
|
|
if not VarIsEmpty(Item.Value) then
|
|
begin
|
|
Params[i].Bound := True;
|
|
if Params[i].DataType in [ftDate, ftTime, ftDateTime] then
|
|
Params[i].Value := Item.Value
|
|
else
|
|
Params[i].Text := VarToStr(Item.Value);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
function TfrxCustomQuery.GetIgnoreDupParams: Boolean;
|
|
begin
|
|
Result := FParams.FIgnoreDuplicates;
|
|
end;
|
|
|
|
procedure TfrxCustomQuery.SetIgnoreDupParams(const Value: Boolean);
|
|
begin
|
|
FParams.FIgnoreDuplicates := Value;
|
|
FParams.UpdateParams(SQL.Text);
|
|
end;
|
|
|
|
{ TfrxDBLookupComboBox }
|
|
|
|
constructor TfrxDBLookupComboBox.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
FComboBox := TComboBox.Create(nil);
|
|
InitControl(FComboBox);
|
|
Width := 145;
|
|
Height := 21;
|
|
FComboBox.OnPainting := PaintControl;
|
|
FIsFilled := False;
|
|
FComboBox.OnChange := DoOnChange;
|
|
// FDBLookupComboBox.ListSource := FDataSource;
|
|
end;
|
|
|
|
destructor TfrxDBLookupComboBox.Destroy;
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.DoOnChange(Sender: TObject);
|
|
begin
|
|
if (FDataSet <> nil) and FDataSet.HasField(FListField) and (FComboBox.Selected <> nil) then
|
|
begin
|
|
FDataSet.DataSet.Locate(FDataSet.ConvertAlias(FListField), FComboBox.Selected.Text, []);
|
|
if(FDataSet.HasField(FKeyField)) then
|
|
begin
|
|
FValue := FDataSet.Value[FKeyField];
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.FillWithData;
|
|
begin
|
|
if not FIsFilled then
|
|
begin
|
|
if FDataSet = nil then Exit;
|
|
if not FDataSet.HasField(FListField) then Exit;
|
|
FDataSet.First;
|
|
{$IFDEF DELPHI23}
|
|
FComboBox.Clear;
|
|
{$ELSE}
|
|
FComboBox.Items.Clear;
|
|
{$ENDIF}
|
|
FComboBox.BeginUpdate;
|
|
try
|
|
while not FDataSet.Eof do
|
|
begin
|
|
FComboBox.Items.Add(FDataSet.Value[FListField]);
|
|
FDataSet.Next;
|
|
end;
|
|
finally
|
|
FComboBox.EndUpdate;
|
|
end;
|
|
if FComboBox.Items.Count > 0 then
|
|
FComboBox.ListItems[0].IsSelected := True;
|
|
FIsFilled := True;
|
|
end;
|
|
end;
|
|
|
|
class function TfrxDBLookupComboBox.GetDescription: String;
|
|
begin
|
|
Result := frxResources.Get('obDBLookup');
|
|
end;
|
|
|
|
function TfrxDBLookupComboBox.GetDataSetName: String;
|
|
begin
|
|
if FDataSet = nil then
|
|
Result := FDataSetName else
|
|
Result := FDataSet.UserName;
|
|
end;
|
|
|
|
function TfrxDBLookupComboBox.GetKeyField: String;
|
|
begin
|
|
Result := FKeyField;
|
|
end;
|
|
|
|
function TfrxDBLookupComboBox.GetKeyValue: Variant;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TfrxDBLookupComboBox.GetListField: String;
|
|
begin
|
|
Result := FListField;
|
|
FDataSet := TfrxDBDataSet(Report.GetDataset(FDataSetName));
|
|
end;
|
|
|
|
function TfrxDBLookupComboBox.GetText: String;
|
|
begin
|
|
if FComboBox.Selected <> nil then
|
|
Result := FComboBox.Selected.Text;
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.SetDataSet(const Value: TfrxDBDataSet);
|
|
begin
|
|
FDataSet := Value;
|
|
if FDataSet = nil then
|
|
FDataSetName := '' else
|
|
FDataSetName := FDataSet.UserName;
|
|
UpdateDataSet;
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.SetDataSetName(const Value: String);
|
|
begin
|
|
FDataSetName := Value;
|
|
FDataSet := TfrxDBDataSet(FindDataSet(FDataSet, FDataSetName));
|
|
UpdateDataSet;
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.SetKeyField(Value: String);
|
|
begin
|
|
FKeyField := Value;
|
|
if FListField = '' then
|
|
FListField := FKeyField;
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.SetKeyValue(const Value: Variant);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if (FDataSet <> nil) and FDataSet.HasField(FKeyField) and FDataSet.HasField(FListField) then
|
|
begin
|
|
FillWithData;
|
|
FDataSet.DataSet.Locate(FDataSet.ConvertAlias(FKeyField), Value, []);
|
|
i := FComboBox.Items.IndexOf(FDataSet.Value[FListField]);
|
|
if i > 0 then
|
|
begin
|
|
FValue := Value;
|
|
FComboBox.ListItems[i].IsSelected := True;
|
|
FComboBox.ItemIndex := i;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.SetListField(Value: String);
|
|
begin
|
|
FListField := Value;
|
|
FIsFilled := False;
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.UpdateDataSet;
|
|
begin
|
|
FIsFilled := False;
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.BeforeStartReport;
|
|
begin
|
|
SetListField(FListField);
|
|
SetKeyField(FKeyField);
|
|
Self.OnActivate := OnOpenDS;
|
|
end;
|
|
|
|
|
|
procedure TfrxDBLookupComboBox.OnOpenDS(Sender: TObject);
|
|
begin
|
|
UpdateDataSet;
|
|
if (FDataSet <> nil) and (FAutoOpenDataSet) then
|
|
FDataSet.Open;
|
|
FIsFilled := False;
|
|
FillWithData;
|
|
SetKeyValue(FValue);
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.PaintControl(Sender: TObject; Canvas: TCanvas;
|
|
const ARect: TRectF);
|
|
begin
|
|
FillWithData;
|
|
end;
|
|
|
|
function TfrxDBLookupComboBox.GetDropDownWidth: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.SetDropDownWidth(const Value: Integer);
|
|
begin
|
|
//FDBLookupComboBox.DropDownWidth := Value;
|
|
end;
|
|
|
|
function TfrxDBLookupComboBox.GetDropDownRows: Integer;
|
|
begin
|
|
Result := FComboBox.DropDownCount;
|
|
end;
|
|
|
|
procedure TfrxDBLookupComboBox.SetDropDownRows(const Value: Integer);
|
|
begin
|
|
FComboBox.DropDownCount := Value;;
|
|
end;
|
|
|
|
initialization
|
|
frxObjects.RegisterObject1(TfrxDBLookupComboBox, nil, '', '', 0, 119);
|
|
|
|
finalization
|
|
frxObjects.UnRegister(TfrxDBLookupComboBox);
|
|
|
|
|
|
end.
|