[英]"Class TBCDField not found" - Error in Delphi
我正在使用德爾福西雅圖。
我有下面的構造函數,在執行第一條語句時,出現錯誤“未找到類 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;
問題已解決。
剛剛我得到了新的信息,即使用Delphi Parser腳本實用程序將 BDE 數據訪問組件替換為 FireDac 組件。 在這種情況下發生的情況是,表/查詢組件的列在設計時創建,它們在 .dfm 文件中的類型保持正確,即 TBCDFiled,但在 .pas 文件中它們是 TFloatField。
在編譯時我沒有任何錯誤。 但是當我打開 TBCDClass 定義文件時,我收到來自 Delphi 的消息,需要更正某某字段類型,您要更正嗎? 我為每個字段單擊“是”按鈕。
運行應用程序,現在沒有錯誤。
感謝 MartynA 提供線索。 干杯!!!!!!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.