分享
 
 
 

delphi7找不到TBDEClientDataSet控件的解决方案

王朝delphi·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

unit BDEClientDataSet;

interface

uses Windows, SysUtils, Variants, Classes, DB, DBCommon, Midas,

SqlTimSt, DBClient, DBLocal, Provider, DBTables;

type

{ TBDEQuery }

TBDEQuery = class(TQuery)

private

FKeyFields: string;

protected

function PSGetDefaultOrder: TIndexDef; override;

end;

{ TBDEClientDataSet }

TBDEClientDataSet = class(TCustomCachedDataSet)

private

FCommandText: string;

FCurrentCommand: string;

FDataSet: TBDEQuery;

FDatabase: TDataBase;

FLocalParams: TParams;

FStreamedActive: Boolean;

procedure CheckMasterSourceActive(MasterSource: TDataSource);

procedure SetDetailsActive(Value: Boolean);

function GetConnection: TDataBase;

function GetDataSet: TDataSet;

function GetMasterSource: TDataSource;

function GetMasterFields: string;

procedure SetConnection(Value: TDataBase);

procedure SetDataSource(Value: TDataSource);

procedure SetLocalParams;

procedure SetMasterFields(const Value: string);

procedure SetParamsFromSQL(const Value: string);

procedure SetSQL(const Value: string);

protected

function GetCommandText: String; override;

procedure Loaded; override;

procedure Notification(AComponent: TComponent; Operation: TOperation); override;

procedure SetActive(Value: Boolean); override;

procedure SetCommandText(Value: string); override;

public

constructor Create(AOwner: TComponent); override;

destructor Destroy; override;

procedure CloneCursor(Source: TCustomClientDataSet; Reset: Boolean;

KeepSettings: Boolean = False); override;

procedure GetFieldNames(List: TStrings); override;

function GetQuoteChar: String;

property DataSet: TDataSet read GetDataSet;

published

property Active;

property CommandText: string read GetCommandText write SetCommandText;

property DBConnection: TDataBase read GetConnection write SetConnection;

property MasterFields read GetMasterFields write SetMasterFields;

property MasterSource: TDataSource read GetMasterSource write SetDataSource;

end;

procedure Register;

implementation

uses BDEConst, MidConst;

type

{ TBDECDSParams }

TBDECDSParams = class(TParams)

private

FFieldName: TStrings;

protected

procedure ParseSelect(SQL: string);

public

constructor Create(Owner: TPersistent);

Destructor Destroy; override;

end;

constructor TBDECDSParams.Create(Owner: TPersistent);

begin

inherited;

FFieldName := TStringList.Create;

end;

destructor TBDECDSParams.Destroy;

begin

FreeAndNil(FFieldName);

inherited;

end;

procedure TBDECDSParams.ParseSelect(SQL: string);

const

SSelect = 'select';

var

FWhereFound: Boolean;

Start: PChar;

FName, Value: string;

SQLToken, CurSection, LastToken: TSQLToken;

Params: Integer;

begin

if Pos(' ' + SSelect + ' ', LowerCase(string(PChar(SQL)+8))) > 1 then Exit; // can't parse sub queries

Start := PChar(ParseSQL(PChar(SQL), True));

CurSection := stUnknown;

LastToken := stUnknown;

FWhereFound := False;

Params := 0;

repeat

repeat

SQLToken := NextSQLToken(Start, FName, CurSection);

if SQLToken in [stWhere] then

begin

FWhereFound := True;

LastToken := stWhere;

end else if SQLToken in [stTableName] then

begin

{ Check for owner qualified table name }

if Start^ = '.' then

NextSQLToken(Start, FName, CurSection);

end else

if (SQLToken = stValue) and (LastToken = stWhere) then

SQLToken := stFieldName;

if SQLToken in SQLSections then CurSection := SQLToken;

until SQLToken in [stFieldName, stEnd];

if FWhereFound and (SQLToken in [stFieldName]) then

repeat

SQLToken := NextSQLToken(Start, Value, CurSection);

if SQLToken in SQLSections then CurSection := SQLToken;

until SQLToken in [stEnd,stValue,stIsNull,stIsNotNull,stFieldName];

if Value='?' then

begin

FFieldName.Add(FName);

Inc(Params);

end;

until (Params = Count) or (SQLToken in [stEnd]);

end;

{ TBDEQuery }

function TBDEQuery.PSGetDefaultOrder: TIndexDef;

begin

if FKeyFields = '' then

Result := inherited PSGetDefaultOrder

else

begin // detail table default order

Result := TIndexDef.Create(nil);

Result.Options := [ixUnique]; // keyfield is unique

Result.Name := StringReplace(FKeyFields, ';', '_', [rfReplaceAll]);

Result.Fields := FKeyFields;

end;

end;

{ TBDEClientDataSet }

constructor TBDEClientDataSet.Create(AOwner: TComponent);

begin

inherited Create(AOwner);

FDataSet := TBDEQuery.Create(nil);

FDataSet.Name := Self.Name + 'DataSet1';

Provider.DataSet := FDataSet;

SqlDBType := typeBDE;

FLocalParams := TParams.Create;

end;

destructor TBDEClientDataSet.Destroy;

begin

FreeAndNil(FLocalParams);

FDataSet.Close;

FreeAndNil(FDataSet);

inherited Destroy;

end;

procedure TBDEClientDataSet.GetFieldNames(List: TStrings);

var

Opened: Boolean;

begin

Opened := (Active = False);

try

if Opened then

Open;

inherited GetFieldNames(List);

finally

if Opened then Close;

end;

end;

function TBDEClientDataSet.GetCommandText: string;

begin

Result := FCommandText;

end;

function TBDEClientDataSet.GetDataSet: TDataSet;

begin

Result := FDataSet as TDataSet;

end;

procedure TBDEClientDataSet.CheckMasterSourceActive(MasterSource: TDataSource);

begin

if Assigned(MasterSource) and Assigned(MasterSource.DataSet) then

if not MasterSource.DataSet.Active then

DatabaseError(SMasterNotOpen);

end;

procedure TBDEClientDataSet.SetParamsFromSQL(const Value: string);

var

DataSet: TQuery;

TableName, TempQuery, Q: string;

List: TBDECDSParams;

I: Integer;

Field: TField;

begin

TableName := GetTableNameFromSQL(Value);

if TableName <> '' then

begin

TempQuery := Value;

List := TBDECDSParams.Create(Self);

try

List.ParseSelect(TempQuery);

List.AssignValues(Params);

for I := 0 to List.Count - 1 do

List[I].ParamType := ptInput;

DataSet := TQuery.Create(nil);

try

DataSet.DatabaseName := FDataSet.DatabaseName;

Q := GetQuoteChar;

DataSet.SQL.Add('select * from ' + Q + TableName + Q + ' where 0 = 1'); { do not localize }

try

DataSet.Open;

for I := 0 to List.Count - 1 do

begin

if List.FFieldName.Count > I then

begin

try

Field := DataSet.FieldByName(List.FFieldName[I]);

except

Field := nil;

end;

end else

Field := nil;

if Assigned(Field) then

begin

if Field.DataType <> ftString then

List[I].DataType := Field.DataType

else if TStringField(Field).FixedChar then

List[I].DataType := ftFixedChar

else

List[I].DataType := ftString;

end;

end;

except

// ignore all exceptions

end;

finally

DataSet.Free;

end;

finally

if List.Count > 0 then

Params.Assign(List);

List.Free;

end;

end;

end;

procedure TBDEClientDataSet.SetSQL(const Value: string);

begin

if Assigned(Provider.DataSet) then

begin

TQuery(Provider.DataSet).SQL.Clear;

if Value <> '' then

TQuery(Provider.DataSet).SQL.Add(Value);

inherited SetCommandText(Value);

end else

DataBaseError(SNoDataProvider);

end;

procedure TBDEClientDataSet.Loaded;

begin

inherited Loaded;

if FStreamedActive then

begin

SetActive(True);

FStreamedActive := False;

end;

end;

function TBDEClientDataSet.GetMasterFields: string;

begin

Result := inherited MasterFields;

end;

procedure TBDEClientDataSet.SetMasterFields(const Value: string);

begin

inherited MasterFields := Value;

if Value <> '' then

IndexFieldNames := Value;

FDataSet.FKeyFields := '';

end;

procedure TBDEClientDataSet.SetCommandText(Value: String);

begin

inherited SetCommandText(Value);

FCommandText := Value;

if not (csLoading in ComponentState) then

begin

FDataSet.FKeyFields := '';

IndexFieldNames := '';

MasterFields := '';

IndexName := '';

IndexDefs.Clear;

Params.Clear;

if (csDesigning in ComponentState) and (Value <> '') then

SetParamsFromSQL(Value);

end;

end;

function TBDEClientDataSet.GetConnection: TDatabase;

begin

Result := FDataBase;

end;

procedure TBDEClientDataSet.SetConnection(Value: TDataBase);

begin

if Value = FDatabase then exit;

CheckInactive;

if Assigned(Value) then

begin

if not (csLoading in ComponentState) and (Value.DatabaseName = '') then

DatabaseError(SDatabaseNameMissing);

FDataSet.DatabaseName := Value.DatabaseName;

end else

FDataSet.DataBaseName := '';

FDataBase := Value;

end;

function TBDEClientDataSet.GetQuoteChar: String;

begin

Result := '';

if Assigned(FDataSet) then

Result := FDataSet.PSGetQuoteChar;

end;

procedure TBDEClientDataSet.CloneCursor(Source: TCustomClientDataSet; Reset: Boolean;

KeepSettings: Boolean = False);

begin

if not (Source is TBDEClientDataSet) then

DatabaseError(SInvalidClone);

Provider.DataSet := TBDEClientDataSet(Source).Provider.DataSet;

DBConnection := TBDEClientDataSet(Source).DBConnection;

CommandText := TBDEClientDataSet(Source).CommandText;

inherited CloneCursor(Source, Reset, KeepSettings);

end;

procedure TBDEClientDataSet.Notification(AComponent: TComponent; Operation: TOperation);

begin

inherited Notification(AComponent, Operation);

if Operation = opRemove then

if AComponent = FDatabase then

begin

FDataBase := nil;

SetActive(False);

end;

end;

procedure TBDEClientDataSet.SetLocalParams;

procedure CreateParamsFromMasterFields(Create: Boolean);

var

I: Integer;

List: TStrings;

begin

List := TStringList.Create;

try

if Create then

FLocalParams.Clear;

FDataSet.FKeyFields := MasterFields;

List.CommaText := MasterFields;

for I := 0 to List.Count -1 do

begin

if Create then

FLocalParams.CreateParam( ftUnknown, MasterSource.DataSet.FieldByName(List[I]).FieldName,

ptInput);

FLocalParams[I].AssignField(MasterSource.DataSet.FieldByName(List[I]));

end;

finally

List.Free;

end;

end;

begin

if (MasterFields <> '') and Assigned(MasterSource) and Assigned(MasterSource.DataSet) then

begin

CreateParamsFromMasterFields(True);

FCurrentCommand := AddParamSQLForDetail(FLocalParams, CommandText, True, GetQuoteChar);

end;

end;

procedure TBDEClientDataSet.SetDataSource(Value: TDataSource);

begin

inherited MasterSource := Value;

if Assigned(Value) then

begin

if PacketRecords = -1 then PacketRecords := 0;

end else

begin

if PacketRecords = 0 then PacketRecords := -1;

end;

end;

function TBDEClientDataSet.GetMasterSource: TDataSource;

begin

Result := inherited MasterSource;

end;

procedure TBDEClientDataSet.SetDetailsActive(Value: Boolean);

var

DetailList: TList;

I: Integer;

begin

DetailList := TList.Create;

try

GetDetailDataSets(DetailList);

for I := 0 to DetailList.Count -1 do

if TDataSet(DetailList[I]) is TBDEClientDataSet then

TBDEClientDataSet(TDataSet(DetailList[I])).Active := Value;

finally

DetailList.Free;

end;

end;

procedure TBDEClientDataSet.SetActive(Value: Boolean);

begin

if Value then

begin

if csLoading in ComponentState then

begin

FStreamedActive := True;

exit;

end;

if MasterFields <> '' then

begin

if not (csLoading in ComponentState) then

CheckMasterSourceActive(MasterSource);

SetLocalParams;

SetSQL(FCurrentCommand);

Params := FLocalParams;

FetchParams;

end else

begin

SetSQL(FCommandText);

if Params.Count > 0 then

begin

FDataSet.Params := Params;

FetchParams;

end;

end;

end;

if Value and (FDataSet.ObjectView <> ObjectView) then

FDataSet.ObjectView := ObjectView;

inherited SetActive(Value);

SetDetailsActive(Value);

end;

procedure Register;

begin

RegisterComponents('BDE', [TBDEClientDataSet]);

end;

end.

//以上经DBLocalB.pas改装而成,可存为任意文件名,当然扩展名是PAS

//然后安装此控件即可

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有