我正在使用Delphi Seattle。
我有下面的构造函数,并且在执行第一个语句时,我收到错误“找不到类TBCDField”。
constructor TFrmMyForm.Create(AOwner:Tcomponent; AParam1:Real; var AParam2:Real);
begin
inherited Create(AOwner); //This statement is giving an error
FValue1 := AParam1;
FValue2 := AParam2;
end;
我用谷歌搜索但没有获得相关信息,并且还尝试将下面的语句放在try..except块中,但没有得到其他异常消息,我可以看到导致问题的原因。
inherited Create(AOwner);
TFrmMyForm派生自TForm类。
类TBCDField如下:
TBCDField = class(TNumericField)
private
FCurrency: Boolean;
FCheckRange: Boolean;
FMinValue: Currency;
FMaxValue: Currency;
FPrecision: Integer;
procedure SetCurrency(Value: Boolean);
procedure SetMaxValue(Value: Currency);
procedure SetMinValue(Value: Currency);
procedure SetPrecision(Value: Integer);
procedure UpdateCheckRange;
protected
class procedure CheckTypeSize(Value: Integer); override;
procedure CopyData(Source, Dest: TValueBuffer); overload; override;
{$IFNDEF NEXTGEN}
procedure CopyData(Source, Dest: Pointer); overload; override; deprecated 'Use overloaded method instead';
{$ENDIF !NEXTGEN}
function GetAsBCD: TBcd; override;
function GetAsCurrency: Currency; override;
function GetAsSingle: Single; override;
function GetAsFloat: Double; override;
function GetAsInteger: Longint; override;
function GetAsLargeInt: Largeint; override;
function GetAsLongWord: LongWord; override;
function GetAsString: string; override;
function GetAsVariant: Variant; override;
function GetDataSize: Integer; override;
function GetDefaultWidth: Integer; override;
procedure GetText(var Text: string; DisplayText: Boolean); override;
function GetValue(var Value: Currency): Boolean;
procedure SetAsBCD(const Value: TBcd); override;
procedure SetAsCurrency(Value: Currency); override;
procedure SetAsSingle(Value: Single); override;
procedure SetAsFloat(Value: Double); override;
procedure SetAsInteger(Value: Longint); override;
procedure SetAsLargeInt(Value: Largeint); override;
procedure SetAsLongWord(Value: LongWord); override;
procedure SetAsString(const Value: string); override;
procedure SetVarValue(const Value: Variant); override;
public
constructor Create(AOwner: TComponent); override;
procedure SetFieldProps(FieldDef: TFieldDef); override;
procedure SetFieldDefProps(FieldDef: TFieldDef); override;
property Value: Currency read GetAsCurrency write SetAsCurrency;
published
{ Lowercase to avoid name clash with C++ Currency type }
[Default(False)]
property currency: Boolean read FCurrency write SetCurrency default False;
property MaxValue: Currency read FMaxValue write SetMaxValue;
property MinValue: Currency read FMinValue write SetMinValue;
[Default(0)]
property Precision: Integer read FPrecision write SetPrecision default 0;
[Default(4)]
property Size default 4;
end;
{ TBCDField }
constructor TBCDField.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
SetDataType(ftBCD);
Size := 4;
ValidChars := [FormatSettings.DecimalSeparator, '+', '-', '0'..'9'];
end;
procedure TBCDField.SetFieldProps(FieldDef: TFieldDef);
begin
inherited SetFieldProps(FieldDef);
Precision := FieldDef.Precision;
end;
procedure TBCDField.SetFieldDefProps(FieldDef: TFieldDef);
begin
inherited SetFieldDefProps(FieldDef);
FieldDef.Precision := Precision;
end;
class procedure TBCDField.CheckTypeSize(Value: Integer);
begin
{ For BCD fields, the scale is stored in the size property.
We allow values up to 32 here even though the currency data type
only supports up to 4 digits of scale. The developer can check
for sizes > 4 to determine if the value from the server may have
been rounded }
if Value > 32 then DatabaseError(SInvalidFieldSize);
end;
function TBCDField.GetAsBCD: TBcd;
var
C: System.Currency;
begin
if GetValue(C) then CurrToBcd(C, Result) else Result := NullBcd;
end;
function TBCDField.GetAsCurrency: Currency;
begin
if not GetValue(Result) then Result := 0;
end;
function TBCDField.GetAsFloat: Double;
begin
Result := GetAsCurrency;
end;
function TBCDField.GetAsInteger: Longint;
begin
Result := Longint(Round(GetAsCurrency));
end;
function TBCDField.GetAsLargeint: Largeint;
begin
Result := Largeint(Round(GetAsCurrency));
end;
function TBCDField.GetAsLongWord: LongWord;
begin
Result := LongWord(Round(GetAsCurrency));
end;
function TBCDField.GetAsSingle: Single;
begin
Result := GetAsCurrency;
end;
function TBCDField.GetAsString: string;
var
C: System.Currency;
begin
if GetValue(C) then Result := CurrToStr(C) else Result := '';
end;
function TBCDField.GetAsVariant: Variant;
var
C: System.Currency;
begin
if GetValue(C) then Result := C else Result := Null;
end;
function TBCDField.GetDataSize: Integer;
begin
// SizeOf(TBcd) is used here instead of SizeOf(Currency) because some
// datasets store the currency data in TBcd format in the record buffer.
// For these classes (TBDEDataset & TClientDataset) a call to
// TField.GetData(Buffer, True) will return a TBcd.
Result := SizeOf(TBcd);
end;
function TBCDField.GetDefaultWidth: Integer;
begin
if FPrecision > 0 then
Result := FPrecision + 1 else
Result := inherited GetDefaultWidth;
end;
procedure TBCDField.GetText(var Text: string; DisplayText: Boolean);
var
C: System.Currency;
Format: TFloatFormat;
Digits: Integer;
FmtStr: string;
begin
try
if GetValue(C) then
begin
if DisplayText or (EditFormat = '') then
FmtStr := DisplayFormat
else
FmtStr := EditFormat;
if FmtStr = '' then
begin
if FCurrency then
begin
if DisplayText then Format := ffCurrency else Format := ffFixed;
Digits := FormatSettings.CurrencyDecimals;
end
else
begin
Format := ffGeneral;
Digits := 0;
end;
Text := CurrToStrF(C, Format, Digits);
end
else
Text := FormatCurr(FmtStr, C);
end
else
Text := '';
except
on E: Exception do
Text := SBCDOverflow;
end;
end;
function TBCDField.GetValue(var Value: Currency): Boolean;
begin
Result := GetData(FIOBuffer, False);
if Result then
Value := TDBBitConverter.UnsafeInto<System.Currency>(FIOBuffer);
end;
procedure TBCDField.SetAsBCD(const Value: TBcd);
var
C: System.Currency;
begin
BcdToCurr(Value, C);
SetAsCurrency(C);
end;
procedure TBCDField.SetAsCurrency(Value: Currency);
begin
if FCheckRange and ((Value < FMinValue) or (Value > FMaxValue)) then
RangeError(Value, FMinValue, FMaxValue);
if FIOBuffer <> nil then
TDBBitConverter.UnsafeFrom<System.Currency>(Value, FIOBuffer);
SetData(FIOBuffer, False);
end;
procedure TBCDField.SetAsFloat(Value: Double);
begin
SetAsCurrency(Value);
end;
procedure TBCDField.SetAsInteger(Value: Longint);
begin
SetAsCurrency(Value);
end;
procedure TBCDField.SetAsLargeint(Value: Largeint);
begin
SetAsCurrency(Value);
end;
procedure TBCDField.SetAsLongWord(Value: LongWord);
begin
SetAsCurrency(Value);
end;
procedure TBCDField.SetAsSingle(Value: Single);
begin
SetAsCurrency(Value);
end;
procedure TBCDField.SetAsString(const Value: string);
var
C: System.Currency;
begin
if Value = '' then Clear else
begin
if not TextToFloat(PChar(Value), C, fvCurrency) then
InvalidFloatValue(Value);
SetAsCurrency(C);
end;
end;
procedure TBCDField.SetCurrency(Value: Boolean);
begin
if FCurrency <> Value then
begin
FCurrency := Value;
PropertyChanged(False);
end;
end;
procedure TBCDField.SetMaxValue(Value: Currency);
begin
FMaxValue := Value;
UpdateCheckRange;
end;
procedure TBCDField.SetMinValue(Value: Currency);
begin
FMinValue := Value;
UpdateCheckRange;
end;
procedure TBCDField.SetPrecision(Value: Integer);
begin
if (DataSet <> nil) then
DataSet.CheckInactive;
if Value < 0 then Value := 0;
if Value > 32 then Value := 32;
if FPrecision <> Value then
begin
FPrecision := Value;
PropertyChanged(False);
end;
end;
procedure TBCDField.SetVarValue(const Value: Variant);
begin
SetAsCurrency(Value);
end;
procedure TBCDField.UpdateCheckRange;
begin
FCheckRange := (FMinValue <> 0) or (FMaxValue <> 0);
end;
procedure TBCDField.CopyData(Source, Dest: TValueBuffer);
begin
Move(Source[0], Dest[0], SizeOf(System.Currency));
end;
{$IFNDEF NEXTGEN}
procedure TBCDField.CopyData(Source, Dest: Pointer);
begin
System.Currency(Dest^) := System.Currency(Source^);
end;
{$ENDIF !NEXTGEN}
{ TFMTBCDField }
constructor TFMTBCDField.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
SetDataType(ftFMTBCD);
Size := 8;
ValidChars := [FormatSettings.DecimalSeparator, '+', '-', '0'..'9'];
FMinValue := '';
FMaxValue := '';
end;
procedure TFMTBCDField.SetFieldProps(FieldDef: TFieldDef);
begin
inherited SetFieldProps(FieldDef);
Precision := FieldDef.Precision;
end;
procedure TFMTBCDField.SetFieldDefProps(FieldDef: TFieldDef);
begin
inherited SetFieldDefProps(FieldDef);
FieldDef.Precision := Precision;
end;
class procedure TFMTBCDField.CheckTypeSize(Value: Integer);
begin
{ For BCD fields, the scale is stored in the size property.
We allow values up to 32 here even though the currency data type
only supports up to 4 digits of scale. The developer can check
for sizes > 4 to determine if the value from the server may have
been rounded }
if Value > MAXFMTBcdFractionSize then DatabaseError(SInvalidFieldSize);
end;
function TFMTBCDField.GetAsBCD: TBcd;
begin
if not GetValue(Result) then Result := NullBcd;
end;
function TFMTBCDField.GetAsCurrency: Currency;
begin
Result := GetAsFloat;
end;
function TFMTBCDField.GetAsFloat: Double;
var
bcd: TBcd;
begin
if GetValue(bcd) then Result := BcdToDouble(bcd) else Result := 0;
end;
function TFMTBCDField.GetAsInteger: Longint;
begin
Result := Longint(Round(GetAsFloat));
end;
function TFMTBCDField.GetAsLargeInt: Largeint;
begin
Result := Largeint(Round(GetAsFloat));
end;
function TFMTBCDField.GetAsLongWord: LongWord;
begin
Result := LongWord(Round(GetAsFloat));
end;
function TFMTBCDField.GetAsSingle: Single;
var
bcd: TBcd;
begin
if GetValue(bcd) then Result := BcdToDouble(bcd) else Result := 0;
end;
function TFMTBCDField.GetAsString: string;
var
bcd: TBcd;
begin
if GetValue(bcd) then Result := BcdToStr(bcd) else Result := '';
end;
function TFMTBCDField.GetAsVariant: Variant;
var
Bcd: TBcd;
begin
if GetValue(Bcd) then Result := VarFMTBcdCreate(Bcd) else Result := Null;
end;
function TFMTBCDField.GetDataSize: Integer;
begin
Result := SizeOf(TBcd);
end;
function TFMTBCDField.GetDefaultWidth: Integer;
begin
if FPrecision > 0 then
Result := FPrecision + 1 else
Result := inherited GetDefaultWidth;
end;
procedure TFMTBCDField.GetText(var Text: string; DisplayText: Boolean);
var
bcd: TBcd;
Format: TFloatFormat;
Digits: Integer;
FmtStr: string;
begin
try
if GetValue(bcd) then
begin
if DisplayText or (EditFormat = '') then
FmtStr := DisplayFormat
else
FmtStr := EditFormat;
if FmtStr = '' then
begin
if FCurrency then
begin
if DisplayText then Format := ffCurrency else Format := ffFixed;
Digits := FormatSettings.CurrencyDecimals;
end
else begin
Format := ffGeneral;
Digits := 0;
end;
Text := BcdToStrF(bcd, Format, FPrecision, Digits);
end
else
Text := FormatBcd(FmtStr, bcd);
end
else
Text := '';
except
on E: Exception do
Text := SBCDOverflow;
end;
end;
function TFMTBCDField.GetValue(var Value: TBcd): Boolean;
var
iLen: Integer;
begin
Result := GetData(FIOBuffer, True);
if Result then begin
Value := TDBBitConverter.UnsafeInto<TBcd>(FIOBuffer);
iLen := (Value.Precision + 1) div 2;
if iLen < SizeOf(Value.Fraction) then
FillChar(Value.Fraction[iLen], SizeOf(Value.Fraction) - iLen, 0);
end;
end;
procedure TFMTBCDField.BcdRangeError(Value: Variant; Max, Min: string);
begin
DataBaseErrorFmt(sBcdFieldRangeError, [Value, Self.FieldName, Max, Min]);
end;
procedure TFMTBCDField.SetAsBCD(const Value: TBcd);
procedure DoCheckRange;
var
V, VMax, VMin: Variant;
begin
VMax := VarFMTBcdCreate(FMaxValue, Self.Precision, Self.Size);
VMin := VarFMTBcdCreate(FMinValue, Self.Precision, Self.Size);
V := VarFMTBcdCreate(Value);
if (V < VMin) or (V > VMax) then
BcdRangeError(V, VMin, VMax);
end;
begin
if FCheckRange then
DoCheckRange;
if FIOBuffer <> nil then
TDBBitConverter.UnsafeFrom<TBcd>(Value, FIOBuffer);
SetData(FIOBuffer, True);
end;
procedure TFMTBCDField.SetAsCurrency(Value: Currency);
var
LValue: TBcd;
begin
CurrToBcd(Value, LValue, MaxBcdPrecision, MaxBcdScale);
SetAsBCD(LValue);
end;
procedure TFMTBCDField.SetAsFloat(Value: Double);
begin
SetAsCurrency(Value);
end;
procedure TFMTBCDField.SetAsInteger(Value: Longint);
begin
SetAsCurrency(Value);
end;
procedure TFMTBCDField.SetAsLargeInt(Value: Largeint);
begin
SetAsCurrency(Value);
end;
procedure TFMTBCDField.SetAsLongWord(Value: LongWord);
begin
SetAsCurrency(Value);
end;
procedure TFMTBCDField.SetAsSingle(Value: Single);
begin
SetAsCurrency(Value);
end;
procedure TFMTBCDField.SetAsString(const Value: string);
var
Bcd: TBcd;
begin
if Value = '' then Clear else
begin
Bcd := StrToBcd(Value);
SetAsBCD(Bcd);
end;
end;
procedure TFMTBCDField.SetCurrency(Value: Boolean);
begin
if FCurrency <> Value then
begin
FCurrency := Value;
PropertyChanged(False);
end;
end;
procedure TFMTBCDField.SetMaxValue(Value: string);
begin
FMaxValue := Value;
UpdateCheckRange;
end;
procedure TFMTBCDField.SetMinValue(Value: string);
begin
FMinValue := Value;
UpdateCheckRange;
end;
procedure TFMTBCDField.SetPrecision(Value: Integer);
begin
if (DataSet <> nil) then
DataSet.CheckInactive;
if Value < 0 then Value := 0;
if Value > MaxFMTBcdFractionSize then Value := MaxFMTBcdFractionSize;
if FPrecision <> Value then
begin
FPrecision := Value;
PropertyChanged(False);
end;
end;
procedure TFMTBCDField.SetVarValue(const Value: Variant);
begin
SetAsBCD(VarToBcd(Value));
end;
procedure TFMTBCDField.UpdateCheckRange;
begin
FCheckRange := (FMinValue <> '') or (FMaxValue <> '');
end;
答案 0 :(得分:1)
问题已经解决。
刚才我使用 Delphi Parser 脚本实用程序获得了使用FireDac组件替换BDE数据访问组件的新信息。在这种情况下发生的是,在设计时创建的表/查询组件列,它们在.dfm文件中的类型保持正确,即TBCDFiled,但在.pas文件中它们是TFloatField。
编译时我没有任何错误。但是当我打开TBCDClass定义文件时,我收到了来自Delphi的消息,某些字段类型需要更正,你想纠正吗?我点击了每个字段的是按钮。
暂停应用程序,现在没有错误。
感谢MartynA提供的线索。干杯!!!!!!