unit ScBillsTree; interface uses ZjIDTree, Classes, DB, ConstMethodUnit, ConstVarUnit, ConstTypeUnit, DBClient; const idFirstSection = 1; idSecondSection = 2; idThreeSection = 3; // 第一二三部分费用合计 idAggregate123 = 4; idPricePerKM = 8; // 概(预)算总金额 idBugetTotalPrice = 5; // 公路基本造价 idProjectTotalPrice = 6; type {BillsTree} TScBillsItem = class(TZjIDTreeNode) private FSCode: string; FSBCode: string; FSName: string; // 是否是预定义项,即系统预设的项目,而不是用户输入的,且不允许删除 FIsPreDefine: Boolean; FSelected: Boolean; FBills: TObject; FUnits: string; FQuantity: Double; // 需要用到Null值 FDesignQuantity: Double; FDesignQuantity2: Double; FIsRepeat: Boolean; // 是否是重复行 FIsSuperscale: Boolean; FUserModified: Boolean; FErrorHint: string; FDeductGrade: Currency; FLostPreSiblingCount: Integer; FLostChildrenCount: Integer; FStandardGrade: Currency; FLostNextSiblingCount: Integer; FIsIgNore: Boolean; FNameErrorFlag: Integer; FUnitsErrorFlag: Integer; FRightName: String; FRightUnits: String; FIsAccQuantity: Boolean; function GetLastBudgetParent: TScBillsItem; function GetBillCategory: TBillCategory; function GetNeed: Boolean; function GetTotalPrice(AIsTender: Boolean): Currency; function GetChapterID: Integer; function GetCode: string; procedure SetSelected(const Value: Boolean); public constructor Create(AOwner: TZjIDTree); override; function CanUpLevel: Boolean; override; function CanDownLevel: Boolean; override; function CanUpMove: Boolean; override; function CanDownMove: Boolean; override; function HasDrawingQuantity: Boolean; procedure SyncSelected(aValue: Boolean); function IsInheritFrom(AID: Integer): Boolean; property Bills: TObject read FBills write FBills; property IsPreDefine: Boolean read FIsPreDefine; property ChapterID: Integer read GetChapterID; // property Code: string read GetCode; property TotalPrice[AIsTender: Boolean]: Currency read GetTotalPrice; property Selected: Boolean read FSelected write SetSelected; property SBillCode: string read FSCode write FSCode; property SBillBCode: string read FSBCode write FSBCode; property SBillName: string read FSName write FSName; property Code: string read FSCode write FSCode; property B_Code: string read FSBCode write FSBCode; property Name: string read FSName write FSName; property Units: string read FUnits write FUnits; property Quantity: Double read FQuantity write FQuantity; property DesignQuantity: Double read FDesignQuantity write FDesignQuantity; property DesignQuantity2: Double read FDesignQuantity2 write FDesignQuantity2; property UserModified: Boolean read FUserModified write FUserModified; property ErrorHint: string read FErrorHint write FErrorHint; property DeductGrade: Currency read FDeductGrade write FDeductGrade; property IsSuperscale: Boolean read FIsSuperscale write FIsSuperscale; property LostPreSiblingCount: Integer read FLostPreSiblingCount write FLostPreSiblingCount; property LostChildrenCount: Integer read FLostChildrenCount write FLostChildrenCount; property LostNextSiblingCount: Integer read FLostNextSiblingCount write FLostNextSiblingCount; property StandardGrade: Currency read FStandardGrade write FStandardGrade; property IsIgNore: Boolean read FIsIgNore write FIsIgNore; property NameErrorFlag: Integer read FNameErrorFlag write FNameErrorFlag; property UnitsErrorFlag: Integer read FUnitsErrorFlag write FUnitsErrorFlag; property RightName: string read FRightName write FRightName; property RightUnits: string read FRightUnits write FRightUnits; property LastBudgetParent: TScBillsItem read GetLastBudgetParent; property Category: TBillCategory read GetBillCategory; property IsRepeat: Boolean read FIsRepeat write FIsRepeat; property NeedSearchInStdLib: Boolean read GetNeed; // Modified By MaiXinRong 2012-03-21 是否填父项量 property IsAccQuantity: Boolean read FIsAccQuantity write FIsAccQuantity; end; TScBillsTree = class(TZjIDTree) private FBills: TObject; FShowError: Boolean; FInternalEvent: TInternalEvent; function GetBillsItem(ID: Integer): TScBillsItem; function GetItems(AIndex: Integer): TScBillsItem; protected function CreateItem: TScIDTreeNode; override; procedure LoadItem(AItem: TScIDTreeNode); override; procedure InitDBRecord; override; public function AddBillsItem(AParentID, ANextSiblingID: TScTreeNodeID): TScBillsItem; overload; function AddBillsItem(AID, AParentID, ANextSiblingID: TScTreeNodeID): TScBillsItem; overload; function Add(AParentID, ANextSiblingID: TScTreeNodeID): TScIDTreeNode; override; function CanAdd(AParentID, ANextSiblingID: TScTreeNodeID): Boolean; override; function CanDelete(ANode: TScIDTreeNode): Boolean; override; function DeleteNode(ANode: TScIDTreeNode): Boolean; override; property BillsItem[ID: Integer]: TScBillsItem read GetBillsItem; default; property Items[AIndex: Integer]: TScBillsItem read GetItems; property Bills: TObject read FBills write FBills; property ShowError: Boolean read FShowError write FShowError; {Events} property InternalEvent: TInternalEvent read FInternalEvent write FInternalEvent; function FindNode(AID: TZjTreeNodeID): TScBillsItem; end; {stdBillsTree} TStdBillNode = class (TZjIDTreeNode) private FCode: string; FBCode: string; FName: string; FUnits: string; FNotes: string; FFee: string; FStaticID: Integer; FExpr: string; FGradeType: Integer; function GetStringValue(AIdx: Integer): string; procedure SetStringValue(AIdx: Integer; Value: string); function GetLastBudgetParent: TStdBillNode; function GetHasYsxmjChild: Boolean; public function TopestAncestor(AList: TList): TStdBillNode; property Code: string index 0 read GetStringValue write SetStringValue; property BCode: string index 1 read GetStringValue write SetStringValue; property Name: string index 2 read GetStringValue write SetStringValue; property Units: string index 3 read GetStringValue write SetStringValue; property Notes: string index 4 read GetStringValue write SetStringValue; property Fee: string index 5 read GetStringValue write SetStringValue; property Exprs: string index 6 read GetStringValue write SetStringValue; property GradeType: Integer read FGradeType write FGradeType; property StaticID: Integer read FStaticID write FStaticID; property LastBudgetParent: TStdBillNode read GetLastBudgetParent; property HasYsxmjChild: Boolean read GetHasYsxmjChild; end; TStdBillsTree = class (TZjIDTree) protected function CreateItem: TScIDTreeNode; override; procedure LoadItem(AItem: TScIDTreeNode); override; public {------------------------------------------------------------------------------- 方法: FindNode 描述: ABItem:要查找的最终清单 ALostBItem:没有找到的那一层清单 ALostStdPaItem:ALostBItem在标准项目表中对应的标准项的父标准项。 它的父标准项一定存在于标准项目表(即ALostStdPaItem一定存在)。 当某清单搜不到时立即返回该清单,不再往下搜索。 如:搜索1-1/1-1-2/1-1-2-9/301-1/301-1-5,在1-1-2-9时出错了,则: ABItem: 301-1-5 ALostBItem: 1-1-2-9 ALostStdPaItem: 1-1-2 作者: Chenshilong, 2010-12-15 17:48:38 -------------------------------------------------------------------------------} function FindNode(ABItem: TScBillsItem; var ALostBItem: TScBillsItem; var ALostStdPaItem: TStdBillNode): TStdBillNode; overload; function FindNode(ACode, AB_Code: string): TStdBillNode; overload; end; { XMJ } TXMJBillsItem = class(TScBillsItem) public function CanUpLevel: Boolean; override; function CanDownLevel: Boolean; override; end; TXMJBillsTree = class(TScBillsTree) protected function CreateItem: TScIDTreeNode; override; end; { Merge } TAdditionalItem = class(TZjIDTreeNode) private FCode: string; FB_Code: string; FName: string; FUnits: string; FOwnerName: string; FMemoStr: string; FQuantity: Double; FQuantity2: Double; FUnitPrice: Currency; FTotalPrice: Currency; FDesignQuantity: Currency; FDesignQuantity2: Currency; FDesignPrice: Currency; public property Code: string read FCode write FCode; property B_Code: string read FB_Code write FB_Code; property Name: string read FName write FName; property Units: string read FUnits write FUnits; property MemoStr: string read FMemoStr write FMemoStr; property OwnerName: string read FOwnerName write FOwnerName; property Quantity: Double read FQuantity write FQuantity; property Quantity2: Double read FQuantity2 write FQuantity2; property UnitPrice: Currency read FUnitPrice write FUnitPrice; property TotalPrice: Currency read FTotalPrice write FTotalPrice; property DesignQuantity: Currency read FDesignQuantity write FDesignQuantity; property DesignQuantity2: Currency read FDesignQuantity2 write FDesignQuantity2; property DesignPrice: Currency read FDesignPrice write FDesignPrice; end; TAdditinalTree = class(TScBillsTree) protected function CreateItem: TScIDTreeNode; override; procedure LoadItem(AItem: TScIDTreeNode); override; procedure InitDBRecord; override; end; implementation uses DataBase, SysUtils, Variants; { TScBillsItem } function TScBillsItem.CanDownLevel: Boolean; begin Result := inherited CanDownLevel // and not TDMDataBase(Bills).HasDrawingQuantity(PrevSiblingID) and not IsPreDefine; // 不是预定义项 end; function TScBillsItem.CanDownMove: Boolean; begin Result := inherited CanDownMove and not IsPreDefine; end; function TScBillsItem.CanUpLevel: Boolean; begin Result := not IsPreDefine and ((Level > 1) or not IsInheritFrom(idFirstSection)) // 第一部分的项目Level必须大于1才能升级,其它部分不限制 and inherited CanUpLevel; {and ( { (NextSibling = nil) or ( (HasChildren and not HasDrawingQuantity) ) ); } // 说明: 当该项目不是预定义项,Levle>1并且满足一下条件时可以升级 { 1: 没有后续兄弟节点的时候,可以升级 2: 有后续兄弟节点时,必须没有定额和自定义的金额(即:用户直接输入金额或计算式), 判断没有自定义金额的方法是: TotalPrice = 0 并且 没有子项。 } { if not Result and TScBillsTree(Owner).FShowError then begin if HasDrawingQuantity then MessageWarning(0, '该项目下面有图纸工程量,不能升级'); end; } end; function TScBillsItem.CanUpMove: Boolean; begin Result := inherited CanUpMove and not IsPreDefine; end; constructor TScBillsItem.Create(AOwner: TZjIDTree); begin inherited Create(AOwner); // FSelected := False; Bills := TScBillsTree(AOwner).Bills; end; function TScBillsItem.GetBillCategory: TBillCategory; begin Result := BillCategory(FSCode, FSBCode); end; function TScBillsItem.GetChapterID: Integer; var Node: TScIDTreeNode; begin Node := Self; while Node.Parent <> nil do begin if Node.Parent.ID in [idFirstSection, idSecondSection, idThreeSection] then begin Result := Node.ID; Exit; end; Node := Node.Parent; end; Result := ID; end; function TScBillsItem.GetCode: string; begin Result := VarToStr(Owner.DataSet.Lookup(SID, ID, sCode)); end; function TScBillsItem.GetLastBudgetParent: TScBillsItem; var vItem: TScBillsItem; begin Result := nil; vItem := Self; while Assigned(vItem) do begin vItem := TScBillsItem(vItem.Parent); if (Trim(vItem.Code) <> '') and (Trim(vItem.B_Code) = '') then begin Result := vItem; Break; end; end; end; function TScBillsItem.GetNeed: Boolean; begin Result := not (IsRepeat or IsSuperscale); end; function TScBillsItem.GetTotalPrice(AIsTender: Boolean): Currency; const sResult: array[Boolean] of string = (STotalPrice, STenderTotalPrice); begin Result := ScVarToCurrency(TDMDataBase(Bills).cdsBills.Lookup(SID, ID, sResult[AIsTender])); end; function TScBillsItem.HasDrawingQuantity: Boolean; begin Result := TDMDataBase(Bills).HasDrawingQuantity(ID); end; function TScBillsItem.IsInheritFrom(AID: Integer): Boolean; var vAncestor: TScBillsItem; vItem: TScBillsItem; begin Result := False; vAncestor := TScBillsTree(Owner).BillsItem[AID]; if vAncestor = nil then Exit; vItem := Self; while (vItem <> nil) and (vItem <> vAncestor) do vItem := TScBillsItem(vItem.Parent); Result := vItem = vAncestor; end; procedure TScBillsItem.SetSelected(const Value: Boolean); begin FSelected := Value; TDMDataBase(Bills).ModifySelected(ID, FSelected); end; procedure TScBillsItem.SyncSelected(aValue: Boolean); begin FSelected := aValue; end; { TScBillsTree } function TScBillsTree.Add(AParentID, ANextSiblingID: TScTreeNodeID): TScIDTreeNode; begin FShowError := True; try if (Selected <> nil) and (Selected.Level = 0) then begin if (Selected.ID in [idAggregate123, idBugetTotalPrice, idPricePerKM]) then Result := inherited Add(Selected.ParentID, Selected.NextSiblingID) else Result := inherited Add(Selected.ID, -1); end else Result := inherited Add(AParentID, ANextSiblingID); finally FShowError := False; end; end; function TScBillsTree.AddBillsItem(AParentID, ANextSiblingID: TScTreeNodeID): TScBillsItem; begin Result := TScBillsItem(Add(AParentID, ANextSiblingID)); end; function TScBillsTree.AddBillsItem(AID, AParentID, ANextSiblingID: TScTreeNodeID): TScBillsItem; begin if not (Assigned(DataSet) and DataSet.Active){Active} then raise Exception.Create('无法在一个关闭的数据集上执行该操作'); Result := nil; if CanAdd(AParentID, ANextSiblingID) then begin DataSet.Insert; ParentField.AsInteger := AParentID; NextSiblingField.AsInteger := ANextSiblingID; InitDBRecord; KeyField.AsInteger := AID; DataSet.Post; Result := TScBillsItem(inherited Add(KeyField.AsInteger, AParentID, ANextSiblingID)); end; end; function TScBillsTree.CanAdd(AParentID, ANextSiblingID: TScTreeNodeID): Boolean; var ParentNode: TScBillsItem; begin ParentNode := BillsItem[AParentID]; Result := (ParentNode = nil) or not ParentNode.IsPreDefine or not(AParentID in [idAggregate123, idBugetTotalPrice, idProjectTotalPrice, idPricePerKM]); if not Result and FShowError then MessageWarning(0, ' 该项目下面不能添加子项 '); if ParentNode = nil then Exit; { if Result then begin Result := not TDMDataBase(Bills).HasDrawingQuantity(AParentID); if not Result and FShowError then MessageWarning(0, ' 父项下面图纸工程量,如果要添加子项,请先删除该项目下面的图纸工程量'); end; } if Result then begin Result := (ParentNode.TotalPrice[False] = 0) or ParentNode.HasChildren; // 父项不能有用户直接输入的金额或计算公式 if not Result and FShowError then MessageWarning(0, ' 父项有用户直接输入的金额或者计算公式,如果要添加子项,请先删除该项目的金额或计算公式 '); end; end; function TScBillsTree.CanDelete(ANode: TScIDTreeNode): Boolean; var IsPreDefine: Boolean; begin Result := False; if (ANode <> nil) and TDMDataBase(FBills).cdsBills.FindKey([ANode.ID]) then begin // 预定义项 IsPreDefine := TDMDataBase(FBills).cdsBills.FieldByName('IsPreDefine').AsBoolean; if not IsPreDefine then // IsPreDefine字段值为空或False begin Result := True; if FShowError then begin // 固定ID清单项 if (not TDMDataBase(FBills).cdsOrgBillsIsPreDefine.Value) and (TDMDataBase(FBills).cdsBillsID.value < 100) then Result := MessageQuest('提醒:清单[' + TDMDataBase(FBills).cdsBillsName.AsString +']是固定ID清单,删除后可以从右侧的清单范本中重新添加,' + #10#13 + '添加后其ID值不变。但若通过手工录入的方式添加则不具有此功能。确认要继续吗?', '确认删除'); // 有子清单 if TScBillsItem(ANode).HasChildren then Result := MessageQuest('确认要删除该清单项及其下面的所有子项吗?', '确认删除') // 没有子清单,但有定额或数量单价类 else if TDMDataBase(FBills).HasDrawingQuantity(TScBillsItem(ANode).ID) then Result := MessageQuest('该清单项下有图纸工程量,确认要删除该清单项吗?', '确认删除'); end; end // IsPreDefine字段值为True时不能删。 else if FShowError then MessageWarning(0, '该项是预定义项,不能被删除 '); end; end; function TScBillsTree.CreateItem: TScIDTreeNode; begin Result := TScBillsItem.Create(Self); end; function TScBillsTree.DeleteNode(ANode: TScIDTreeNode): Boolean; begin FShowError := True; try Result := inherited DeleteNode(ANode); finally FShowError := False; end; end; function TScBillsTree.FindNode(AID: TZjTreeNodeID): TScBillsItem; begin Result := TScBillsItem(inherited FindNode(AID)); end; function TScBillsTree.GetBillsItem(ID: Integer): TScBillsItem; begin Result := TScBillsItem(FindNode(ID)); end; function TScBillsTree.GetItems(AIndex: Integer): TScBillsItem; begin Result := TScBillsItem(inherited Items[AIndex]); end; procedure TScBillsTree.InitDBRecord; begin if Assigned(FInternalEvent) then FInternalEvent; end; procedure TScBillsTree.LoadItem(AItem: TScIDTreeNode); begin inherited; with TScBillsItem(AItem) do begin FIsPreDefine := DataSet.FieldByName('IsPreDefine').AsBoolean; FSCode := DataSet.FieldByName(sCode).AsString; FSBCode := DataSet.FieldByName(sB_Code).AsString; FSName := DataSet.FieldByName(sName).AsString; FSelected := DataSet.FieldByName('Selected').AsBoolean; FUnits := DataSet.FieldByName('Units').AsString; FQuantity := DataSet.FieldByName('Quantity').AsFloat; FDesignQuantity := DataSet.FieldByName('DesignQuantity').AsFloat; FDesignQuantity2 := DataSet.FieldByName('DesignQuantity2').AsFloat; FIsSuperscale := DataSet.FieldByName('IsSuperscale').AsBoolean; FUserModified := DataSet.FieldByName('UserModified').AsBoolean; FIsIgNore := DataSet.FieldByName('IsIgNore').AsBoolean; FErrorHint := DataSet.FieldByName('ErrorHint').AsString; FDeductGrade := DataSet.FieldByName('DeductGrade').AsCurrency; FStandardGrade := DataSet.FieldByName('StandardGrade').AsCurrency; FLostPreSiblingCount := DataSet.FieldByName('LostPreSiblingCount').AsInteger; FLostChildrenCount := DataSet.FieldByName('LostChildrenCount').AsInteger; FLostNextSiblingCount := DataSet.FieldByName('LostNextSiblingCount').AsInteger; FNameErrorFlag := DataSet.FieldByName('NameErrorFlag').AsInteger; FUnitsErrorFlag := DataSet.FieldByName('UnitsErrorFlag').AsInteger; FRightName := DataSet.FieldByName('RightName').AsString; FRightUnits := DataSet.FieldByName('RightUnits').AsString; FIsAccQuantity := DataSet.FieldByName('IsAccQuantity').AsBoolean; end; end; { TStdBillNode } function TStdBillNode.GetHasYsxmjChild: Boolean; var i: Integer; vItem: TStdBillNode; begin Result := False; for i := 0 to ChildCount - 1 do begin vItem := TStdBillNode(Self.ChildNodes[i]); if vItem.Code <> '' then begin Result := True; Break; end; end; end; function TStdBillNode.GetLastBudgetParent: TStdBillNode; var vNode: TStdBillNode; begin Result := nil; vNode := Self; while Assigned(vNode) do begin vNode := TStdBillNode(vNode.Parent); if (vNode.FCode <> '') and (vNode.FBCode = '') then begin Result := vNode; Break; end; end; end; function TStdBillNode.GetStringValue(AIdx: Integer): string; begin case AIdx of 0: Result := FCode; 1: Result := FBCode; 2: Result := FName; 3: Result := FUnits; 4: Result := FNotes; 5: Result := FFee; 6: Result := FExpr; end; end; procedure TStdBillNode.SetStringValue(AIdx: Integer; Value: string); begin case AIdx of 0: FCode := Value; 1: FBCode := Value; 2: FName := Value; 3: FUnits := Value; 4: FNotes := Value; 5: FFee := Value; 6: FExpr := Value; end; end; function TStdBillNode.TopestAncestor(AList: TList): TStdBillNode; var vNode: TZjIDTreeNode; begin vNode := Self; while Assigned(vNode.Parent) do begin AList.Add(vNode.Parent); vNode := vNode.Parent; end; Result := TStdBillNode(vNode); end; { TStdBillsTree } function TStdBillsTree.CreateItem: TScIDTreeNode; begin Result := TStdBillNode.Create(Self); end; function TStdBillsTree.FindNode(ABItem: TScBillsItem; var ALostBItem: TScBillsItem; var ALostStdPaItem: TStdBillNode): TStdBillNode; var BGPaList: TList; vBPaItem: TScBillsItem; vStdItem, vStdItemChild: TStdBillNode; i, j: Integer; bFinded: Boolean; // 获取父结点列表,包括自身 procedure GetBGParents; begin vBPaItem := ABItem; while Assigned(vBPaItem) do begin BGPaList.Add(vBPaItem); vBPaItem := TScBillsItem(vBPaItem.Parent); end; end; begin Result := nil; // 从标准项目表第一结点开始(1 第一部分 建筑安装工程费) vStdItem := TStdBillNode(Self.Items[0]); if ABItem.ID = 1 then begin Result := vStdItem; Exit; end; try BGPaList := TList.Create; GetBGParents; // 从次顶层父结点开始(如1-1),逐层往下搜索 for i := BGPaList.Count - 2 downto 0 do begin vBPaItem := TScBillsItem(BGPaList[i]); bFinded := False; for j := 0 to vStdItem.ChildCount - 1 do begin vStdItemChild := TStdBillNode(vStdItem.ChildNodes[j]); if (vBPaItem.Code = vStdItemChild.Code) and (vBPaItem.FSBCode = vStdItemChild.FBCode) then begin vStdItem := vStdItemChild; if vBPaItem = ABItem then begin Result := vStdItem; Exit; end; bFinded := True; Break; end; end; if not bFinded then begin ALostBItem := vBPaItem; ALostStdPaItem := vStdItem; end; end; finally BGPaList.Free; end; end; function TStdBillsTree.FindNode(ACode, AB_Code: string): TStdBillNode; var i: Integer; vNode: TStdBillNode; begin Result := nil; for i := 0 to Count - 1 do begin vNode := TStdBillNode(Items[i]); if SameText(vNode.Code, ACode) and SameText(vNode.BCode, AB_Code) then begin Result := vNode; Break; end; end; end; procedure TStdBillsTree.LoadItem(AItem: TScIDTreeNode); begin with TStdBillNode(AItem) do begin Code := DataSet.FieldByName('Code').AsString; BCode := DataSet.FieldByName('B_Code').AsString; Name := DataSet.FieldByName('Name').AsString; Units := DataSet.FieldByName('Unit').AsString; Exprs := DataSet.FieldByName('Expr').AsString; if DataSet.FieldByName('StaticID').IsNull then StaticID := -1 else StaticID := DataSet.FieldByName('StaticID').AsInteger; end; end; { TXMJBillsItem } function TXMJBillsItem.CanDownLevel: Boolean; begin Result := False; end; function TXMJBillsItem.CanUpLevel: Boolean; begin Result := False; end; { TXMJBillsTree } function TXMJBillsTree.CreateItem: TScIDTreeNode; begin Result := TXMJBillsItem.Create(Self); end; { TMergeTree } function TAdditinalTree.CreateItem: TScIDTreeNode; begin Result := TAdditionalItem.Create(Self); end; procedure TAdditinalTree.InitDBRecord; begin end; procedure TAdditinalTree.LoadItem(AItem: TScIDTreeNode); begin with TAdditionalItem(AItem) do begin FCode := DataSet.FieldByName(sCode).AsString; FB_Code := DataSet.FieldByName(sB_Code).AsString; FName := DataSet.FieldByName(sName).AsString; FUnits := DataSet.FieldByName(sUnits).AsString; FMemoStr := DataSet.FieldByName(sMemoStr).AsString; FOwnerName := DataSet.FieldByName(sOwnerName).AsString; FQuantity := DataSet.FieldByName(sQuantity).AsFloat; FQuantity2 := DataSet.FieldByName(sQuantity2).AsFloat; FUnitPrice := DataSet.FieldByName(sUnitPrice).AsCurrency; FTotalPrice := DataSet.FieldByName(STotalPrice).AsCurrency; FDesignQuantity := DataSet.FieldByName(sDesignQuantity).AsCurrency; FDesignQuantity2 := DataSet.FieldByName(sDesignQuantity2).AsCurrency; FDesignPrice := DataSet.FieldByName(sDesignPrice).AsCurrency; end; end; end.