unit BillsGatherDm; interface uses SysUtils, Classes, DB, DBClient, sdIDTree, sdDB; type TGclNode = class private FB_Code: string; FIndexCode: string; FName: string; FUnits: string; FPrice: Double; FNewPrice: Double; FDealQuantity: Double; FDealTotalPrice: Double; FQuantity: Double; FTotalPrice: Double; FBGLQuantity: Double; FBGLTotalPrice: Double; FCurDealQuantity: Double; FCurDealTotalPrice: Double; FCurQcQuantity: Double; FCurQcTotalPrice: Double; FCurPcQuantity: Double; FCurPcTotalPrice: Double; FCurGatherQuantity: Double; FCurGatherTotalPrice: Double; FEndDealQuantity: Double; FEndDealTotalPrice: Double; FEndQcQuantity: Double; FEndQcTotalPrice: Double; FEndPcQuantity: Double; FEndPcTotalPrice: Double; FEndGatherQuantity: Double; FEndGatherTotalPrice: Double; FAddDealQuantity: Double; FAddDealTotalPrice: Double; FAddQcQuantity: Double; FAddQcTotalPrice: Double; FAddPcQuantity: Double; FAddPcTotalPrice: Double; FAddGatherQuantity: Double; FAddGatherTotalPrice: Double; end; TBillsGatherData = class(TDataModule) cdsBillsGather: TClientDataSet; cdsBillsGatherB_Code: TStringField; cdsBillsGatherName: TWideStringField; cdsBillsGatherUnits: TWideStringField; cdsBillsGatherPrice: TFloatField; cdsBillsGatherNewPrice: TFloatField; cdsBillsGatherQuantity: TFloatField; cdsBillsGatherTotalPrice: TFloatField; cdsBillsGatherCurDealQuantity: TFloatField; cdsBillsGatherCurDealTotalPrice: TFloatField; cdsBillsGatherCurQcQuantity: TFloatField; cdsBillsGatherCurQcTotalPrice: TFloatField; cdsBillsGatherCurPcQuantity: TFloatField; cdsBillsGatherCurPcTotalPrice: TFloatField; cdsBillsGatherCurGatherQuantity: TFloatField; cdsBillsGatherCurGatherTotalPrice: TFloatField; cdsBillsGatherAddDealQuantity: TFloatField; cdsBillsGatherAddDealTotalPrice: TFloatField; cdsBillsGatherAddQcQuantity: TFloatField; cdsBillsGatherAddQcTotalPrice: TFloatField; cdsBillsGatherAddPcQuantity: TFloatField; cdsBillsGatherAddPcTotalPrice: TFloatField; cdsBillsGatherAddGatherQuantity: TFloatField; cdsBillsGatherAddGatherTotalPrice: TFloatField; cdsRelaXmj: TClientDataSet; cdsRelaXmjCode: TStringField; cdsRelaXmjName: TWideStringField; cdsRelaXmjUnits: TWideStringField; cdsRelaXmjQuantity: TFloatField; cdsRelaXmjNameFenBu: TWideStringField; cdsRelaXmjNameFenXiang: TWideStringField; cdsRelaXmjNameDanWei: TWideStringField; cdsRelaXmjPeg: TWideStringField; cdsRelaXmjNameUnit: TWideStringField; cdsRelaXmjDrawingCode: TWideStringField; cdsBillsGatherIndexCode: TStringField; cdsBillsGatherDealQuantity: TFloatField; cdsBillsGatherDealTotalPrice: TFloatField; cdsBillsGatherEndDealQuantity: TFloatField; cdsBillsGatherEndDealTotalPrice: TFloatField; cdsBillsGatherEndQcQuantity: TFloatField; cdsBillsGatherEndQcTotalPrice: TFloatField; cdsBillsGatherEndPcQuantity: TFloatField; cdsBillsGatherEndPcTotalPrice: TFloatField; cdsBillsGatherEndGatherQuantity: TFloatField; cdsBillsGatherEndGatherTotalPrice: TFloatField; cdsBillsGatherBGLQuantity: TFloatField; cdsBillsGatherBGLTotalPrice: TFloatField; cdsBillsGatherCompletionRate: TFloatField; cdsBillsGatherDeal_BGLQuantity: TFloatField; cdsBillsGatherDeal_BGLTotalPrice: TFloatField; procedure cdsBillsGatherQuantityGetText(Sender: TField; var Text: String; DisplayText: Boolean); procedure cdsBillsGatherAfterScroll(DataSet: TDataSet); private FProjectData: TObject; FGclList: TList; function GetGclNode(ARec: TsdDataRecord): TGclNode; procedure FilterGclBills(ANode: TsdIDTreeNode); procedure FilterBills(ANode: TsdIDTreeNode); procedure FilterDealBills; procedure WriteGclBills; procedure RefreshRelaXmj; procedure AddRelaXmjs(const AB_Code, AName, AUnits: string; APrice: Double); function GetMainBillsTree: TsdIDTree; public constructor Create(AProjectData: TObject); destructor Destroy; override; procedure RefreshBills; property MainBillsTree: TsdIDTree read GetMainBillsTree; end; implementation uses ProjectData, PhaseData, StageDm, BillsDm, UtilMethods, ZhAPI, BillsCompileDm, DealBillsDm, BGLDm, BillsTree, BillsMeasureDm; {$R *.dfm} { TBillsGatherData } procedure TBillsGatherData.FilterBills(ANode: TsdIDTreeNode); begin if not Assigned(ANode) then Exit; if ANode.HasChildren then FilterBills(ANode.FirstChild) else FilterGclBills(ANode); FilterBills(ANode.NextSibling); end; procedure TBillsGatherData.FilterGclBills(ANode: TsdIDTreeNode); procedure LoadPhaseData(AGclNode: TGclNode; AID: Integer); var Rec: TsdDataRecord; begin Rec := TBillsIDTreeNode(ANode).StageRec; if not Assigned(Rec) then Exit; AGclNode.FCurDealQuantity := AGclNode.FCurDealQuantity + Rec.ValueByName('DealQuantity').AsFloat; AGclNode.FCurDealTotalPrice := AGclNode.FCurDealTotalPrice + Rec.ValueByName('DealTotalPrice').AsFloat; AGclNode.FCurQcQuantity := AGclNode.FCurQcQuantity + Rec.ValueByName('QcQuantity').AsFloat; AGclNode.FCurQcTotalPrice := AGclNode.FCurQcTotalPrice + Rec.ValueByName('QcTotalPrice').AsFloat; AGclNode.FCurPcQuantity := AGclNode.FCurPcQuantity + Rec.ValueByName('PcQuantity').AsFloat; AGclNode.FCurPcTotalPrice := AGclNode.FCurPcTotalPrice + Rec.ValueByName('PcTotalPrice').AsFloat; AGclNode.FCurGatherQuantity := AGclNode.FCurGatherQuantity + Rec.ValueByName('GatherQuantity').AsFloat; AGclNode.FCurGatherTotalPrice := AGclNode.FCurGatherTotalPrice + Rec.ValueByName('GatherTotalPrice').AsFloat; AGclNode.FEndDealQuantity := AGclNode.FEndDealQuantity + Rec.ValueByName('EndDealQuantity').AsFloat; AGclNode.FEndDealTotalPrice := AGclNode.FEndDealTotalPrice + Rec.ValueByName('EndDealTotalPrice').AsFloat; AGclNode.FEndQcQuantity := AGclNode.FEndQcQuantity + Rec.ValueByName('EndQcQuantity').AsFloat; AGclNode.FEndQcTotalPrice := AGclNode.FEndQcTotalPrice + Rec.ValueByName('EndQcTotalPrice').AsFloat; AGclNode.FEndPcQuantity := AGclNode.FEndPcQuantity + Rec.ValueByName('EndPcQuantity').AsFloat; AGclNode.FEndPcTotalPrice := AGclNode.FEndPcTotalPrice + Rec.ValueByName('EndPcTotalPrice').AsFloat; AGclNode.FEndGatherQuantity := AGclNode.FEndGatherQuantity + Rec.ValueByName('EndGatherQuantity').AsFloat; AGclNode.FEndGatherTotalPrice := AGclNode.FEndGatherTotalPrice + Rec.ValueByName('EndGatherTotalPrice').AsFloat; end; procedure LoadMeasureData(AGclNode: TGclNode; ARec: TsdDataRecord); begin AGclNode.FQuantity := AGclNode.FQuantity + ARec.ValueByName('Quantity').AsFloat; AGclNode.FTotalPrice := AGclNode.FTotalPrice + ARec.ValueByName('TotalPrice').AsFloat; if TProjectData(FProjectData).ProjProperties.PhaseCount = 0 then Exit; LoadPhaseData(AGclNode, ARec.ValueByName('ID').AsInteger); AGclNode.FAddDealQuantity := AGclNode.FAddDealQuantity + ARec.ValueByName('AddDealQuantity').AsFloat; AGclNode.FAddDealTotalPrice := AGclNode.FAddDealTotalPrice + ARec.ValueByName('AddDealTotalPrice').AsFloat; AGclNode.FAddQcQuantity := AGclNode.FAddQcQuantity + ARec.ValueByName('AddQcQuantity').AsFloat; AGclNode.FAddQcTotalPrice := AGclNode.FAddQcTotalPrice + ARec.ValueByName('AddQcTotalPrice').AsFloat; AGclNode.FAddPcQuantity := AGclNode.FAddPcQuantity + ARec.ValueByName('AddPcQuantity').AsFloat; AGclNode.FAddPcTotalPrice := AGclNode.FAddPcTotalPrice + ARec.ValueByName('AddPcTotalPrice').AsFloat; AGclNode.FAddGatherQuantity := AGclNode.FAddGatherQuantity + ARec.ValueByName('AddGatherQuantity').AsFloat; AGclNode.FAddGatherTotalPrice := AGclNode.FAddGatherTotalPrice + ARec.ValueByName('AddGatherTotalPrice').AsFloat; end; var Rec: TsdDataRecord; GclNode: TGclNode; begin if not Assigned(ANode) then Exit; Rec := ANode.Rec; if Rec.ValueByName('B_Code').AsString = '' then Exit; GclNode := GetGclNode(Rec); LoadMeasureData(GclNode, Rec); end; constructor TBillsGatherData.Create(AProjectData: TObject); begin inherited Create(nil); FProjectData := AProjectData; cdsBillsGather.IndexFieldNames := 'IndexCode'; end; destructor TBillsGatherData.Destroy; begin inherited; end; function TBillsGatherData.GetMainBillsTree: TsdIDTree; begin Result := TProjectData(FProjectData).BillsMeasureData.BillsMeasureTree; end; procedure TBillsGatherData.RefreshBills; begin cdsBillsGather.DisableControls; cdsBillsGather.AfterScroll := nil; try cdsBillsGather.EmptyDataSet; FGclList := TList.Create; FilterBills(MainBillsTree.FirstNode); FilterDealBills; WriteGclBills; finally ClearObjects(FGclList); FGclList.Free; cdsBillsGather.EnableControls; cdsBillsGather.AfterScroll := cdsBillsGatherAfterScroll; end; end; procedure TBillsGatherData.cdsBillsGatherQuantityGetText(Sender: TField; var Text: String; DisplayText: Boolean); begin if Sender.AsFloat <> 0 then Text := FormatFloat('0.###', Sender.AsFloat) else Text := ''; end; procedure TBillsGatherData.cdsBillsGatherAfterScroll(DataSet: TDataSet); begin RefreshRelaXmj; end; procedure TBillsGatherData.RefreshRelaXmj; begin cdsRelaXmj.EmptyDataSet; AddRelaXmjs(cdsBillsGatherB_Code.AsString, cdsBillsGatherName.AsString, cdsBillsGatherUnits.AsString, cdsBillsGatherPrice.AsFloat); end; procedure TBillsGatherData.AddRelaXmjs( const AB_Code, AName, AUnits: string; APrice: Double); function GetFirstXmjParent(AID: Integer): TsdIDTreeNode; begin Result := MainBillsTree.FindNode(AID); while Assigned(Result) and (Result.Rec.ValueByName('B_Code').AsString <> '') do Result := Result.Parent; end; // 取树结构的第ALevel层节点的名称(level从0开始) function GetNameByLevel(ANode: TsdIDTreeNode; ALevel: Integer): string; begin Result := ''; if not Assigned(ANode) then Exit; if ANode.Level = ALevel then Result := ANode.Rec.ValueByName('Name').AsString else if ANode.Level > ALevel then Result := GetNameByLevel(ANode.Parent, ALevel); end; function GetPegNode(ANode: TsdIDTreeNode): TsdIDTreeNode; begin Result := nil; if not Assigned(ANode) then Exit; if CheckPeg(ANode.Rec.ValueByName('Name').AsString) then Result := ANode else Result := GetPegNode(ANode.Parent); end; function GetNameDanWei(ANode: TsdIDTreeNode): string; begin // 取树结构的第二层节点的名称 Result := GetNameByLevel(ANode, 1); end; // ANode为计量单元节点,APegNode为桩号节点 function GetNameFenBu(ANode, APegNode: TsdIDTreeNode): string; var vCurNode: TsdIDTreeNode; begin // 如果计量单元节点的名称为桩号(转化为判断计量单元节点与桩号节点为同一个) if not Assigned(APegNode) or (ANode.ID = APegNode.ID) then // 取树结构的第三层节点的名称 Result := GetNameByLevel(ANode, 2) // 否则,取桩号节点的子节点的名称 else begin vCurNode := ANode; while vCurNode.Level > APegNode.Level + 1 do vCurNode := vCurNode.Parent; Result := vCurNode.Rec.ValueByName('Name').AsString; end; end; function GetNameFenXiang(ANode, APegNode: TsdIDTreeNode): string; var iTopLevel: Integer; vCurNode: TsdIDTreeNode; begin if Assigned(APegNode) then begin iTopLevel := 3; if APegNode.ID <> ANode.ID then iTopLevel := APegNode.Level + 2; Result := ''; vCurNode := ANode.Parent; while vCurNode.Level >= iTopLevel do begin Result := vCurNode.Rec.ValueByName('Name').AsString + ';' + Result; vCurNode := vCurNode.Parent; end; end else Result := GetNameByLevel(ANode, 3); end; function GetNameUnit(ANode: TsdIDTreeNode): string; begin Result := ANode.Rec.ValueByName('Name').AsString; end; function GetDrawingCode(ANode: TsdIDTreeNode): string; begin Result := ''; if not Assigned(ANode) then Exit; Result := ANode.Rec.ValueByName('DrawingCode').AsString; if Result = '' then Result := GetDrawingCode(ANode.Parent); end; function GetPegName(APegNode: TsdIDTreeNode): string; begin if Assigned(APegNode) then Result := APegNode.Rec.ValueByName('Name').AsString else Result := ''; end; procedure AddRelaXmj(ARec: TsdDataRecord); var vNode, vPeg: TsdIDTreeNode; begin vNode := GetFirstXmjParent(ARec.ValueByName('ID').AsInteger); if not Assigned(vNode) then Exit; cdsRelaXmj.Append; cdsRelaXmjQuantity.AsFloat := ARec.ValueByName('Quantity').AsFloat; cdsRelaXmjCode.AsString := vNode.Rec.ValueByName('Code').AsString; cdsRelaXmjName.AsString := vNode.Rec.ValueByName('Name').AsString; cdsRelaXmjUnits.AsString := vNode.Rec.ValueByName('Units').AsString; vPeg := GetPegNode(vNode); cdsRelaXmjPeg.AsString := GetPegName(vPeg); cdsRelaXmjNameDanWei.AsString := GetNameDanWei(vNode); cdsRelaXmjNameFenBu.AsString := GetNameFenBu(vNode, vPeg); cdsRelaXmjNameFenXiang.AsString := GetNameFenXiang(vNode, vPeg); cdsRelaXmjNameUnit.AsString := GetNameUnit(vNode); cdsRelaXmjDrawingCode.AsString := GetDrawingCode(vNode); cdsRelaXmj.Post; end; var I: Integer; Rec: TsdDataRecord; begin if AB_Code = '' then Exit; with TProjectData(FProjectData).BillsData do for I := 0 to sddBills.RecordCount - 1 do begin Rec := sddBills.Records[I]; if SameText(AB_Code, Rec.ValueByName('B_Code').AsString) and SameText(AName, Trim(Rec.ValueByName('Name').AsString)) and SameText(AUnits, Rec.ValueByName('Units').AsString) and (APrice = Rec.ValueByName('Price').AsFloat) then AddRelaXmj(Rec); end; end; procedure TBillsGatherData.WriteGclBills; var I: Integer; GclNode: TGclNode; begin for I := 0 to FGclList.Count - 1 do begin GclNode := TGclNode(FGclList.Items[I]); cdsBillsGather.Append; cdsBillsGatherB_Code.AsString := GclNode.FB_Code; cdsBillsGatherIndexCode.AsString := GclNode.FIndexCode; cdsBillsGatherName.AsString := GclNode.FName; cdsBillsGatherUnits.AsString := GclNode.FUnits; cdsBillsGatherPrice.AsFloat := GclNode.FPrice; cdsBillsGatherNewPrice.AsFloat := GclNode.FNewPrice; cdsBillsGatherDealQuantity.AsFloat := GclNode.FDealQuantity; cdsBillsGatherDealTotalPrice.AsFloat := GclNode.FDealTotalPrice; cdsBillsGatherQuantity.AsFloat := GclNode.FQuantity; cdsBillsGatherTotalPrice.AsFloat := GclNode.FTotalPrice; cdsBillsGatherBGLQuantity.AsFloat := GclNode.FBGLQuantity; cdsBillsGatherBGLTotalPrice.AsFloat := GclNode.FBGLTotalPrice; cdsBillsGatherDeal_BGLQuantity.AsFloat := GclNode.FQuantity + GclNode.FBGLQuantity; cdsBillsGatherDeal_BGLTotalPrice.AsFloat := GclNode.FTotalPrice + GclNode.FBGLTotalPrice; cdsBillsGatherCurDealQuantity.AsFloat := GclNode.FCurDealQuantity; cdsBillsGatherCurDealTotalPrice.AsFloat := GclNode.FCurDealTotalPrice; cdsBillsGatherCurQcQuantity.AsFloat := GclNode.FCurQcQuantity; cdsBillsGatherCurQcTotalPrice.AsFloat := GclNode.FCurQcTotalPrice; cdsBillsGatherCurPcQuantity.AsFloat := GclNode.FCurPcQuantity; cdsBillsGatherCurPcTotalPrice.AsFloat := GclNode.FCurPcTotalPrice; cdsBillsGatherCurGatherQuantity.AsFloat := GclNode.FCurGatherQuantity; cdsBillsGatherCurGatherTotalPrice.AsFloat := GclNode.FCurGatherTotalPrice; cdsBillsGatherEndDealQuantity.AsFloat := GclNode.FEndDealQuantity; cdsBillsGatherEndDealTotalPrice.AsFloat := GclNode.FEndDealTotalPrice; cdsBillsGatherEndQcQuantity.AsFloat := GclNode.FEndQcQuantity; cdsBillsGatherEndQcTotalPrice.AsFloat := GclNode.FEndQcTotalPrice; cdsBillsGatherEndPcQuantity.AsFloat := GclNode.FEndPcQuantity; cdsBillsGatherEndPcTotalPrice.AsFloat := GclNode.FEndPcTotalPrice; cdsBillsGatherEndGatherQuantity.AsFloat := GclNode.FEndGatherQuantity; cdsBillsGatherEndGatherTotalPrice.AsFloat := GclNode.FEndGatherTotalPrice; cdsBillsGatherAddDealQuantity.AsFloat := GclNode.FAddDealQuantity; cdsBillsGatherAddDealTotalPrice.AsFloat := GclNode.FAddDealTotalPrice; cdsBillsGatherAddQcQuantity.AsFloat := GclNode.FAddQcQuantity; cdsBillsGatherAddQcTotalPrice.AsFloat := GclNode.FAddQcTotalPrice; cdsBillsGatherAddPcQuantity.AsFloat := GclNode.FAddPcQuantity; cdsBillsGatherAddPcTotalPrice.AsFloat := GclNode.FAddPcTotalPrice; cdsBillsGatherAddGatherQuantity.AsFloat := GclNode.FAddGatherQuantity; cdsBillsGatherAddGatherTotalPrice.AsFloat := GclNode.FAddGatherTotalPrice; if (GclNode.FTotalPrice + GclNode.FBGLTotalPrice) <> 0 then cdsBillsGatherCompletionRate.AsFloat := AdvRoundTo( GclNode.FEndGatherTotalPrice/(GclNode.FTotalPrice + GclNode.FBGLTotalPrice)*100); cdsBillsGather.Post; end; end; procedure TBillsGatherData.FilterDealBills; var iIndex: Integer; Rec: TsdDataRecord; GclNode: TGclNode; begin with TProjectData(FProjectData).DealBillsData do for iIndex := 0 to sddDealBills.RecordCount - 1 do begin Rec := sddDealBills.Records[iIndex]; GclNode := GetGclNode(Rec); GclNode.FDealQuantity := GclNode.FDealQuantity + Rec.ValueByName('Quantity').AsFloat; GclNode.FDealTotalPrice := GclNode.FDealTotalPrice + Rec.ValueByName('TotalPrice').AsFloat; end; end; function TBillsGatherData.GetGclNode(ARec: TsdDataRecord): TGclNode; procedure LoadBGLData(AGclNode: TGclNode); begin with TProjectData(FProjectData).BGLData do begin cdsBGBills.First; while not cdsBGBills.Eof do begin if SameText(AGclNode.FB_Code, cdsBGBillsB_Code.AsString) and SameText(AGclNode.FName, Trim(cdsBGBillsName.AsString)) and SameText(AGclNode.FUnits, cdsBGBillsUnits.AsString) and (AGclNode.FPrice = cdsBGBillsPrice.AsFloat) then begin AGclNode.FBGLQuantity := AGclNode.FBGLQuantity + cdsBGBillsQuantity.AsFloat; AGclNode.FBGLTotalPrice := AGclNode.FBGLTotalPrice + cdsBGBillsTotalPrice.AsFloat; end; cdsBGBills.Next; end; end; end; function CreateGclNode: TGclNode; begin Result := TGclNode.Create; FGclList.Add(Result); Result.FB_Code := ARec.ValueByName('B_Code').AsString; Result.FIndexCode := B_CodeToIndexCode(ARec.ValueByName('B_Code').AsString); Result.FName := Trim(ARec.ValueByName('Name').AsString); Result.FUnits := ARec.ValueByName('Units').AsString; Result.FPrice := ARec.ValueByName('Price').AsFloat; if Assigned(ARec.ValueByName('NewPrice')) then Result.FNewPrice := ARec.ValueByName('NewPrice').AsFloat else Result.FNewPrice := 0; LoadBGLData(Result); end; var I: Integer; GclNode: TGclNode; begin Result := nil; for I := 0 to FGclList.Count - 1 do begin GclNode := TGclNode(FGclList.Items[I]); if SameText(GclNode.FB_Code, ARec.ValueByName('B_Code').AsString) and SameText(GclNode.FName, Trim(ARec.ValueByName('Name').AsString)) and SameText(GclNode.FUnits, ARec.ValueByName('Units').AsString) and (PriceRoundTo(GclNode.FPrice - ARec.ValueByName('Price').AsFloat) = 0) then begin Result := GclNode; Break; end; end; if not Assigned(Result) then Result := CreateGclNode; end; end.