unit ZJJLDm; interface uses ZjGrid, MeasureGatherZJJL, SysUtils, Classes, DB, DBClient, ADODB, sdIDTree, sdDB, Provider, Windows, BillsTree, sdProvider, Variants; type TZJJLType = (ztFx, ztGcl, ztGclGather); TRefreshDetailGridEvent = procedure of Object; TZJJLNode = class private FBillsID: Integer; FCode: string; FCertificateCode: string; FBillsCode: string; FFormulaMemo: string; FRelaFile: string; FType: Integer; end; TZJJLInfoRec = Record FBFXName: string; PegName: string; BeginPeg: string; EndPeg: string; BGLCode: string; DrawingCode: string; UnitName: string; end; TZJJLData = class(TDataModule) sdpZJJL: TsdADOProvider; sddZJJL: TsdDataSet; sdvZJJL: TsdDataView; sdpHistory: TsdADOProvider; sddHistory: TsdDataSet; sdpZJJLDetail: TsdADOProvider; sddZJJLDetail: TsdDataSet; procedure sdvZJJLBeforeValueChange(AValue: TsdValue; const NewValue: Variant; var Allow: Boolean); procedure sdvZJJLAfterDeleteRecord(ARecord: TsdDataRecord); procedure sdvZJJLCurrentChanged(ARecord: TsdDataRecord); private FPhaseData: TObject; FCanModified: Boolean; FNewID: Integer; FOrgDataList: TList; FRefreshDetailGrid: TRefreshDetailGridEvent; function GetNewCode(ANewID: Integer): string; procedure GenerateZJJLNode(ANode: TsdIDTreeNode; AType: Integer); function CheckLastXmj(AID: Integer): Boolean; function CheckBGExist(ANode: TsdIDTreeNode): Boolean; function CheckMeasureExist(ANode: TsdIDTreeNode): Boolean; procedure GenerateLastXmj(ANode: TsdIDTreeNode); procedure GenerateNode(ANode: TsdIDTreeNode); function CheckLeafNodeMeasureExist(AID: Integer): Boolean; procedure GenerateLeafNode(ANode: TsdIDTreeNode); procedure GenerateNodeByB_Code(ANode: TsdIDTreeNode); procedure DeleteAll; procedure RestoreOrgData; procedure DeleteHistory(ABillsID, AType: Integer); procedure DeleteGatherHistory(ARecord: TsdDataRecord); procedure DetailGridCellCanEdit(Sender: TObject; const ACoord: TPoint; var Allow: Boolean); procedure DetailGridCellTextChanged(Sender: TObject; Col, Row: Integer); function GetFieldStrDef(ANode: TsdIDTreeNode; const AFieldName, ADef: string): string; function GetPegNode(ANode: TsdIDTreeNode): TsdIDTreeNode; function GetBGLCode(ANode: TsdIDTreeNode): string; // 取树结构的第ALevel层节点的名称(level从0开始) function GetNameByLevel(ANode: TsdIDTreeNode; ALevel: Integer): string; function GetFBFXName(ANode, APegNode: TsdIDTreeNode): string; function GetPegName(ANode: TsdIDTreeNode): string; function GetInfoRecByCode_2(ABillsID: Integer): TZJJLInfoRec; function GetInfoRecByB_Code_2(ABillsID: Integer): TZJJLInfoRec; function GetInfoRec_2(ABillsID, AType: Integer): TZJJLInfoRec; function GetNewHistoryID: Integer; procedure SetHistory(const AFieldName, AValue: string; AZJJL_Rec: TsdDataRecord); // 向父项检测,直至提取到图册号为止 function GetDrawingCode(ANode: TsdIDTreeNode): string; procedure CheckZjjlVerison; function GetMainBillsTree: TsdIDTree; public constructor Create(APhaseData: TObject); destructor Destroy; override; procedure Open(AConnection: TADOConnection); procedure Save; procedure GenerateAll; procedure GenerateAllByB_Code; procedure GenerateAllByB_CodeGather; procedure AssignedCurData(ARec: TsdDataRecord; ADetailGrid: TZJGrid); function GetInfoRecByCode(ABillsID: Integer): TZJJLInfoRec; function GetInfoRecByB_Code(ABillsID: Integer): TZJJLInfoRec; function GetInfoRec(ABillsID, AType: Integer): TZJJLInfoRec; function GetZJJLCalcData(ARec: TsdDataRecord; const AFileName: string): Double; procedure LocateBills; function FindZJJLRecord(ABillsID: Integer): TsdDataRecord; property PhaseData: TObject read FPhaseData; property MainBillsTree: TsdIDTree read GetMainBillsTree; property CanModified: Boolean read FCanModified write FCanModified; property RefreshDetailGrid: TRefreshDetailGridEvent read FRefreshDetailGrid write FRefreshDetailGrid; end; implementation uses PhaseData, ProjectData, BillsDm, UtilMethods, ProjectProperty, ZhAPI, BillsCompileDm, BillsMeasureDm, mPegFilter, Math; {$R *.dfm} { TZJJLData } constructor TZJJLData.Create(APhaseData: TObject); begin inherited Create(nil); FPhaseData := APhaseData; FOrgDataList := TList.Create; end; destructor TZJJLData.Destroy; begin ClearObjects(FOrgDataList); FOrgDataList.Free; inherited; end; function TZJJLData.GetMainBillsTree: TsdIDTree; begin with TProjectData(TPhaseData(FPhaseData).ProjectData) do Result := BillsMeasureData.BillsMeasureTree; end; procedure TZJJLData.Open(AConnection: TADOConnection); begin sdpZJJL.Connection := AConnection; sddZJJL.Open; sddZJJL.AddIndex('idxID', 'ID'); sddZJJL.AddIndex('idxBillsID', 'BillsID'); sdvZJJL.Open; sdpHistory.Connection := AConnection; sddHistory.Open; sddHistory.AddIndex('idxID', 'ID'); sddHistory.AddIndex('idxHistory', 'BillsID;Type;FieldName'); sddHistory.AddIndex('idxGatherHistory', 'BillsID;Type;B_Code;Name;Units;Price;FieldName'); sdpZJJLDetail.Connection := AConnection; sddZJJLDetail.Open; sddZJJLDetail.AddIndex('idxID', 'ID'); CheckZjjlVerison; end; procedure TZJJLData.Save; begin sddZJJL.Save; sddHistory.Save; sddZJJLDetail.Save; end; function TZJJLData.CheckLastXmj(AID: Integer): Boolean; var stnNode, stnChild: TsdIDTreeNode; begin stnNode := MainBillsTree.FindNode(AID); Result := stnNode.Rec.ValueByName('Code').AsString <> ''; if not stnNode.HasChildren or not Result then Exit; stnChild := stnNode.FirstChild; Result := stnChild.Rec.ValueByName('B_Code').AsString <> ''; end; procedure TZJJLData.AssignedCurData(ARec: TsdDataRecord; ADetailGrid: TZJGrid); var iRowIndex: Integer; begin ADetailGrid.OnCellTextChanged := nil; ADetailGrid.FixedRowCount := 0; ADetailGrid.FixedColCount := 0; ADetailGrid.ColCount := 1; ADetailGrid.RowCount := 11; ADetailGrid.DefaultColWidth := 300; for iRowIndex := 0 to ADetailGrid.RowCount - 1 do ADetailGrid[0, iRowIndex].Align := gaTopLeft; if not Assigned(ARec) then Exit; ADetailGrid.Cells[0, 0].Text := '变更令号:' + ARec.ValueByName('BGLCode').AsString; ADetailGrid.Cells[0, 1].Text := '部位:' + ARec.ValueByName('PegName').AsString; ADetailGrid.Cells[0, 2].Text := '起始桩号:' + ARec.ValueByName('BeginPeg').AsString; ADetailGrid.Cells[0, 3].Text := '终止桩号:' + ARec.ValueByName('EndPeg').AsString; ADetailGrid.Cells[0, 4].Text := '分部分项工程:' + ARec.ValueByName('FBFXName').AsString; ADetailGrid.Cells[0, 5].Text := '计量单元:' + ARec.ValueByName('UnitName').AsString; ADetailGrid.Cells[0, 6].Text := '图号:' + ARec.ValueByName('DrawingCode').AsString; ADetailGrid.Cells[0, 7].Text := '计算式说明:'; ADetailGrid.Cells[0, 8].Text := ARec.ValueByName('FormulaMemo').AsString; ADetailGrid.Cells[0, 8].Align := gaTopLeft; ADetailGrid.RowHeights[8] := 57; ADetailGrid.Cells[0, 9].Text := '计算草图几何尺寸:'; ADetailGrid.Cells[0, 10].Text := ARec.ValueByName('RelaFile').AsString; ADetailGrid.Cells[0, 10].Align := gaTopLeft; ADetailGrid.RowHeights[10] := 57; ADetailGrid.OnCellTextChanged := DetailGridCellTextChanged; end; procedure TZJJLData.GenerateAll; begin RestoreOrgData; FNewID := 1; DeleteAll; GenerateNode(MainBillsTree.FirstNode); TPhaseData(FPhaseData).PhaseProperty.ZjjlVersion := 1; end; procedure TZJJLData.GenerateNode(ANode: TsdIDTreeNode); begin if not Assigned(ANode) then Exit; if CheckLastXmj(ANode.ID) then GenerateLastXmj(ANode) else GenerateNode(ANode.FirstChild); GenerateNode(ANode.NextSibling); end; procedure TZJJLData.GenerateLastXmj(ANode: TsdIDTreeNode); begin if CheckMeasureExist(ANode) then GenerateZJJLNode(ANode, 0); end; function TZJJLData.CheckBGExist(ANode: TsdIDTreeNode): Boolean; function CheckBGLExist(AID: Integer): Boolean; var StageRec: TsdDataRecord; begin StageRec := TPhaseData(FPhaseData).StageData.StageRecord(AID); Result := Assigned(StageRec) and ((StageRec.ValueByName('QcBGLCode').AsString <> '') or (StageRec.ValueByName('PcBGLCode').AsString <> '')); end; var iChild: Integer; begin Result := False; if not Assigned(ANode) then Exit; if ANode.HasChildren then begin for iChild := 0 to ANode.ChildCount - 1 do begin Result := Result or CheckBGExist(ANode.ChildNodes[iChild]); if Result then Break; end; end else Result := CheckBGLExist(ANode.ID); end; procedure TZJJLData.DeleteAll; begin sddZJJL.DeleteAll; sddZJJLDetail.DeleteAll; end; procedure TZJJLData.RestoreOrgData; function CreateNodeData(ARec: TsdDataRecord): TZJJLNode; begin Result := TZJJLNode.Create; Result.FBillsID := ARec.ValueByName('BillsID').AsInteger; Result.FCode := ARec.ValueByName('Code').AsString; Result.FCertificateCode := ARec.ValueByName('CertificateCode').AsString; Result.FBillsCode := ARec.ValueByName('BillsCode').AsString; Result.FFormulaMemo := ARec.ValueByName('FormulaMemo').AsString; Result.FRelaFile := ARec.ValueByName('RelaFile').AsString; Result.FType := ARec.ValueByName('Type').AsInteger; end; var i: Integer; vRec: TsdDataRecord; begin FOrgDataList.Clear; for i := 0 to sddZJJL.RecordCount - 1 do begin vRec := sddZJJL.Records[i]; FOrgDataList.Add(CreateNodeData(vRec)); end; end; function TZJJLData.CheckMeasureExist(ANode: TsdIDTreeNode): Boolean; function CheckStageCompleteData(AID: Integer): Boolean; var StageRec: TsdDataRecord; begin StageRec := TPhaseData(FPhaseData).StageData.StageRecord(AID); Result := Assigned(StageRec) and ((StageRec.ValueByName('GatherQuantity').AsFloat <> 0) or (StageRec.ValueByName('GatherTotalPrice').AsFloat <> 0)); end; var iChild: Integer; begin Result := False; if not Assigned(ANode) then Exit; if ANode.HasChildren then begin for iChild := 0 to ANode.ChildCount - 1 do begin Result := Result or CheckMeasureExist(ANode.ChildNodes[iChild]); if Result then Break; end; end else Result := CheckStageCompleteData(ANode.ID); end; procedure TZJJLData.DetailGridCellCanEdit(Sender: TObject; const ACoord: TPoint; var Allow: Boolean); begin Allow := ((ACoord.Y = 6) or (ACoord.Y = 8)) and not TPhaseData(FPhaseData).StageDataReadOnly; end; function TZJJLData.GetInfoRecByCode(ABillsID: Integer): TZJJLInfoRec; var vPeg, vNode: TsdIDTreeNode; begin vNode := MainBillsTree.FindNode(ABillsID); vPeg := GetPegNode(vNode); Result.BGLCode := GetBGLCode(vNode); Result.PegName := GetFieldStrDef(vPeg, 'Name', ''); Result.FBFXName := GetFBFXName(vNode, vPeg); Result.UnitName := GetFieldStrDef(vNode, 'Name', ''); Result.DrawingCode := GetDrawingCode(vNode); end; procedure TZJJLData.DetailGridCellTextChanged(Sender: TObject; Col, Row: Integer); var Rec: TsdDataRecord; begin Rec := sdvZJJL.Current; if not Assigned(Rec) then Exit; if (Row = 8) then Rec.ValueByName('FormulaMemo').AsString := TZJGrid(Sender).Cells[Col, Row].Text else if (Row = 10) then Rec.ValueByName('RelaFile').AsString := TZJGrid(Sender).Cells[Col, Row].Text; end; procedure TZJJLData.GenerateAllByB_Code; begin RestoreOrgData; FNewID := 1; DeleteAll; GenerateNodeByB_Code(MainBillsTree.FirstNode); TPhaseData(FPhaseData).PhaseProperty.ZjjlVersion := 1; end; procedure TZJJLData.GenerateNodeByB_Code(ANode: TsdIDTreeNode); begin if not Assigned(ANode) then Exit; if ANode.HasChildren then GenerateNodeByB_Code(ANode.FirstChild) else GenerateLeafNode(ANode); GenerateNodeByB_Code(ANode.NextSibling); end; procedure TZJJLData.GenerateLeafNode(ANode: TsdIDTreeNode); begin if (ANode.Rec.ValueByName('B_Code').AsString <> '') and CheckLeafNodeMeasureExist(ANode.ID) then GenerateZJJLNode(ANode, 1); end; procedure TZJJLData.GenerateZJJLNode(ANode: TsdIDTreeNode; AType: Integer); function GetOrgZJJLNode(ABillsID: Integer): TZJJLNode; var iIndex: Integer; begin Result := nil; for iIndex := 0 to FOrgDataList.Count - 1 do // 7/30新增了一个“总量控制”模式,Type字段控制。真的是要疯掉了。 if (TZJJLNode(FOrgDataList.Items[iIndex]).FBillsID = ABillsID) and (TZJJLNode(FOrgDataList.Items[iIndex]).FType = AType) then begin Result := TZJJLNode(FOrgDataList.Items[iIndex]); Break; end; end; function GetFieldValue(const AFieldName, ADefaultValue: string): string; var HistoryRec: TsdDataRecord; begin HistoryRec := sddHistory.FindKey('idxHistory', VarArrayOf([ANode.ID, AType, AFieldName])); if Assigned(HistoryRec) then Result := HistoryRec.ValueByName('FieldValue').AsString else Result := ADefaultValue; end; var ZJJLNode: TZJJLNode; vInfoRec: TZJJLInfoRec; Rec: TsdDataRecord; begin Rec := sddZJJL.Add; Rec.ValueByName('ID').AsInteger := FNewID; Rec.ValueByName('BillsID').AsInteger := ANode.ID; Rec.ValueByName('Type').AsInteger := AType; if AType = Ord(ztFx) then Rec.ValueByName('BillsCode').AsString := ANode.Rec.ValueByName('Code').AsString else if AType = Ord(ztGcl) then Rec.ValueByName('BillsCode').AsString := ANode.Rec.ValueByName('B_Code').AsString; Rec.ValueByName('Code').AsString := GetFieldValue('Code', GetNewCode(FNewID)); Rec.ValueByName('CertificateCode').AsString := GetFieldValue('CertificateCode', ''); Rec.ValueByName('FormulaMemo').AsString := GetFieldValue('FormulaMemo', ''); Rec.ValueByName('RelaFile').AsString := GetFieldValue('RelaFile', ''); vInfoRec := GetInfoRec_2(ANode.ID, AType); Rec.ValueByName('BGLCode').AsString := GetFieldValue('BGLCode', vInfoRec.BGLCode); Rec.ValueByName('PegName').AsString := GetFieldValue('PegName', vInfoRec.PegName); Rec.ValueByName('BeginPeg').AsString := GetFieldValue('BeginPeg', vInfoRec.BeginPeg); Rec.ValueByName('EndPeg').AsString := GetFieldValue('EndPeg', vInfoRec.EndPeg); Rec.ValueByName('FBFXName').AsString := GetFieldValue('FBFXName', vInfoRec.FBFXName); Rec.ValueByName('UnitName').AsString := GetFieldValue('UnitName', vInfoRec.UnitName); Rec.ValueByName('DrawingCode').AsString := GetFieldValue('DrawingCode', vInfoRec.DrawingCode); Rec := sddZJJLDetail.Add; Rec.ValueByName('ID').AsInteger := FNewID; Rec.ValueByName('BillsID').AsInteger := ANode.ID; Inc(FNewID); end; function TZJJLData.GetInfoRecByB_Code(ABillsID: Integer): TZJJLInfoRec; var vNode: TsdIDTreeNode; begin vNode := MainBillsTree.FindNode(ABillsID); Result.BGLCode := GetBGLCode(vNode); if Assigned(vNode.Parent) then Result.PegName := vNode.Parent.Rec.ValueByName('Name').AsString; Result.FBFXName := ''; Result.UnitName := vNode.Rec.ValueByName('Name').AsString; Result.DrawingCode := GetDrawingCode(vNode); end; function TZJJLData.GetInfoRec(ABillsID, AType: Integer): TZJJLInfoRec; begin if AType = 0 then Result := GetInfoRecByCode(ABillsID) else if AType = 1 then Result := GetInfoRecByB_Code(ABillsID); end; procedure TZJJLData.LocateBills; var Rec: TsdDataRecord; begin with TProjectData(TPhaseData(FPhaseData).ProjectData) do begin Rec := BillsData.sddBills.FindKey('idxID', sdvZJJL.Current.ValueByName('BillsID').AsInteger); BillsMeasureData.sdvBillsMeasure.LocateInControl(Rec); end; end; function TZJJLData.GetDrawingCode(ANode: TsdIDTreeNode): string; var vNode: TBillsIDTreeNode; begin Result := ''; vNode := TBillsIDTreeNode(ANode); while (Result = '') and Assigned(vNode) do begin if Assigned(vNode.Rec) then Result := vNode.Rec.DrawingCode.AsString; vNode := TBillsIDTreeNode(vNode.Parent); end; end; procedure TZJJLData.CheckZjjlVerison; procedure LoadVersion0Info; var i: Integer; Rec: TsdDataRecord; ZJJLInfoRec: TZJJLInfoRec; begin for i := 0 to sddZJJL.RecordCount - 1 do begin Rec := sddZJJL.Records[i]; ZJJLInfoRec := GetInfoRec(Rec.ValueByName('BillsID').AsInteger, Rec.ValueByName('Type').AsInteger); Rec.ValueByName('BGLCode').AsString := ZJJLInfoRec.BGLCode; Rec.ValueByName('PegName').AsString := ZJJLInfoRec.PegName; Rec.ValueByName('FBFXName').AsString := ZJJLInfoRec.FBFXName; Rec.ValueByName('UnitName').AsString := ZJJLInfoRec.UnitName; Rec.ValueByName('DrawingCode').AsString := ZJJLInfoRec.DrawingCode; end; end; procedure LoadVersion0History; var i, j, iNewID: Integer; Rec: TsdDataRecord; begin for i := 0 to sddZJJL.RecordCount - 1 do begin Rec := sddZJJL.Records[i]; if Rec.ValueByName('CertificateCode').AsString <> '' then SetHistory('CertificateCode', Rec.ValueByName('CertificateCode').AsString, Rec); if Rec.ValueByName('FormulaMemo').AsString <> '' then SetHistory('FormulaMemo', Rec.ValueByName('FormulaMemo').AsString, Rec); if Rec.ValueByName('RelaFile').AsString <> '' then SetHistory('RelaFile', Rec.ValueByName('RelaFile').AsString, Rec); end; end; begin if TPhaseData(PhaseData).PhaseProperty.ZjjlVersion = 0 then begin TPhaseData(PhaseData).PhaseProperty.ZJJLPreText := TProjectData(TPhaseData(PhaseData).ProjectData).ProjProperties.ZJJLPreText; LoadVersion0Info; LoadVersion0History; end; end; function TZJJLData.GetInfoRec_2(ABillsID, AType: Integer): TZJJLInfoRec; begin if AType = 0 then Result := GetInfoRecByCode_2(ABillsID) else if AType = 1 then Result := GetInfoRecByB_Code_2(ABillsID); end; function TZJJLData.GetInfoRecByB_Code_2(ABillsID: Integer): TZJJLInfoRec; var vNode: TsdIDTreeNode; sPeg: string; vPegFilter: TPegStrFilter; begin vNode := MainBillsTree.FindNode(ABillsID); sPeg := GetPegName(vNode); Result.BGLCode := GetBGLCode(vNode); if Assigned(vNode.Parent) then Result.PegName := vNode.Parent.Rec.ValueByName('Name').AsString; if sPeg <> '' then begin vPegFilter := TPegStrFilter.Create; vPegFilter.PegStr := sPeg; Result.BeginPeg := vPegFilter.BeginPeg; Result.EndPeg := vPegFilter.EndPeg; vPegFilter.Free; end; Result.UnitName := vNode.Rec.ValueByName('Name').AsString; Result.DrawingCode := GetDrawingCode(vNode); end; function TZJJLData.GetInfoRecByCode_2(ABillsID: Integer): TZJJLInfoRec; var vPeg, vNode: TsdIDTreeNode; vPegFilter: TPegStrFilter; begin vNode := MainBillsTree.FindNode(ABillsID); vPeg := GetPegNode(vNode); Result.BGLCode := GetBGLCode(vNode); Result.PegName := GetFieldStrDef(vPeg, 'Name', ''); if Result.PegName <> '' then begin vPegFilter := TPegStrFilter.Create; vPegFilter.PegStr := Result.PegName; Result.BeginPeg := vPegFilter.BeginPeg; Result.EndPeg := vPegFilter.EndPeg; vPegFilter.Free; end; Result.FBFXName := GetFBFXName(vNode, vPeg); Result.UnitName := GetFieldStrDef(vNode, 'Name', ''); Result.DrawingCode := GetDrawingCode(vNode); end; function TZJJLData.GetBGLCode(ANode: TsdIDTreeNode): string; begin with TProjectData(TPhaseData(FPhaseData).ProjectData) do Result := BillsMeasureData.GatherRelaBGL(ANode); end; function TZJJLData.GetPegName(ANode: TsdIDTreeNode): string; var vPeg: TsdIDTreeNode; begin vPeg := GetPegNode(ANode); Result := GetFieldStrDef(vPeg, 'Name', ''); end; function TZJJLData.GetFieldStrDef(ANode: TsdIDTreeNode; const AFieldName, ADef: string): string; begin if Assigned(ANode) then Result := ANode.Rec.ValueByName(AFieldName).AsString else Result := ''; end; function TZJJLData.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 TZJJLData.GetFBFXName(ANode, APegNode: TsdIDTreeNode): string; var vCurNode: TsdIDTreeNode; begin Result := ''; if not Assigned(ANode) then Exit; // 如果计量单元节点的名称为桩号(转化为判断计量单元节点与桩号节点为同一个) if not Assigned(APegNode) or (ANode.ID = APegNode.ID) then begin // 取树结构的第三、四层节点的名称 Result := GetNameByLevel(ANode, 2); if (Result <> '') and (GetNameByLevel(ANode, 3) <> '') then Result := Result + ','; Result := Result + GetNameByLevel(ANode, 3); end // 否则,合并[桩号节点的子节点]至[计量单元节点的父节点]的名称 else begin vCurNode := ANode.Parent; // 转化为判断层次,层次大于[桩号节点的子节点]的层次 while vCurNode.Level > APegNode.Level do begin Result := vCurNode.Rec.ValueByName('Name').AsString + ',' + Result; vCurNode := vCurNode.Parent; end; end; end; function TZJJLData.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; procedure TZJJLData.SetHistory(const AFieldName, AValue: string; AZJJL_Rec: TsdDataRecord); var HistoryRec: TsdDataRecord; begin if AZJJL_Rec.ValueByName('Type').AsInteger <> Integer(ztGclGather) then HistoryRec := sddHistory.FindKey('idxHistory', VarArrayOf([AZJJL_Rec.ValueByName('BillsID').AsInteger, AZJJL_Rec.ValueByName('Type').AsInteger, AFieldName])) else HistoryRec := sddHistory.FindKey('idxGatherHistory', VarArrayOf([AZJJL_Rec.ValueByName('GatherBillsID').AsInteger, AZJJL_Rec.ValueByName('Type').AsInteger, AZJJL_Rec.ValueByName('B_Code').AsString, AZJJL_Rec.ValueByName('Name').AsString, AZJJL_Rec.ValueByName('Units').AsString, AZJJL_Rec.ValueByName('Price').AsFloat, AFieldName])); if not Assigned(HistoryRec) then begin HistoryRec := sddHistory.Add; HistoryRec.ValueByName('ID').AsInteger := GetNewHistoryID; if AZJJL_Rec.ValueByName('Type').AsInteger <> Integer(ztGclGather) then HistoryRec.ValueByName('BillsID').AsInteger := AZJJL_Rec.ValueByName('BillsID').AsInteger else HistoryRec.ValueByName('BillsID').AsInteger := AZJJL_Rec.ValueByName('GatherBillsID').AsInteger; HistoryRec.ValueByName('Type').AsInteger := AZJJL_Rec.ValueByName('Type').AsInteger; HistoryRec.ValueByName('FieldName').AsString := AFieldName; HistoryRec.ValueByName('B_Code').AsString := AZJJL_Rec.ValueByName('B_Code').AsString; HistoryRec.ValueByName('Name').AsString := AZJJL_Rec.ValueByName('Name').AsString; HistoryRec.ValueByName('Units').AsString := AZJJL_Rec.ValueByName('Units').AsString; HistoryRec.ValueByName('Price').AsFloat := AZJJL_Rec.ValueByName('Price').AsFloat; end; HistoryRec.ValueByName('FieldValue').AsString := AValue; end; function TZJJLData.GetNewHistoryID: Integer; var idx: TsdIndex; begin idx := sddHistory.FindIndex('idxID'); if idx.RecordCount = 0 then Result := 1 else Result := idx.Records[idx.RecordCount - 1].ValueByName('ID').AsInteger + 1; end; procedure TZJJLData.sdvZJJLBeforeValueChange(AValue: TsdValue; const NewValue: Variant; var Allow: Boolean); function CheckFieldNeedHistory(const AFieldName: string): Boolean; begin Result := SameText(AFieldName, 'Code') or SameText(AFieldName, 'CertificateCode') or SameText(AFieldName, 'BGLCode') or SameText(AFieldName, 'PegName') or SameText(AFieldName, 'BeginPeg') or SameText(AFieldName, 'EndPeg') or SameText(AFieldName, 'FBFXName') or SameText(AFieldName, 'UnitName') or SameText(AFieldName, 'DrawingCode') or SameText(AFieldName, 'FormulaMemo') or SameText(AFieldName, 'RelaFile'); end; var sNewValue: string; begin if CheckFieldNeedHistory(AValue.FieldName) and not TPhaseData(FPhaseData).StageDataReadOnly then begin sNewValue := VarToStrDef(NewValue, ''); if sNewValue <> AValue.AsString then SetHistory(AValue.FieldName, sNewValue, AValue.Owner); end; end; procedure TZJJLData.sdvZJJLAfterDeleteRecord(ARecord: TsdDataRecord); begin if ARecord.ValueByName('Type').AsInteger <> Integer(ztGclGather) then DeleteHistory(ARecord.ValueByName('BillsID').AsInteger, ARecord.ValueByName('Type').AsInteger) else DeleteGatherHistory(ARecord); end; procedure TZJJLData.DeleteHistory(ABillsID, AType: Integer); var i: Integer; Rec: TsdDataRecord; begin i := 0; while (i < sddHistory.RecordCount) do begin Rec := sddHistory.Records[i]; if (ABillsID = Rec.ValueByName('BillsID').AsInteger) and (AType = Rec.ValueByName('Type').AsInteger) then sddHistory.Remove(Rec) else Inc(i); end; end; procedure TZJJLData.GenerateAllByB_CodeGather; procedure GenerateZJJLGather(AManager: TmgZJJLManager; ANode: TBillsIDTreeNode); var iChild: Integer; vChild: TBillsIDTreeNode; begin if ANode.HasChildren then begin iChild := 0; vChild := TBillsIDTreeNode(ANode.NextNode); while iChild < ANode.PosterityCount do begin if not vChild.HasChildren and CheckLeafNodeMeasureExist(vChild.ID) then AManager.AddZJJLAndDetail(vChild, ANode); vChild := TBillsIDTreeNode(vChild.NextNode); Inc(iChild); end; end else if CheckLeafNodeMeasureExist(ANode.ID) then AManager.AddZJJLAndDetail(ANode, ANode); end; procedure GenerateZJJLGatherByNode(AManager: TmgZJJLManager; ANode: TsdIDTreeNode); begin if not Assigned(ANode) then Exit; if ANode.HasChildren and not TBillsIDTreeNode(ANode).Rec.IsGatherZJJL.AsBoolean then GenerateZJJLGatherByNode(AManager, ANode.FirstChild) else GenerateZJJLGather(AManager, TBillsIDTreeNode(ANode)); GenerateZJJLGatherByNode(AManager, ANode.NextSibling); end; function GetFieldValue(AZJJL: TmgZJJL; const AFieldName, ADefaultValue: string): string; var HistoryRec: TsdDataRecord; begin HistoryRec := sddHistory.FindKey('idxGatherHistory', VarArrayOf([AZJJL.GatherNode.ID, Integer(ztGclGather), AZJJL.B_Code, AZJJL.Name, AZJJL.Units, AZJJL.Price, AFieldName])); if Assigned(HistoryRec) then Result := HistoryRec.ValueByName('FieldValue').AsString else Result := ADefaultValue; end; procedure SaveGatherData(AManager: TmgZJJLManager); var i, j: Integer; vZJJL: TmgZJJL; Rec: TsdDataRecord; begin for i := 0 to AManager.ZJJLCount - 1 do begin vZJJL := AManager.ZJJL[i]; Rec := sddZJJL.Add; Rec.ValueByName('ID').AsInteger := i + 1; Rec.ValueByName('BillsID').AsInteger := vZJJL.Detail[0].RelaNode.ID; Rec.ValueByName('Type').AsInteger := Integer(ztGclGather); Rec.ValueByName('GatherBillsID').AsInteger := vZJJL.GatherNode.ID; Rec.ValueByName('BillsCode').AsString := vZJJL.B_Code; Rec.ValueByName('B_Code').AsString := vZJJL.B_Code; Rec.ValueByName('Name').AsString := vZJJL.Name; Rec.ValueByName('Units').AsString := vZJJL.Units; Rec.ValueByName('Price').AsFloat := vZJJL.Price; Rec.ValueByName('Code').AsString := GetFieldValue(vZJJL, 'Code', GetNewCode(i+1)); Rec.ValueByName('CertificateCode').AsString := GetFieldValue(vZJJL, 'CertificateCode', ''); Rec.ValueByName('FormulaMemo').AsString := GetFieldValue(vZJJL, 'FormulaMemo', ''); Rec.ValueByName('RelaFile').AsString := GetFieldValue(vZJJL, 'RelaFile', ''); Rec.ValueByName('BGLCode').AsString := GetFieldValue(vZJJL, 'BGLCode', vZJJL.BGLCode); Rec.ValueByName('PegName').AsString := GetFieldValue(vZJJL, 'PegName', ''); Rec.ValueByName('BeginPeg').AsString := GetFieldValue(vZJJL, 'BeginPeg', vZJJL.BeginPeg); Rec.ValueByName('EndPeg').AsString := GetFieldValue(vZJJL, 'EndPeg', vZJJL.EndPeg); Rec.ValueByName('FBFXName').AsString := GetFieldValue(vZJJL, 'FBFXName', vZJJL.GatherNode.Rec.Name.AsString); Rec.ValueByName('UnitName').AsString := GetFieldValue(vZJJL, 'UnitName', ''); Rec.ValueByName('DrawingCode').AsString := GetFieldValue(vZJJL, 'DrawingCode', vZJJL.DrawingCode); for j := 0 to vZJJL.DetailCount - 1 do begin Rec := sddZJJLDetail.Add; Rec.ValueByName('ID').AsInteger := i + 1; Rec.ValueByName('BillsID').AsInteger := vZJJL.Detail[j].RelaNode.ID; end; end; end; var vManager: TmgZJJLManager; begin vManager := TmgZJJLManager.Create; try DeleteAll; GenerateZJJLGatherByNode(vManager, MainBillsTree.FirstNode); SaveGatherData(vManager); TPhaseData(FPhaseData).PhaseProperty.ZjjlVersion := Integer(ztGclGather); finally vManager.Free; end; end; function TZJJLData.CheckLeafNodeMeasureExist(AID: Integer): Boolean; var StageRec: TsdDataRecord; begin StageRec := TPhaseData(FPhaseData).StageData.StageRecord(AID); Result := Assigned(StageRec) and ((StageRec.ValueByName('GatherQuantity').AsFloat <> 0) or (StageRec.ValueByName('GatherTotalPrice').AsFloat <> 0)); end; function TZJJLData.GetNewCode(ANewID: Integer): string; begin with TProjectData(TPhaseData(FPhaseData).ProjectData) do begin Result := ProjProperties.ZJJLPreText; if (Result <> '') and (Result[Length(Result)] <> '-') then Result := Result + '-'; Result := Result + Format('%d-%d', [PhaseIndex, ANewID]); end; end; function TZJJLData.FindZJJLRecord(ABillsID: Integer): TsdDataRecord; var ADetailRec: TsdDataRecord; begin if sddZJJLDetail.RecordCount > 0 then begin ADetailRec := sddZJJLDetail.Locate('BillsID', ABillsID); if Assigned(ADetailRec) then Result := sddZJJL.FindKey('idxID', ADetailRec.ValueByName('ID').AsInteger) else Result := nil; end else Result := sddZJJL.Locate('BillsID', ABillsID); end; procedure TZJJLData.DeleteGatherHistory(ARecord: TsdDataRecord); var i: Integer; Rec: TsdDataRecord; begin i := 0; while (i < sddHistory.RecordCount) do begin Rec := sddHistory.Records[i]; if (ARecord.ValueByName('GatherBillsID').AsInteger = Rec.ValueByName('BillsID').AsInteger) and (ARecord.ValueByName('Type').AsInteger = Rec.ValueByName('Type').AsInteger) and (ARecord.ValueByName('B_Code').AsString = Rec.ValueByName('B_Code').AsString) and (ARecord.ValueByName('Name').AsString = Rec.ValueByName('Name').AsString) and (ARecord.ValueByName('Units').AsString = Rec.ValueByName('Units').AsString) and (Abs(ARecord.ValueByName('Price').AsFloat - Rec.ValueByName('Price').AsFloat) < 0.00001) then sddHistory.Remove(Rec) else Inc(i); end; end; procedure TZJJLData.sdvZJJLCurrentChanged(ARecord: TsdDataRecord); begin if Assigned(FRefreshDetailGrid) then FRefreshDetailGrid; end; function TZJJLData.GetZJJLCalcData(ARec: TsdDataRecord; const AFileName: string): Double; var vIdx: TsdIndex; iBegin, iEnd, i: Integer; vRec, vStageRec: TsdDataRecord; begin Result := 0; vIdx := sddZJJLDetail.FindIndex('idxID'); iBegin := vIdx.FindKeyIndex(ARec.ValueByName('ID').AsInteger); iEnd := vIdx.FindKeyLastIndex(ARec.ValueByName('ID').AsInteger); if iBegin <> -1 then begin for i := iBegin to iEnd do begin vRec := vIdx.Records[i]; vStageRec := TPhaseData(FPhaseData).StageData.StageRecord(vRec.ValueByName('BillsID').AsInteger); if Assigned(vStageRec) then Result := QuantityRoundTo(Result + vStageRec.ValueByName(AFileName).AsFloat); end; end; end; end.