unit OtherMeasurePhaseDm; interface uses SysUtils, Classes, sdDB, sdProvider, ADODB, OMPhaseRecord; type TOtherMeasurePhaseData = class(TDataModule) sdpPhase: TsdADOProvider; sddPhase: TsdDataSet; sdvPhase: TsdDataView; procedure sdvPhaseBeforeAddRecord(ARecord: TsdDataRecord; var Allow: Boolean); procedure sdvPhaseAfterValueChanged(AValue: TsdValue); procedure sddPhaseGetRecordClass(var ARecordClass: TsdRecordClass); procedure sddPhaseAfterValueChanged(AValue: TsdValue); procedure sdvPhaseSetText(var Text: String; ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn; var Allow: Boolean); private FProjectData: TObject; function GetNewID: Integer; function GetNewSerialNo: Integer; procedure SaveDetailData; procedure BeforeBatchOperation; procedure AfterBatchOperation; public constructor Create(AProjectData: TObject); destructor Destroy; override; procedure Open(AConnection: TADOConnection); procedure Save; procedure LoadCurStageData; end; implementation uses ProjectData, UtilMethods, Math; {$R *.dfm} { TOtherMeasurePhaseData } procedure TOtherMeasurePhaseData.AfterBatchOperation; begin sddPhase.EndUpdate; sddPhase.EnableControls; sddPhase.AfterValueChanged := sddPhaseAfterValueChanged; end; procedure TOtherMeasurePhaseData.BeforeBatchOperation; begin sddPhase.AfterValueChanged := nil; sddPhase.DisableControls; sddPhase.BeginUpdate; end; constructor TOtherMeasurePhaseData.Create(AProjectData: TObject); begin inherited Create(nil); FProjectData := AProjectData; end; destructor TOtherMeasurePhaseData.Destroy; begin inherited; end; function TOtherMeasurePhaseData.GetNewID: Integer; var idx: TsdIndex; begin idx := sddPhase.FindIndex('idxID'); if idx.RecordCount > 0 then Result := idx.Records[idx.RecordCount - 1].ValueByName('ID').AsInteger + 1 else Result := 1; end; function TOtherMeasurePhaseData.GetNewSerialNo: Integer; var idx: TsdIndex; begin idx := sddPhase.FindIndex('idxSerial'); if idx.RecordCount > 0 then Result := idx.Records[idx.RecordCount - 1].ValueByName('SerialNo').AsInteger + 1 else Result := 1; end; procedure TOtherMeasurePhaseData.LoadCurStageData; procedure LoadData; const sSelectSql = 'Select * From OMPhaseDetail Where (PhaseID = %d) and (StageID = %d)'; var vQuery: TADOQuery; i: Integer; Rec: TOMPhaseRecord; begin try with TProjectData(FProjectData) do vQuery := QueryData(sdpPhase.Connection, Format(sSelectSql, [PhaseIndex, StageIndex])); for i := 0 to sddPhase.RecordCount - 1 do begin Rec := TOMPhaseRecord(sddPhase.Records[i]); if vQuery.Locate('ID', Rec.ValueByName('ID').AsInteger, []) then begin Rec.PreTotalPrice.AsFloat := vQuery.FieldByName('PreTotalPrice').AsFloat; Rec.CurTotalPrice.AsFloat := vQuery.FieldByName('CurTotalPrice').AsFloat; Rec.EndTotalPrice.AsFloat := vQuery.FieldByName('EndTotalPrice').AsFloat; end else begin Rec.PreTotalPrice.AsFloat := 0; Rec.CurTotalPrice.AsFloat := 0; Rec.EndTotalPrice.AsFloat := 0; end; end; finally vQuery.Free; end; end; begin BeforeBatchOperation; try LoadData; finally AfterBatchOperation; end; end; procedure TOtherMeasurePhaseData.Open(AConnection: TADOConnection); begin sdpPhase.Connection := AConnection; sddPhase.Open; if not Assigned(sddPhase.FindIndex('idxID')) then sddPhase.AddIndex('idxID', 'ID'); if not Assigned(sddPhase.FindIndex('idxSerial')) then sddPhase.AddIndex('idxSerial', 'SerialNo'); sdvPhase.Open; sdvPhase.IndexName := 'idxSerial'; LoadCurStageData; end; procedure TOtherMeasurePhaseData.Save; begin sddPhase.Save; if not TProjectData(FProjectData).StageDataReadOnly then SaveDetailData; end; procedure TOtherMeasurePhaseData.SaveDetailData; const sDeleteSql = 'Delete From OMPhaseDetail where (PhaseID = %d) and (StageID = %d)'; sInsertSql = 'Insert Into OMPhaseDetail' + ' Select ID, %d As PhaseID, %d As StageID, PreTotalPrice, CurTotalPrice, EndTotalPrice' + ' From OtherMeasurePhase'; var iPhase, iStage: Integer; vQuery: TADOQuery; begin if TProjectData(FProjectData).StageDataReadOnly then Exit; iPhase := TProjectData(FProjectData).PhaseIndex; iStage := TProjectData(FProjectData).StageIndex; ExecuteSql(sdpPhase.Connection, Format(sDeleteSql, [iPhase, iStage])); ExecuteSql(sdpPhase.Connection, Format(sInsertSql, [iPhase, iStage])); ExecuteSql(sdpPhase.Connection, Format(sDeleteSql, [iPhase, -1])); ExecuteSql(sdpPhase.Connection, Format(sInsertSql, [iPhase, -1])); end; procedure TOtherMeasurePhaseData.sdvPhaseBeforeAddRecord( ARecord: TsdDataRecord; var Allow: Boolean); begin ARecord.ValueByName('ID').AsInteger := GetNewID; ARecord.ValueByName('SerialNo').AsInteger := GetNewSerialNo; ARecord.ValueByName('CreatePhaseID').AsInteger := TProjectData(FProjectData).PhaseIndex; end; procedure TOtherMeasurePhaseData.sdvPhaseAfterValueChanged( AValue: TsdValue); var Rec: TOMPhaseRecord; begin if SameText(AValue.FieldName, 'CurTotalPrice') then begin Rec := TOMPhaseRecord(AValue.Owner); Rec.SetFloatValue(Rec.EndTotalPrice, TotalPriceRoundTo(Rec.CurTotalPrice.AsFloat + Rec.PreTotalPrice.AsFloat)); end; end; procedure TOtherMeasurePhaseData.sddPhaseGetRecordClass( var ARecordClass: TsdRecordClass); begin ARecordClass := TOMPhaseRecord; end; procedure TOtherMeasurePhaseData.sddPhaseAfterValueChanged( AValue: TsdValue); var Rec: TOMPhaseRecord; begin if SameText(AValue.FieldName, 'CurTotalPrice') then begin Rec := TOMPhaseRecord(AValue.Owner); Rec.SetFloatValue(Rec.EndTotalPrice, TotalPriceRoundTo(Rec.CurTotalPrice.AsFloat + Rec.PreTotalPrice.AsFloat)); Rec.SetFloatValue(Rec.AddTotalPrice, Rec.EndTotalPrice.AsFloat); end; end; procedure TOtherMeasurePhaseData.sdvPhaseSetText(var Text: String; ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn; var Allow: Boolean); begin if SameText(AColumn.FieldName, 'Code') then begin if (Text = '') then begin if (ARecord.ValueByName('Name').AsString = '') then DataSetErrorMessage(Allow, '编号和名称不可同时为空。'); if (ARecord.ValueByName('Code').AsString = '') and (ARecord.ValueByName('Name').AsString = '') then sddPhase.Remove(ARecord); end; end else if SameText(AColumn.FieldName, 'Name') then begin if (Text = '') then begin if (ARecord.ValueByName('Code').AsString = '') then DataSetErrorMessage(Allow, '编号和名称不可同时为空。'); if(ARecord.ValueByName('Code').AsString = '') and (ARecord.ValueByName('Name').AsString = '') then sddPhase.Remove(ARecord); end; end else begin if (ARecord.ValueByName('Code').AsString = '') and (ARecord.ValueByName('Name').AsString = '') then begin DataSetErrorMessage(Allow, '编号、名称不可同时为空,请先填写编号或名称,再填写其他信息。'); sddPhase.Remove(AValue.Owner); end; end; end; end.