如果还有datetime字段,Delphi 10.4无法在DBGrids上显示十进制(5,2)BCD字段

如果还有datetime字段,Delphi 10.4无法在DBGrids上显示十进制(5,2)BCD字段,delphi,bcd,delphi-10.4-sydney,Delphi,Bcd,Delphi 10.4 Sydney,当我有一个包含datetime字段和decimal(5,2)字段的ClientDataset时,Delphi10.4无法在TDBGrid上显示它们,它会引发一个convert异常 我已经准备了一个小的测试项目来显示这个错误(我的真实数据来自SQL Server,尽管我可以手动填充Clientdataset得到相同的错误) 它引发此异常:'8200@'不是有效的整数值 如果我注释行ClientDataset.FieldDefs.Find('decimal'),十进制(18,2)就没有这个问题。精度

当我有一个包含datetime字段和decimal(5,2)字段的ClientDataset时,Delphi10.4无法在TDBGrid上显示它们,它会引发一个convert异常

我已经准备了一个小的测试项目来显示这个错误(我的真实数据来自SQL Server,尽管我可以手动填充Clientdataset得到相同的错误)

它引发此异常:
'8200@'不是有效的整数值

如果我注释行
ClientDataset.FieldDefs.Find('decimal'),十进制(18,2)就没有这个问题。精度:=5则不会引发任何错误

此外,如果没有datetime字段,则也不会引发错误。运行良好:

procedure TForm1.FormCreate(Sender: TObject);
var ClientDataset: TClientDataset;
    Datasource: TDatasource;
    DBGrid: TDBGrid;
begin
  ClientDataset := TClientDataset.Create(Self);
  ClientDataset.FieldDefs.Add('Id', ftInteger);
  ClientDataset.FieldDefs.Add('Decimal', ftBCD, 2);
  ClientDataset.FieldDefs.Find('Decimal').Precision := 5;
  ClientDataset.CreateDataSet;
  Datasource := TDatasource.Create(Self);
  Datasource.Dataset := ClientDataset;

  ClientDataset.Insert;
  ClientDataset.FieldValues['id'] := 1;
  ClientDataset.FieldValues['Decimal'] := 7.55;
  ClientDataset.Post;
  ClientDataset.Insert;
  ClientDataset.FieldValues['id'] := 2;
  ClientDataset.FieldValues['Decimal'] := 8.2;
  ClientDataset.Post;

  DBGrid := TDBGrid.Create(Self);
  DBGrid.Parent := Self;
  DBGrid.Align := alClient;
  DBGrid.Datasource := Datasource;
end;
您认为这可以在不必用十进制(18,2)字段替换所有十进制(5,2)字段的情况下修复吗

更新:这是ClientDataset特有的问题。如果我在TADOQuery或TFDMemTable上打开相同的数据(具有完全相同的datetime和十进制(5,2)BCD字段),Delphi 10.4将显示DBGrid,而不会出现任何问题


这个问题也是DBGrid特有的。在DBEdits上显示这些字段没有问题。

在10.4版中,对unit Data.FmtBcd的函数bcdtocur e BCDToCurrency进行了更改

德尔菲法10.3

function BCDToCurr(const BCD: TBcd; var Curr: Currency): Boolean;
  Curr := StrToCurr(string(Bcd));
  Result := True;
end;

function BCDToCurrency(const BCD: TBcd): Currency;
begin
  Result := StrToCurr(string(Bcd)); 
end;
德尔菲法10.4

function BCDToCurr(const BCD: TBcd; var Curr: Currency): Boolean;
var
  B: TBcd;
  S: string;
const
  DecimalSeparator = '.';
begin
  // B := BCD * 10000;
  B := BCD;
  if BcdScale(B) >= 4 then
    Dec(B.SignSpecialPlaces, 4)
  else if BcdPrecision(B) <= (MaxFMTBcdFractionSize - 4) then
    Inc(B.Precision, 4)
  else
    OverflowError(SBcdOverflow);

  S := BcdToStr(B, DecimalSeparator);
  Round(S, DecimalSeparator, 0);
  // The real format of Currency type is Int64.
  PInt64(@Curr)^ := StrToInt64(S);
  Result := True;
end;

function BCDToCurrency(const BCD: TBcd): Currency;
begin
  BCDToCurr(BCD, Result);
end;
函数BCDToCurr(常量BCD:TBcd;变量Curr:Currency):布尔值;
变量
B:待定;
S:字符串;
常数
小数分隔符=';
开始
//B:=BCD*10000;
B:=BCD;
如果BcdScale(B)>=4,则
12月(B.SignSpecialPlaces,4)

否则,如果BcdPrecision(B)我报告了该错误,现在已在最近的Delphi 10.4更新1中修复。

奇怪的错误。您是否尝试过使用
TFDMemTable
?是否在windows的区域部分未选中Beta Unicode UTF-8?@Olivier,我刚刚尝试过TFDMemTable,它工作正常。真奇怪-(@Ravaut123我从来没有听说过这个设置,在哪里可以找到它?。它是Delphi 10.4的一个干净的安装,只有Delphi更新和报表生成器,没有对它做更多的工作。@Ravaut123为什么你认为这个问题与这个设置有关?
function BCDToCurr(const BCD: TBcd; var Curr: Currency): Boolean;
var
  B: TBcd;
  S: string;
const
  DecimalSeparator = '.';
begin
  // B := BCD * 10000;
  B := BCD;
  if BcdScale(B) >= 4 then
    Dec(B.SignSpecialPlaces, 4)
  else if BcdPrecision(B) <= (MaxFMTBcdFractionSize - 4) then
    Inc(B.Precision, 4)
  else
    OverflowError(SBcdOverflow);

  S := BcdToStr(B, DecimalSeparator);
  Round(S, DecimalSeparator, 0);
  // The real format of Currency type is Int64.
  PInt64(@Curr)^ := StrToInt64(S);
  Result := True;
end;

function BCDToCurrency(const BCD: TBcd): Currency;
begin
  BCDToCurr(BCD, Result);
end;