unit ZJJLDm; interface uses ZjGrid, SysUtils, Classes, DB, DBClient, ADODB, sdIDTree, sdDB, Provider, Windows; type TZJJLNode = class private FBillsID: Integer; FCode: string; FCertificateCode: string; FBillsCode: string; FFormulaMemo: string; FRelaFile: string; FType: Integer; end; TZJJLInfoRec = Record FBFXName: string; PegName: string; BGLCode: string; DrawingCode: string; UnitName: string; end; TZJJLData = class(TDataModule) atZJJL: TADOTable; dspZJJL: TDataSetProvider; cdsZJJL: TClientDataSet; cdsZJJLID: TIntegerField; cdsZJJLBillsID: TIntegerField; cdsZJJLCode: TWideStringField; cdsZJJLCertificateCode: TWideStringField; cdsZJJLBillsCode: TWideStringField; cdsZJJLFormulaMemo: TMemoField; cdsZJJLRelaFile: TWideStringField; cdsZJJLType: TIntegerField; cdsZJJLView: TClientDataSet; cdsZJJLViewID: TIntegerField; cdsZJJLViewBillsID: TIntegerField; cdsZJJLViewCode: TWideStringField; cdsZJJLViewCertificateCode: TWideStringField; cdsZJJLViewBillsCode: TWideStringField; cdsZJJLViewFormulaMemo: TMemoField; cdsZJJLViewRelaFile: TWideStringField; cdsZJJLViewType: TIntegerField; procedure cdsZJJLViewAfterScroll(DataSet: TDataSet); private FPhaseData: TObject; FCanModified: Boolean; FNewID: Integer; FOrgDataList: TList; FDetailGrid: TZJGrid; 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); procedure GenerateLeafNode(ANode: TsdIDTreeNode); procedure GenerateNodeByB_Code(ANode: TsdIDTreeNode); procedure DeleteAll; procedure RestoreOrgData; procedure DetailGridCellCanEdit(Sender: TObject; const ACoord: TPoint; var Allow: Boolean); procedure DetailGridCellTextChanged(Sender: TObject; Col, Row: Integer); function GetMainBillsTree: TsdIDTree; public constructor Create(APhaseData: TObject); destructor Destroy; override; procedure Open(AConnection: TADOConnection); procedure Save; procedure GenerateAll; procedure GenerateAllByB_Code; procedure AssignedCurData; function GetInfoRecByCode(ABillsID: Integer): TZJJLInfoRec; function GetInfoRecByB_Code(ABillsID: Integer): TZJJLInfoRec; function GetInfoRec(ABillsID, AType: Integer): TZJJLInfoRec; procedure LocateBills; property PhaseData: TObject read FPhaseData; property MainBillsTree: TsdIDTree read GetMainBillsTree; property CanModified: Boolean read FCanModified write FCanModified; property DetailGrid: TZJGrid read FDetailGrid; end; implementation uses PhaseData, ProjectData, BillsDm, UtilMethods, ProjectProperty, ZhAPI, BillsCompileDm, BillsMeasureDm; {$R *.dfm} { TZJJLData } constructor TZJJLData.Create(APhaseData: TObject); begin inherited Create(nil); FPhaseData := APhaseData; FOrgDataList := TList.Create; FDetailGrid := TZJGrid.Create(nil); FDetailGrid.Options := FDetailGrid.Options + [goWarpText]; FDetailGrid.OnCellCanEdit := DetailGridCellCanEdit; FDetailGrid.OnCellTextChanged := DetailGridCellTextChanged; end; destructor TZJJLData.Destroy; begin FDetailGrid.Free; 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 atZJJL.Connection := AConnection; cdsZJJL.Open; cdsZJJL.IndexFieldNames := 'ID'; cdsZJJLView.CloneCursor(cdsZJJL, True); cdsZJJLView.IndexFieldNames := 'ID'; end; procedure TZJJLData.Save; begin cdsZJJL.ApplyUpdates(0); 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; var iRowIndex: Integer; InfoRec: TZJJLInfoRec; begin FDetailGrid.OnCellTextChanged := nil; FDetailGrid.FixedRowCount := 0; FDetailGrid.FixedColCount := 0; FDetailGrid.ColCount := 1; FDetailGrid.RowCount := 9; FDetailGrid.DefaultColWidth := 300; for iRowIndex := 0 to FDetailGrid.RowCount - 1 do FDetailGrid[0, iRowIndex].Align := gaTopLeft; InfoRec := GetInfoRec(cdsZJJLViewBillsID.AsInteger, cdsZJJLViewType.AsInteger); FDetailGrid.Cells[0, 0].Text := '变更令号:' + InfoRec.BGLCode; FDetailGrid.Cells[0, 1].Text := '桩号或部位:' + InfoRec.PegName; FDetailGrid.Cells[0, 2].Text := '分部分项工程:' + InfoRec.FBFXName; FDetailGrid.Cells[0, 3].Text := '计量单元:' + InfoRec.UnitName; FDetailGrid.Cells[0, 4].Text := '图号:' + InfoRec.DrawingCode; FDetailGrid.Cells[0, 5].Text := '计算式说明:'; FDetailGrid.Cells[0, 6].Text := cdsZJJLViewFormulaMemo.AsString; FDetailGrid.Cells[0, 6].Align := gaTopLeft; FDetailGrid.RowHeights[6] := 57; FDetailGrid.Cells[0, 7].Text := '计算草图几何尺寸:'; FDetailGrid.Cells[0, 8].Text := cdsZJJLViewRelaFile.AsString; FDetailGrid.Cells[0, 8].Align := gaTopLeft; FDetailGrid.RowHeights[8] := 57; FDetailGrid.OnCellTextChanged := DetailGridCellTextChanged; end; procedure TZJJLData.GenerateAll; begin RestoreOrgData; FNewID := 1; DeleteAll; GenerateNode(MainBillsTree.FirstNode); 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 cdsZJJL.First; while not cdsZJJL.Eof do cdsZJJL.Delete; end; procedure TZJJLData.RestoreOrgData; function CreateNodeData: TZJJLNode; begin Result := TZJJLNode.Create; Result.FBillsID := cdsZJJLBillsID.AsInteger; Result.FCode := cdsZJJLCode.AsString; Result.FCertificateCode := cdsZJJLCertificateCode.AsString; Result.FBillsCode := cdsZJJLBillsCode.AsString; Result.FFormulaMemo := cdsZJJLFormulaMemo.AsString; Result.FRelaFile := cdsZJJLRelaFile.AsString; Result.FType := cdsZJJLType.AsInteger; end; begin FOrgDataList.Clear; cdsZJJL.First; while not cdsZJJL.Eof do begin FOrgDataList.Add(CreateNodeData); cdsZJJL.Next; 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.cdsZJJLViewAfterScroll(DataSet: TDataSet); begin AssignedCurData; 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; function GetBGLCode(ANode: TsdIDTreeNode): string; begin with TProjectData(TPhaseData(FPhaseData).ProjectData) do Result := BillsMeasureData.GatherRelaBGL(ANode); end; function GetPegName(APegNode: TsdIDTreeNode): string; begin if Assigned(APegNode) then Result := APegNode.Rec.ValueByName('Name').AsString else Result := ''; 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; // 取树结构的第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 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 GetFieldStrDef(ANode: TsdIDTreeNode; const AFieldName, ADef: string): string; begin if Assigned(ANode) then Result := ANode.Rec.ValueByName(AFieldName).AsString else Result := ''; end; var vPeg, vNode: TsdIDTreeNode; begin vNode := MainBillsTree.FindNode(ABillsID); vPeg := GetPegNode(vNode); Result.BGLCode := GetBGLCode(vNode); Result.PegName := GetPegName(vPeg); Result.FBFXName := GetFBFXName(vNode, vPeg); Result.UnitName := GetFieldStrDef(vNode, 'Name', ''); Result.DrawingCode := GetFieldStrDef(vNode, 'DrawingCode', ''); end; procedure TZJJLData.DetailGridCellTextChanged(Sender: TObject; Col, Row: Integer); begin if (Row = 6) then begin cdsZJJLView.Edit; cdsZJJLViewFormulaMemo.AsString := TZJGrid(Sender).Cells[Col, Row].Text; cdsZJJLView.Post; end else if (Row = 8) then begin cdsZJJLView.Edit; cdsZJJLViewRelaFile.AsString := TZJGrid(Sender).Cells[Col, Row].Text; cdsZJJLView.Post; end; end; procedure TZJJLData.GenerateAllByB_Code; begin RestoreOrgData; FNewID := 1; DeleteAll; GenerateNodeByB_Code(MainBillsTree.FirstNode); 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); function CheckMeasureExist(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; begin if (ANode.Rec.ValueByName('B_Code').AsString <> '') and CheckMeasureExist(ANode.ID) then GenerateZJJLNode(ANode, 1); end; procedure TZJJLData.GenerateZJJLNode(ANode: TsdIDTreeNode; AType: Integer); function GetNewCode: 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, FNewID]); end; end; 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; var ZJJLNode: TZJJLNode; begin cdsZJJL.Append; cdsZJJLID.AsInteger := FNewID; cdsZJJLBillsID.AsInteger := ANode.ID; cdsZJJLType.AsInteger := AType; ZJJLNode := GetOrgZJJLNode(ANode.ID); if not Assigned(ZJJLNode) then begin cdsZJJLCode.AsString := GetNewCode; cdsZJJLBillsCode.AsString := ANode.Rec.ValueByName('Code').AsString; end else begin cdsZJJLCode.AsString := ZJJLNode.FCode; cdsZJJLCertificateCode.AsString := ZJJLNode.FCertificateCode; cdsZJJLBillsCode.AsString := ZJJLNode.FBillsCode; cdsZJJLFormulaMemo.AsString := ZJJLNode.FFormulaMemo; cdsZJJLRelaFile.AsString := ZJJLNode.FRelaFile; end; cdsZJJL.Post; Inc(FNewID); end; function TZJJLData.GetInfoRecByB_Code(ABillsID: Integer): TZJJLInfoRec; function GetBGLCode(ANode: TsdIDTreeNode): string; begin with TProjectData(TPhaseData(FPhaseData).ProjectData) do Result := BillsMeasureData.GatherRelaBGL(ANode); end; 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 := ''; Result.DrawingCode := vNode.Rec.ValueByName('DrawingCode').AsString; 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', cdsZJJLViewBillsID.AsInteger); BillsMeasureData.sdvBillsMeasure.LocateInControl(Rec); end; end; end.