FormatFloat(#,##0.00, var_number) 和 Format('%n', var_number) 舍入到千位时出错
Error on FormatFloat(#,##0.00, var_number) and Format('%n', var_number) Rounding-off to Thousands
FormatFloat(#,##0.00, var_number) 和 Format('%n', var_number) 为我提供了四舍五入的结果。为什么会这样?我的代码有问题吗?
下面我做了一些Minimum Reproducible Example
供大家参考。 我得到的结果是 12 而不是 12,345.00。请让我知道我到底错过了什么地方和什么。
FMX 程序:
unit Unit9;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base,
FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf,
FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async,
FireDAC.Phys, FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef,
FireDAC.Stan.ExprFuncs, FireDAC.FMXUI.Wait, FireDAC.Stan.Param, FireDAC.DatS,
FireDAC.DApt.Intf, FireDAC.DApt, Data.Bind.EngExt, Fmx.Bind.DBEngExt,
System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.Components,
Data.Bind.DBScope, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client,
FMX.ListView, FMX.Controls.Presentation, FMX.StdCtrls;
type
TForm9 = class(TForm)
lbl1: TLabel;
lsv1: TListView;
con1: TFDConnection;
qryLists: TFDQuery;
bdr1: TBindSourceDB;
bdl1: TBindingsList;
tcf1: TLinkFillControlToField;
lpfText: TLinkPropertyToField;
qryInsert: TFDQuery;
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form9: TForm9;
implementation
{$R *.fmx}
procedure TForm9.btn1Click(Sender: TObject);
begin
qryInsert.ParamByName('id').AsInteger := 1;
qryInsert.ParamByName('cur_datetime').AsDateTime := now;
qryInsert.ParamByName('name').AsString := 'sample';
qryInsert.ParamByName('size_cont').AsString := 'size_cont';
qryInsert.ParamByName('qty').AsFloat := 10;
qryInsert.ParamByName('est_price').AsFloat := 1234.5;
qryInsert.ParamByName('qty_price').AsString := '10 x 1234.5';
qryInsert.ParamByName('estimate').AsString := FormatFloat('#,##0.00', 10 * 1234.5); //the result is giving me 12 (the correct one is 12,345.00)
qryInsert.ExecSQL;
qryLists.Close;
qryLists.Open();
end;
end.
FMX 文件:
object Form9: TForm9
Left = 0
Top = 0
Caption = 'Form9'
ClientHeight = 480
ClientWidth = 308
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object lbl1: TLabel
Align = Top
StyledSettings = [Family, Style, FontColor]
Size.Width = 308.000000000000000000
Size.Height = 33.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 14.000000000000000000
TextSettings.HorzAlign = Center
Text = '5'
TabOrder = 0
end
object lsv1: TListView
ItemAppearanceClassName = 'TImageListItemBottomDetailAppearance'
ItemEditAppearanceClassName = 'TImageListItemBottomDetailShowCheckAppearance'
HeaderAppearanceClassName = 'TListHeaderObjects'
FooterAppearanceClassName = 'TListHeaderObjects'
Align = Client
Size.Width = 308.000000000000000000
Size.Height = 407.000000000000000000
Size.PlatformDefault = False
TabOrder = 1
end
object btn1: TButton
Align = Bottom
Position.Y = 440.000000000000000000
Size.Width = 308.000000000000000000
Size.Height = 40.000000000000000000
Size.PlatformDefault = False
TabOrder = 7
Text = 'btn1'
OnClick = btn1Click
end
object con1: TFDConnection
Params.Strings = (
'Database=D:\My Project Files. my_projects_aws-rest\project_x_v' +
'0\application\client\database\smartcart.s3db'
'LockingMode=Normal'
'DriverID=SQLite')
Connected = True
LoginPrompt = False
Left = 72
Top = 24
end
object qryLists: TFDQuery
Active = True
Connection = con1
SQL.Strings = (
'SELECT id, date_created, name, size_cont, qty_price, estimate'
'FROM lists ORDER BY date_created DESC')
Left = 112
Top = 24
end
object bdr1: TBindSourceDB
DataSet = qryLists
ScopeMappings = <>
Left = 152
Top = 24
end
object bdl1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 20
Top = 5
object tcf1: TLinkFillControlToField
Category = 'Quick Bindings'
Control = lsv1
Track = True
FillDataSource = bdr1
AutoFill = True
FillExpressions = <
item
SourceMemberName = 'estimate'
ControlMemberName = 'Detail'
end>
FillHeaderExpressions = <>
FillBreakGroups = <>
end
object lpfText: TLinkPropertyToField
Category = 'Quick Bindings'
DataSource = bdr1
FieldName = 'estimate'
Component = lbl1
ComponentProperty = 'Text'
end
end
object qryInsert: TFDQuery
Connection = con1
SQL.Strings = (
'INSERT INTO lists (id, date_created, name, size_cont, '
' qty, est_price, qty_price, estimate) '
'VALUES (:id, :cur_datetime, :name, :size_cont, '
' :qty, :est_price, :qty_price, :estimate);')
Left = 192
Top = 24
ParamData = <
item
Name = 'ID'
DataType = ftInteger
ParamType = ptInput
Value = Null
end
item
Name = 'CUR_DATETIME'
DataType = ftDateTime
ParamType = ptInput
Value = Null
end
item
Name = 'NAME'
DataType = ftString
ParamType = ptInput
Value = Null
end
item
Name = 'SIZE_CONT'
DataType = ftString
ParamType = ptInput
Value = Null
end
item
Name = 'QTY'
DataType = ftFloat
ParamType = ptInput
Value = Null
end
item
Name = 'EST_PRICE'
DataType = ftFloat
ParamType = ptInput
Value = Null
end
item
Name = 'QTY_PRICE'
DataType = ftString
ParamType = ptInput
Value = Null
end
item
Name = 'ESTIMATE'
DataType = ftFloat
ParamType = ptInput
Value = Null
end>
end
end
更新: TListView 属性截图
根据您的表单定义文件,您的参数定义为 Datatype = ftFloat
。
item
Name = 'ESTIMATE'
DataType = ftFloat
ParamType = ptInput
Value = Null
end>
这意味着您根本不需要使用参数的 AsString
赋值或使用 FormatFloat
转换它,因为您可以直接将值作为浮点值赋值。
qryInsert.ParamByName('estimate').AsFloat := 10 * 1234.5;
这样做不会导致任何舍入错误,因为数据是以正确的值存储的。根本没有四舍五入。
FormatFloat(#,##0.00, var_number) 和 Format('%n', var_number) 为我提供了四舍五入的结果。为什么会这样?我的代码有问题吗?
下面我做了一些Minimum Reproducible Example
供大家参考。 我得到的结果是 12 而不是 12,345.00。请让我知道我到底错过了什么地方和什么。
FMX 程序:
unit Unit9;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base,
FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf,
FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async,
FireDAC.Phys, FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef,
FireDAC.Stan.ExprFuncs, FireDAC.FMXUI.Wait, FireDAC.Stan.Param, FireDAC.DatS,
FireDAC.DApt.Intf, FireDAC.DApt, Data.Bind.EngExt, Fmx.Bind.DBEngExt,
System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.Components,
Data.Bind.DBScope, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client,
FMX.ListView, FMX.Controls.Presentation, FMX.StdCtrls;
type
TForm9 = class(TForm)
lbl1: TLabel;
lsv1: TListView;
con1: TFDConnection;
qryLists: TFDQuery;
bdr1: TBindSourceDB;
bdl1: TBindingsList;
tcf1: TLinkFillControlToField;
lpfText: TLinkPropertyToField;
qryInsert: TFDQuery;
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form9: TForm9;
implementation
{$R *.fmx}
procedure TForm9.btn1Click(Sender: TObject);
begin
qryInsert.ParamByName('id').AsInteger := 1;
qryInsert.ParamByName('cur_datetime').AsDateTime := now;
qryInsert.ParamByName('name').AsString := 'sample';
qryInsert.ParamByName('size_cont').AsString := 'size_cont';
qryInsert.ParamByName('qty').AsFloat := 10;
qryInsert.ParamByName('est_price').AsFloat := 1234.5;
qryInsert.ParamByName('qty_price').AsString := '10 x 1234.5';
qryInsert.ParamByName('estimate').AsString := FormatFloat('#,##0.00', 10 * 1234.5); //the result is giving me 12 (the correct one is 12,345.00)
qryInsert.ExecSQL;
qryLists.Close;
qryLists.Open();
end;
end.
FMX 文件:
object Form9: TForm9
Left = 0
Top = 0
Caption = 'Form9'
ClientHeight = 480
ClientWidth = 308
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object lbl1: TLabel
Align = Top
StyledSettings = [Family, Style, FontColor]
Size.Width = 308.000000000000000000
Size.Height = 33.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 14.000000000000000000
TextSettings.HorzAlign = Center
Text = '5'
TabOrder = 0
end
object lsv1: TListView
ItemAppearanceClassName = 'TImageListItemBottomDetailAppearance'
ItemEditAppearanceClassName = 'TImageListItemBottomDetailShowCheckAppearance'
HeaderAppearanceClassName = 'TListHeaderObjects'
FooterAppearanceClassName = 'TListHeaderObjects'
Align = Client
Size.Width = 308.000000000000000000
Size.Height = 407.000000000000000000
Size.PlatformDefault = False
TabOrder = 1
end
object btn1: TButton
Align = Bottom
Position.Y = 440.000000000000000000
Size.Width = 308.000000000000000000
Size.Height = 40.000000000000000000
Size.PlatformDefault = False
TabOrder = 7
Text = 'btn1'
OnClick = btn1Click
end
object con1: TFDConnection
Params.Strings = (
'Database=D:\My Project Files. my_projects_aws-rest\project_x_v' +
'0\application\client\database\smartcart.s3db'
'LockingMode=Normal'
'DriverID=SQLite')
Connected = True
LoginPrompt = False
Left = 72
Top = 24
end
object qryLists: TFDQuery
Active = True
Connection = con1
SQL.Strings = (
'SELECT id, date_created, name, size_cont, qty_price, estimate'
'FROM lists ORDER BY date_created DESC')
Left = 112
Top = 24
end
object bdr1: TBindSourceDB
DataSet = qryLists
ScopeMappings = <>
Left = 152
Top = 24
end
object bdl1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 20
Top = 5
object tcf1: TLinkFillControlToField
Category = 'Quick Bindings'
Control = lsv1
Track = True
FillDataSource = bdr1
AutoFill = True
FillExpressions = <
item
SourceMemberName = 'estimate'
ControlMemberName = 'Detail'
end>
FillHeaderExpressions = <>
FillBreakGroups = <>
end
object lpfText: TLinkPropertyToField
Category = 'Quick Bindings'
DataSource = bdr1
FieldName = 'estimate'
Component = lbl1
ComponentProperty = 'Text'
end
end
object qryInsert: TFDQuery
Connection = con1
SQL.Strings = (
'INSERT INTO lists (id, date_created, name, size_cont, '
' qty, est_price, qty_price, estimate) '
'VALUES (:id, :cur_datetime, :name, :size_cont, '
' :qty, :est_price, :qty_price, :estimate);')
Left = 192
Top = 24
ParamData = <
item
Name = 'ID'
DataType = ftInteger
ParamType = ptInput
Value = Null
end
item
Name = 'CUR_DATETIME'
DataType = ftDateTime
ParamType = ptInput
Value = Null
end
item
Name = 'NAME'
DataType = ftString
ParamType = ptInput
Value = Null
end
item
Name = 'SIZE_CONT'
DataType = ftString
ParamType = ptInput
Value = Null
end
item
Name = 'QTY'
DataType = ftFloat
ParamType = ptInput
Value = Null
end
item
Name = 'EST_PRICE'
DataType = ftFloat
ParamType = ptInput
Value = Null
end
item
Name = 'QTY_PRICE'
DataType = ftString
ParamType = ptInput
Value = Null
end
item
Name = 'ESTIMATE'
DataType = ftFloat
ParamType = ptInput
Value = Null
end>
end
end
更新: TListView 属性截图
根据您的表单定义文件,您的参数定义为 Datatype = ftFloat
。
item
Name = 'ESTIMATE'
DataType = ftFloat
ParamType = ptInput
Value = Null
end>
这意味着您根本不需要使用参数的 AsString
赋值或使用 FormatFloat
转换它,因为您可以直接将值作为浮点值赋值。
qryInsert.ParamByName('estimate').AsFloat := 10 * 1234.5;
这样做不会导致任何舍入错误,因为数据是以正确的值存储的。根本没有四舍五入。