unit ZJJLDm; interface uses ZjGrid, SysUtils, Classes, DB, DBClient, ADODB, sdIDTree, sdDB, Provider, Windows, BillsTree, sdProvider, Variants; type TZJJLType = (ztFx, ztGcl); 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; procedure sdvZJJLBeforeValueChange(AValue: TsdValue; const NewValue: Variant; var Allow: Boolean); procedure sdvZJJLAfterDeleteRecord(ARecord: TsdDataRecord); private FPhaseData: TObject; FCanModified: Boolean; FNewID: Integer; FOrgDataList: TList; 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 DeleteHistory(ABillsID, AType: Integer); 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 AssignedCurData(ARec: TsdDataRecord; ADetailGrid: TZJGrid); 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; end; implementation uses PhaseData, ProjectData, BillsDm, UtilMethods, ProjectProperty, ZhAPI, BillsCompileDm, BillsMeasureDm, mPegFilter; {$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'); CheckZjjlVerison; end; procedure TZJJLData.Save; begin sddZJJL.Save; sddHistory.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; 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); 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; 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); 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); 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]; SetHistory('CertificateCode', Rec.ValueByName('CertificateCode').AsString, Rec); SetHistory('FormulaMemo', Rec.ValueByName('FormulaMemo').AsString, Rec); 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 HistoryRec := sddHistory.FindKey('idxHistory', VarArrayOf([AZJJL_Rec.ValueByName('BillsID').AsInteger, AZJJL_Rec.ValueByName('Type').AsInteger, AFieldName])); if not Assigned(HistoryRec) then begin HistoryRec := sddHistory.Add; HistoryRec.ValueByName('ID').AsInteger := GetNewHistoryID; HistoryRec.ValueByName('BillsID').AsInteger := AZJJL_Rec.ValueByName('BillsID').AsInteger; HistoryRec.ValueByName('Type').AsInteger := AZJJL_Rec.ValueByName('Type').AsInteger; HistoryRec.ValueByName('FieldName').AsString := AFieldName; 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) then begin sNewValue := VarToStrDef(NewValue, ''); if sNewValue <> AValue.AsString then SetHistory(AValue.FieldName, sNewValue, AValue.Owner); end; end; procedure TZJJLData.sdvZJJLAfterDeleteRecord(ARecord: TsdDataRecord); begin DeleteHistory(ARecord.ValueByName('BillsID').AsInteger, ARecord.ValueByName('Type').AsInteger); 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; end.