簡體   English   中英

“未找到 TBCDField 類” - Delphi 中的錯誤

[英]"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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM