unit ProjectGLDm; interface uses SysUtils, Classes, sdDB, sdProvider, ADODB, mDataRecord, CalcDecimal; type TProjectGLData = class(TDataModule) sdpProjectGL: TsdADOProvider; sddProjectGL: TsdDataSet; sdvProjectGL: TsdDataView; smpGather: TsdMemoryProvider; sddGather: TsdDataSet; sdvGather: TsdDataView; procedure sddProjectGLAfterAddRecord(ARecord: TsdDataRecord); procedure sddProjectGLAfterValueChanged(AValue: TsdValue); procedure sdvProjectGLGetText(var Text: String; ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn; DisplayText: Boolean); procedure sddProjectGLGetRecordClass(var ARecordClass: TsdRecordClass); procedure sdvProjectGLSetText(var Text: String; ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn; var Allow: Boolean); procedure sddProjectGLBeforeDeleteRecord(ARecord: TsdDataRecord; var Allow: Boolean); procedure sdvGatherGetText(var Text: String; ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn; DisplayText: Boolean); private FProjectData: TObject; FTempGLs: TList; function CheckSameCode(ACode: Integer): Boolean; function CheckApplied(AGLID: Integer): Boolean; procedure LoadDetailGLs(AGLID: Integer); procedure CalculateDeltaPrice(ARec: TProjectGLRecord); procedure CalculatePrice; procedure CalculatePM_Quantity(ARec: TProjectGLRecord); procedure CalculatePM_TotalPrice(ARec: TProjectGLRecord); procedure CalculatePriceMargin; procedure CalculateRelaBills(ARec: TProjectGLRecord); procedure CalculatePALRela(ARec: TProjectGLRecord); procedure CalculatePALRelas; procedure SaveGLPrice; procedure SavePM_CurData; procedure CalcRecGather(ARec: TsdDataRecord; const AFieldName, APreFieldName: string); procedure BeforeBatchOperation; procedure AfterBatchOperation; function GetValidDeltaPrice(AID: Integer): Double; function GetPM_TotalPrice: Double; function GetActive: Boolean; function GetDecimal: TCalcDecimal; public constructor Create(AProjectData: TObject); destructor Destroy; override; procedure Open(AConnection: TADOConnection); procedure Save; procedure LoadCurPhaseInfoPrice; procedure LoadStagePM_CalcData; procedure CalculateAll; procedure CalculateGL_PM(AGLID: Integer); procedure CalculateGLs_PM(ADetailGLs: TList); procedure RefreshGatherData; property ProjectData: TObject read FProjectData write FProjectData; property Active: Boolean read GetActive; property ValidDeltaPrice[AID: Integer]: Double read GetValidDeltaPrice; property PM_TotalPrice: Double read GetPM_TotalPrice; property Decimal: TCalcDecimal read GetDecimal; end; implementation uses ProjectData, UtilMethods, DB, Variants, PhaseData, DetailGLDm, BillsMeasureDm, BillsTree, sdIDTree, PhasePayDm, DateUtils, ZhAPI; {$R *.dfm} { TProjectGLData } function TProjectGLData.CheckSameCode(ACode: Integer): Boolean; var Rec: TsdDataRecord; begin Rec := sddProjectGL.FindKey('idxCode', ACode); Result := Assigned(Rec); end; constructor TProjectGLData.Create(AProjectData: TObject); begin inherited Create(nil); FProjectData := AProjectData; FTempGLs := TList.Create; end; destructor TProjectGLData.Destroy; begin FTempGLs.Free; inherited; end; procedure TProjectGLData.LoadCurPhaseInfoPrice; const sSelectSql = 'Select * From GLPrice Where PhaseID = %d'; var sSql: string; vQuery: TADOQuery; procedure LoadInfoPrice; var iRec: Integer; Rec: TProjectGLRecord; begin for iRec := 0 to sddProjectGL.RecordCount - 1 do begin Rec := TProjectGLRecord(sddProjectGL.Records[iRec]); if vQuery.Active and vQuery.Locate('GLID', Rec.ValueByName('ID').AsInteger, []) then begin Rec.InfoPrice.AsFloat := vQuery.FieldByName('InfoPrice').AsFloat; Rec.InfoDate.AsString := vQuery.FieldByName('InfoDate').AsString; Rec.DeltaPrice.AsFloat := vQuery.FieldByName('DeltaPrice').AsFloat; Rec.ValidDeltaPrice.AsFloat := vQuery.FieldByName('ValidDeltaPrice').AsFloat; Rec.UsedQuantity.AsFloat := vQuery.FieldByName('UsedQuantity').AsFloat; Rec.UsedTotalPrice.AsFloat := vQuery.FieldByName('UsedTotalPrice').AsFloat; Rec.PreUsedQuantity.AsFloat := vQuery.FieldByName('PreUsedQuantity').AsFloat; Rec.PreUsedTotalPrice.AsFloat := vQuery.FieldByName('PreUsedTotalPrice').AsFloat; end else begin Rec.InfoPrice.AsFloat := 0; Rec.InfoDate.AsString := ''; Rec.DeltaPrice.AsFloat := 0; Rec.ValidDeltaPrice.AsFloat := 0; Rec.UsedQuantity.AsFloat := 0; Rec.UsedTotalPrice.AsFloat := 0; Rec.PreUsedQuantity.AsFloat := 0; Rec.PreUsedTotalPrice.AsFloat := 0; end; end; end; begin BeforeBatchOperation; vQuery := TADOQuery.Create(nil); try vQuery.Connection := sdpProjectGL.Connection; sSql := Format(sSelectSql, [TProjectData(FProjectData).PhaseIndex]); vQuery.SQL.Clear; vQuery.SQL.Add(sSql); vQuery.Open; LoadInfoPrice; finally vQuery.Free; AfterBatchOperation; end; end; procedure TProjectGLData.Open(AConnection: TADOConnection); begin sdpProjectGL.Connection := AConnection; sddProjectGL.Open; if not Assigned(sddProjectGL.IndexList.FindByName('idxID')) then sddProjectGL.AddIndex('idxID', 'ID'); if not Assigned(sddProjectGL.IndexList.FindByName('idxCode')) then sddProjectGL.AddIndex('idxCode', 'Code'); sdvProjectGL.Open; sdvProjectGL.IndexName := 'idxCode'; LoadCurPhaseInfoPrice; LoadStagePM_CalcData; RefreshGatherData; end; procedure TProjectGLData.Save; begin sddProjectGL.Save; if not TProjectData(FProjectData).PriceMarginReadOnly then SaveGLPrice; if not TProjectData(FProjectData).StageDataReadOnly then SavePM_CurData; end; procedure TProjectGLData.SaveGLPrice; const sDeleteSql = 'Delete From GLPrice Where PhaseID = %d'; sInsertSql = 'Insert Into GLPrice'+ ' Select ID As GLID, %d As PhaseID, InfoPrice, InfoDate, DeltaPrice, ValidDeltaPrice, UsedQuantity, UsedTotalPrice' + ' From ProjectGL'; sUpdateSql = 'Update GLPrice As G, ProjectGL As P'+ ' Set G.PM_PreQuantity = P.PM_PreQuantity, G.PM_PreTotalPrice = P.PM_PreTotalPrice,'+ ' G.PrePAL_UsedQuantity = P.PrePAL_UsedQuantity, G.PrePAL_UsedTotalPrice = P.PrePAL_UsedTotalPrice,' + ' G.PrePAL_DeltaPrice = P.PrePAL_DeltaPrice, G.PrePAL_Total = P.PrePAL_Total'+ ' Where (G.PhaseID = %d) and (G.GLID = P.ID)'; var iPhaseID: Integer; sSql: String; begin iPhaseID := TProjectData(FProjectData).ProjProperties.PhaseCount; sSql := Format(sDeleteSql, [iPhaseID]); ExecuteSql(sdpProjectGL.Connection, sSql); sSql := Format(sInsertSql, [iPhaseID]); ExecuteSql(sdpProjectGL.Connection, sSql); sSql := Format(sUpdateSql, [iPhaseID]); ExecuteSql(sdpProjectGL.Connection, sSql); end; procedure TProjectGLData.sddProjectGLAfterAddRecord( ARecord: TsdDataRecord); begin ARecord.ValueByName('ID').AsInteger := GetsdDataSetNewID(sddProjectGL, 'idxID'); ARecord.ValueByName('CreatePhaseID').AsInteger := TProjectData(FProjectData).ProjProperties.PhaseCount; end; procedure TProjectGLData.sddProjectGLAfterValueChanged(AValue: TsdValue); begin if SameText(AValue.FieldName, 'BasePrice') or SameText(AValue.FieldName, 'RiskRange') or SameText(AValue.FieldName, 'InfoPrice') then begin CalculateDeltaPrice(TProjectGLRecord(AValue.Owner)); CalculatePM_Quantity(TProjectGLRecord(AValue.Owner)); CalculatePM_TotalPrice(TProjectGLRecord(AValue.Owner)); CalculatePALRela(TProjectGLRecord(AValue.Owner)); CalculateRelaBills(TProjectGLRecord(AValue.Owner)); TProjectData(FProjectData).PriceMarginBillsData.RefreshAllDetailBills; RefreshGatherData; end; if SameText(AValue.FieldName, 'UsedQuantity') then begin CalculatePALRela(TProjectGLRecord(AValue.Owner)); RefreshGatherData; end; end; procedure TProjectGLData.CalculateDeltaPrice(ARec: TProjectGLRecord); var C0, Ci, r, DeltaC, RiskC, ValidDeltaC: Double; begin C0 := ARec.BasePrice.AsFloat; Ci := ARec.InfoPrice.AsFloat; r := ARec.RiskRange.AsFloat; DeltaC := Ci - C0; RiskC := C0 * r / 100; if (DeltaC > 0) and (DeltaC - RiskC > 0) then ValidDeltaC := DeltaC - RiskC else if (DeltaC < 0) and (DeltaC + RiskC < 0) then ValidDeltaC := DeltaC + RiskC else ValidDeltaC := 0; if DeltaC <> ARec.DeltaPrice.AsFloat then ARec.DeltaPrice.AsFloat := Decimal.Price.RoundTo(DeltaC); if ValidDeltaC <> ARec.ValidDeltaPrice.AsFloat then ARec.ValidDeltaPrice.AsFloat := Decimal.Price.RoundTo(ValidDeltaC); end; procedure TProjectGLData.sdvProjectGLGetText(var Text: String; ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn; DisplayText: Boolean); procedure GetDisplayText; begin if ((Pos('Price', AColumn.FieldName) > 0) or (Pos('Quantity', AColumn.FieldName) > 0) or (Pos('PAL', AColumn.FieldName) = 1) or SameText('RiskRange', AColumn.FieldName)) then begin if AValue.AsFloat = 0 then Text := ''; end; end; begin if DisplayText then GetDisplayText; end; procedure TProjectGLData.CalculateAll; begin CalculatePrice; TProjectData(FProjectData).PhaseData.StageData.CalculateAll; TProjectData(FProjectData).PriceMarginBillsData.RefreshAllDetailBills; CalculatePriceMargin; CalculatePALRelas; RefreshGatherData; end; function TProjectGLData.GetValidDeltaPrice(AID: Integer): Double; var Rec: TProjectGLRecord; begin Rec := TProjectGLRecord(sddProjectGL.FindKey('idxID', AID)); if Assigned(Rec) then Result := Rec.ValidDeltaPrice.AsFloat else Result := 0; end; procedure TProjectGLData.CalculatePrice; var iRec: Integer; begin if TProjectData(FProjectData).PriceMarginReadOnly then Exit; for iRec := 0 to sddProjectGL.RecordCount - 1 do CalculateDeltaPrice(TProjectGLRecord(sddProjectGL.Records[iRec])); end; procedure TProjectGLData.CalculatePriceMargin; var iRec: Integer; Rec: TProjectGLRecord; begin if TProjectData(FProjectData).PhaseData.StageDataReadOnly then Exit; for iRec := 0 to sddProjectGL.RecordCount - 1 do begin Rec := TProjectGLRecord(sddProjectGL.Records[iRec]); CalculatePM_Quantity(Rec); CalculatePM_TotalPrice(Rec); end; end; procedure TProjectGLData.CalculatePM_Quantity(ARec: TProjectGLRecord); var vGLs: TList; fQuantity: Double; i: Integer; GLRec: TsdDataRecord; BillsNode: TMeasureBillsIDTreeNode; begin vGLs := TList.Create; try fQuantity := 0; with TProjectData(FProjectData).DetailGLData do LoadProjectGL_DetailGLs(ARec.ValueByName('ID').AsInteger, vGLs); for i := 0 to vGLs.Count - 1 do begin GLRec := TsdDataRecord(vGLs.Items[i]); with TProjectData(FProjectData).BillsMeasureData do BillsNode := TMeasureBillsIDTreeNode(BillsMeasureTree.FindNode(GLRec.ValueByName('BillsID').AsInteger)); if Assigned(BillsNode.StageRec) then fQuantity := fQuantity + Decimal.Quantity.RoundTo(BillsNode.StageRec.GatherQuantity.AsFloat * GLRec.ValueByName('Quantity').AsFloat); end; if fQuantity <> ARec.PM_Quantity.AsFloat then ARec.PM_Quantity.AsFloat := Decimal.Quantity.RoundTo(fQuantity); finally vGLs.Free; end; end; procedure TProjectGLData.CalculatePM_TotalPrice(ARec: TProjectGLRecord); var fTotalPrice: Double; begin fTotalPrice := ARec.ValidDeltaPrice.AsFloat * ARec.PM_Quantity.AsFloat; if fTotalPrice <> ARec.PM_TotalPrice.AsFloat then ARec.PM_TotalPrice.AsFloat := Decimal.TotalPrice.RoundTo(fTotalPrice); end; procedure TProjectGLData.sddProjectGLGetRecordClass( var ARecordClass: TsdRecordClass); begin ARecordClass := TProjectGLRecord; end; function TProjectGLData.GetPM_TotalPrice: Double; var i: Integer; Rec: TProjectGLRecord; begin Result := 0; for i := 0 to sddProjectGL.RecordCount - 1 do begin Rec := TProjectGLRecord(sddProjectGL.Records[i]); Result := Result + Rec.PM_TotalPrice.AsFloat; end; end; procedure TProjectGLData.SavePM_CurData; const sUpdateSql = 'Update GLPrice As G, ProjectGL As P'+ ' Set G.PM_Quantity%d = P.PM_Quantity, G.PM_TotalPrice%d = P.PM_TotalPrice,'+ ' G.PAL_UsedQuantity%d = P.PAL_UsedQuantity, G.PAL_UsedTotalPrice%d = P.PAL_UsedTotalPrice,'+ ' G.PAL_DeltaPrice%d = P.PAL_DeltaPrice, G.PAL_Total%d = P.PAL_Total,'+ ' G.PM_Quantity_F = P.PM_Quantity, G.PM_TotalPrice_F = P.PM_TotalPrice,'+ ' G.PAL_UsedQuantity_F = P.PAL_UsedQuantity, G.PAL_UsedTotalPrice_F = P.PAL_UsedTotalPrice,'+ ' G.PAL_DeltaPrice_F = P.PAL_DeltaPrice, G.PAL_Total_F = P.PAL_Total'+ ' Where (G.PhaseID = %d) and (G.GLID = P.ID)'; var iStageIndex: Integer; iPhaseCount: Integer; sSql: string; begin iStageIndex := TProjectData(FProjectData).PhaseData.StageIndex; iPhaseCount := TProjectData(FProjectData).ProjProperties.PhaseCount; sSql := Format(sUpdateSql, [iStageIndex, iStageIndex, iStageIndex, iStageIndex, iStageIndex, iStageIndex, iPhaseCount]); ExecuteSql(sdpProjectGL.Connection, sSql); end; procedure TProjectGLData.CalculateGL_PM(AGLID: Integer); var Rec: TProjectGLRecord; begin Rec := TProjectGLRecord(sddProjectGL.FindKey('idxID', AGLID)); if not Assigned(Rec) then Exit; CalculatePM_Quantity(Rec); CalculatePM_TotalPrice(Rec); CalculatePALRela(Rec); end; procedure TProjectGLData.CalculateGLs_PM(ADetailGLs: TList); var i: Integer; DetailGLRec: TDetailGLRecord; begin for i := 0 to ADetailGLs.Count - 1 do begin DetailGLRec := TDetailGLRecord(ADetailGLs.Items[i]); CalculateGL_PM(DetailGLRec.GLID.AsInteger); end; end; procedure TProjectGLData.CalculateRelaBills(ARec: TProjectGLRecord); var iGL: Integer; DetailGLRec: TDetailGLRecord; begin LoadDetailGLs(ARec.ID.AsInteger); for iGL := 0 to FTempGLs.Count - 1 do begin DetailGLRec := TDetailGLRecord(FTempGLs.Items[iGL]); with TProjectData(FProjectData).PhaseData do StageData.CalculatePriceMargin(DetailGLRec.BillsID.AsInteger); end; {with TProjectData(FProjectData).PhaseData do StageData.CalculatePriceMarginNode;} end; procedure TProjectGLData.LoadDetailGLs(AGLID: Integer); begin FTempGLs.Clear; with TProjectData(FProjectData).DetailGLData do LoadProjectGL_DetailGLs(AGLID, FTempGLs); end; function TProjectGLData.GetActive: Boolean; begin Result := sddProjectGL.Active; end; procedure TProjectGLData.sdvProjectGLSetText(var Text: String; ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn; var Allow: Boolean); var iPhaseID: Integer; Rec: TProjectGLRecord; begin Rec := TProjectGLRecord(ARecord); if SameText(AColumn.FieldName, 'Code') or SameText(AColumn.FieldName, 'Name') or SameText(AColumn.FieldName, 'Units') or SameText(AColumn.FieldName, 'Specs') or SameText(AColumn.FieldName, 'BasePrice') or SameText(AColumn.FieldName, 'RiskRange') then begin iPhaseID := Rec.LockedPhaseID.AsInteger; if iPhaseID > 0 then DataSetErrorMessage(Allow, Format('该工料在第%d期已进行调差计算,不可修改基础数据。', [iPhaseID])); end; if AValue.DataType in [ftInteger, ftFloat] then if not CheckNumeric(Text) then Text := ''; if SameText(AColumn.FieldName, 'Code') then begin if StrToIntDef(Text, 0) = 0 then begin DataSetErrorMessage(Allow, '编号不可为0或空。'); if Rec.Code.AsString = '' then sddProjectGL.Remove(ARecord); end else if CheckSameCode(StrToInt(Text)) then begin DataSetErrorMessage(Allow, '编号不可重复。'); if Rec.Code.AsString = '' then sddProjectGL.Remove(AValue.Owner); end else if CheckApplied(Rec.ID.AsInteger) then DataSetErrorMessage(Allow, '工料已被应用,不可修改编号。'); end else begin if (Rec.Code.AsString = '') then begin DataSetErrorMessage(Allow, '编号不可为空,请先填写编号,再填写其他信息。'); sddProjectGL.Remove(AValue.Owner); end; end; if AValue.FieldName = 'BasePrice' then Text := Decimal.Price.StrRoundTo(Text) else if AValue.FieldName = 'InfoPrice' then Text := Decimal.Price.StrRoundTo(Text) else if SameText(AValue.FieldName, 'UsedQuantity') then Text := Decimal.Quantity.StrRoundTo(Text); end; procedure TProjectGLData.LoadStagePM_CalcData; const sSelectSql = 'Select GLID, PhaseID, PM_PreQuantity, PM_PreTotalPrice,'+ ' PrePAL_UsedQuantity, PrePAL_UsedTotalPrice, PrePAL_DeltaPrice, PrePAL_Total,' + ' PM_Quantity%d As PM_Quantity, PM_TotalPrice%d As PM_TotalPrice,'+ ' PAL_UsedQuantity%d As PAL_UsedQuantity, PAL_UsedTotalPrice%d As PAL_UsedTotalPrice,' + ' PAL_DeltaPrice%d As PAL_DeltaPrice, PAL_Total%d As PAL_Total' + ' From GLPrice Where PhaseID = %d'; var sSql: string; vQuery: TADOQuery; procedure LoadPM_Calc; var iRec: Integer; Rec: TProjectGLRecord; begin for iRec := 0 to sddProjectGL.RecordCount - 1 do begin Rec := TProjectGLRecord(sddProjectGL.Records[iRec]); if vQuery.Active and vQuery.Locate('GLID', Rec.ValueByName('ID').AsInteger, []) then begin Rec.PM_Quantity.AsFloat := vQuery.FieldByName('PM_Quantity').AsFloat; Rec.PM_TotalPrice.AsFloat := vQuery.FieldByName('PM_TotalPrice').AsFloat; Rec.PM_PreQuantity.AsFloat := vQuery.FieldByName('PM_PreQuantity').AsFloat; Rec.PM_PreTotalPrice.AsFloat := vQuery.FieldByName('PM_PreTotalPrice').AsFloat; Rec.PAL_UsedQuantity.AsFloat := vQuery.FieldByName('PAL_UsedQuantity').AsFloat; Rec.PAL_UsedTotalPrice.AsFloat := vQuery.FieldByName('PAL_UsedTotalPrice').AsFloat; Rec.PAL_DeltaPrice.AsFloat := vQuery.FieldByName('PAL_DeltaPrice').AsFloat; Rec.PAL_Total.AsFloat := vQuery.FieldByName('PAL_Total').AsFloat; Rec.PrePAL_UsedQuantity.AsFloat := vQuery.FieldByName('PrePAL_UsedQuantity').AsFloat; Rec.PrePAL_UsedTotalPrice.AsFloat := vQuery.FieldByName('PrePAL_UsedTotalPrice').AsFloat; Rec.PrePAL_DeltaPrice.AsFloat := vQuery.FieldByName('PrePAL_DeltaPrice').AsFloat; Rec.PrePAL_Total.AsFloat := vQuery.FieldByName('PrePAL_Total').AsFloat; end else begin Rec.PM_Quantity.AsFloat := 0; Rec.PM_TotalPrice.AsFloat := 0; Rec.PM_PreQuantity.AsFloat := 0; Rec.PM_PreTotalPrice.AsFloat := 0; Rec.PAL_UsedQuantity.AsFloat := 0; Rec.PAL_UsedTotalPrice.AsFloat := 0; Rec.PAL_DeltaPrice.AsFloat := 0; Rec.PAL_Total.AsFloat := 0; Rec.PrePAL_UsedQuantity.AsFloat := 0; Rec.PrePAL_UsedTotalPrice.AsFloat := 0; Rec.PrePAL_DeltaPrice.AsFloat := 0; Rec.PrePAL_Total.AsFloat := 0; end; end; end; begin BeforeBatchOperation; vQuery := TADOQuery.Create(nil); try vQuery.Connection := sdpProjectGL.Connection; with TProjectData(FProjectData) do sSql := Format(sSelectSql, [StageIndex, StageIndex, StageIndex, StageIndex, StageIndex, StageIndex, PhaseIndex]); vQuery.SQL.Clear; vQuery.SQL.Add(sSql); vQuery.Open; LoadPM_Calc; finally vQuery.Free; AfterBatchOperation; end; end; procedure TProjectGLData.AfterBatchOperation; begin sddProjectGL.EndUpdate; sddProjectGL.EnableControls; sddProjectGL.AfterValueChanged := sddProjectGLAfterValueChanged; end; procedure TProjectGLData.BeforeBatchOperation; begin sddProjectGL.AfterValueChanged := nil; sddProjectGL.DisableControls; sddProjectGL.BeginUpdate; end; function TProjectGLData.CheckApplied(AGLID: Integer): Boolean; begin LoadDetailGLs(AGLID); Result := FTempGLs.Count > 0; end; procedure TProjectGLData.sddProjectGLBeforeDeleteRecord( ARecord: TsdDataRecord; var Allow: Boolean); begin Allow := not CheckApplied(ARecord.ValueByName('ID').AsInteger); if not Allow then ErrorMessage('工料已被应用,不可删除。'); end; function TProjectGLData.GetDecimal: TCalcDecimal; begin Result := TProjectData(FProjectData).ProjProperties.DecimalManager.PriceMargin; end; procedure TProjectGLData.CalculatePALRela(ARec: TProjectGLRecord); begin ARec.UsedTotalPrice.AsFloat := Decimal.TotalPrice.RoundTo(ARec.UsedQuantity.AsFloat * ARec.InfoPrice.AsFloat); ARec.PAL_UsedQuantity.AsFloat := Decimal.Quantity.RoundTo(ARec.PM_Quantity.AsFloat - ARec.UsedQuantity.AsFloat); ARec.PAL_UsedTotalPrice.AsFloat := Decimal.TotalPrice.RoundTo(ARec.PAL_UsedQuantity.AsFloat * ARec.BasePrice.AsFloat); ARec.PAL_DeltaPrice.AsFloat := Decimal.TotalPrice.RoundTo( - ARec.UsedQuantity.AsFloat * ARec.DeltaPrice.AsFloat); ARec.PAL_Total.AsFloat := Decimal.TotalPrice.RoundTo(ARec.BasePrice.AsFloat*ARec.PM_Quantity.AsFloat - ARec.InfoPrice.AsFloat*ARec.UsedQuantity.AsFloat); end; procedure TProjectGLData.CalculatePALRelas; var iRec: Integer; Rec: TProjectGLRecord; begin if TProjectData(FProjectData).PhaseData.StageDataReadOnly then Exit; for iRec := 0 to sddProjectGL.RecordCount - 1 do begin Rec := TProjectGLRecord(sddProjectGL.Records[iRec]); CalculatePALRela(Rec); end; end; procedure TProjectGLData.RefreshGatherData; var Rec: TsdDataRecord; begin sddGather.BeginUpdate; sddGather.DeleteAll; Rec := sddGather.Add; Rec.ValueByName('ID').AsInteger := 0; Rec.ValueByName('Name').AsString := '材料调差'; CalcRecGather(Rec, 'PM_TotalPrice', 'PM_PreTotalPrice'); Rec := sddGather.Add; Rec.ValueByName('ID').AsInteger := 1; Rec.ValueByName('Name').AsString := '实耗数量差'; CalcRecGather(Rec, 'PAL_UsedTotalPrice', 'PrePAL_UsedTotalPrice'); Rec := sddGather.Add; Rec.ValueByName('ID').AsInteger := 2; Rec.ValueByName('Name').AsString := '实耗价差'; CalcRecGather(Rec, 'PAL_DeltaPrice', 'PrePAL_DeltaPrice'); Rec := sddGather.Add; Rec.ValueByName('ID').AsInteger := 3; Rec.ValueByName('Name').AsString := '节余金额'; CalcRecGather(Rec, 'PAL_Total', 'PrePAL_Total'); sddGather.EndUpdate; end; procedure TProjectGLData.CalcRecGather(ARec: TsdDataRecord; const AFieldName, APreFieldName: string); const sSelectSql = 'Select (Sum(%s)+Sum(%s_F)) As AddGather'+ ' From GLPrice, (Select Max(PhaseID) As MaxPhaseID From GLPrice)'+ ' Where PhaseID = MaxPhaseID'; var iRec: Integer; RecGL: TsdDataRecord; vQuery: TADOQuery; fCur, fPre: Double; begin fCur := 0; fPre := 0; for iRec := 0 to sddProjectGL.RecordCount - 1 do begin RecGL := sddProjectGL.Records[iRec]; fCur := fCur + RecGL.ValueByName(AFieldName).AsFloat; fPre := fPre + RecGL.ValueByName(APreFieldName).AsFloat; end; ARec.ValueByName('CurTotalPrice').AsFloat := Decimal.TotalPrice.RoundTo(fCur); ARec.ValueByName('PreTotalPrice').AsFloat := Decimal.TotalPrice.RoundTo(fPre); ARec.ValueByName('EndTotalPrice').AsFloat := Decimal.TotalPrice.RoundTo(fPre + fCur); ARec.ValueByName('AddTotalPrice').AsFloat := Decimal.TotalPrice.RoundTo(fPre + fCur); with TProjectData(FProjectData) do begin if PhaseIndex <> ProjProperties.PhaseCount then begin vQuery := TADOQuery.Create(nil); vQuery.Connection := ADOConnection; try vQuery.SQL.Clear; vQuery.SQL.Add(Format(sSelectSql, [APreFieldName, AFieldName])); vQuery.Open; ARec.ValueByName('AddTotalPrice').AsFloat := Decimal.TotalPrice.RoundTo(vQuery.FieldByName('AddGather').AsFloat); finally vQuery.Free; end; end; end; end; procedure TProjectGLData.sdvGatherGetText(var Text: String; ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn; DisplayText: Boolean); procedure GetDisplayText; begin if Pos('TotalPrice', AColumn.FieldName) > 0 then if (AValue.AsFloat = 0) then Text := ''; end; begin if DisplayText then GetDisplayText; end; end.