Explorar o código

Task #1557.2 ZJJL, Filter BeginPeg & EndPeg, remember all modified Value, keep modified Value when Generate ZJJL again

MaiXinRong %!s(int64=8) %!d(string=hai) anos
pai
achega
eb8d822d7e

+ 7 - 2
DataModules/ReportMemoryDm/rmHaBaiCustomizedDm.pas

@@ -918,6 +918,8 @@ end;
 procedure TrmHaBaiCustomizedData.WriteFlowData;
 
   procedure AddNodeData(ANode: TMeasureBillsIDTreeNode);
+  var
+    vRec: TsdDataRecord;
   begin
     cdsCustom14.Append;
     cdsCustom14IndexCode.AsString := ANode.Rec.IndexCode.AsString;
@@ -928,8 +930,11 @@ procedure TrmHaBaiCustomizedData.WriteFlowData;
     cdsCustom14Quantity.AsFloat := ANode.StageRec.GatherQuantity.AsFloat;
     cdsCustom14TotalPrice.AsFloat := ANode.StageRec.GatherTotalPrice.AsFloat;
     with FProjectData.PhaseData.ZJJLData do
-      if cdsZJJL.Locate('BillsID', ANode.ID, []) then
-        cdsCustom14CertificateCode.AsString := cdsZJJLCertificateCode.AsString;
+    begin
+      vRec := sddZJJL.FindKey('idxBillsID', ANode.ID);
+      if Assigned(vRec) then
+        cdsCustom14CertificateCode.AsString := vRec.ValueByName('CertificateCode').AsString;
+    end;
     cdsCustom14.Post;
   end;
 

+ 126 - 139
DataModules/ZJJLDm.dfm

@@ -1,150 +1,137 @@
 object ZJJLData: TZJJLData
   OldCreateOrder = False
-  Left = 691
-  Top = 246
+  Left = 704
+  Top = 204
   Height = 241
-  Width = 166
-  object atZJJL: TADOTable
+  Width = 269
+  object sdpZJJL: TsdADOProvider
     TableName = 'ZJJL'
-    Left = 33
-    Top = 17
+    Left = 42
+    Top = 16
   end
-  object dspZJJL: TDataSetProvider
-    DataSet = atZJJL
-    UpdateMode = upWhereKeyOnly
-    Left = 33
+  object sddZJJL: TsdDataSet
+    Active = False
+    Provider = sdpZJJL
+    Left = 40
     Top = 80
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D650909507265636973696F6E02000453697A6502000001044E616D
+      65060742696C6C734944094669656C644E616D65060742696C6C734944084461
+      7461547970650203084461746153697A6502040549734B6579080F4E65656450
+      726F636573734E616D650909507265636973696F6E02000453697A6502000001
+      044E616D650604436F6465094669656C644E616D650604436F64650844617461
+      547970650218084461746153697A6502320549734B6579080F4E65656450726F
+      636573734E616D650909507265636973696F6E02000453697A6502000001044E
+      616D65060F4365727469666963617465436F6465094669656C644E616D65060F
+      4365727469666963617465436F64650844617461547970650218084461746153
+      697A6502320549734B6579080F4E65656450726F636573734E616D6509095072
+      65636973696F6E02000453697A6502000001044E616D65060942696C6C73436F
+      6465094669656C644E616D65060942696C6C73436F6465084461746154797065
+      0218084461746153697A6502320549734B6579080F4E65656450726F63657373
+      4E616D650909507265636973696F6E02000453697A6502000001044E616D6506
+      0B466F726D756C614D656D6F094669656C644E616D65060B466F726D756C614D
+      656D6F0844617461547970650210084461746153697A650477EC00000549734B
+      6579080F4E65656450726F636573734E616D650909507265636973696F6E0200
+      0453697A6502000001044E616D65060852656C6146696C65094669656C644E61
+      6D65060852656C6146696C650844617461547970650210084461746153697A65
+      0477EC00000549734B6579080F4E65656450726F636573734E616D6509095072
+      65636973696F6E02000453697A6502000001044E616D65060454797065094669
+      656C644E616D650604547970650844617461547970650203084461746153697A
+      6502040549734B6579080F4E65656450726F636573734E616D65090950726563
+      6973696F6E02000453697A6502000001044E616D65060742474C436F64650946
+      69656C644E616D65060742474C436F6465084461746154797065021008446174
+      6153697A650477EC00000549734B6579080F4E65656450726F636573734E616D
+      650909507265636973696F6E02000453697A6502000001044E616D6506075065
+      674E616D65094669656C644E616D6506075065674E616D650844617461547970
+      650218084461746153697A6502320549734B6579080F4E65656450726F636573
+      734E616D650909507265636973696F6E02000453697A6502000001044E616D65
+      0608464246584E616D65094669656C644E616D650608464246584E616D650844
+      617461547970650218084461746153697A6502320549734B6579080F4E656564
+      50726F636573734E616D650909507265636973696F6E02000453697A65020000
+      01044E616D650608426567696E506567094669656C644E616D65060842656769
+      6E5065670844617461547970650218084461746153697A6502320549734B6579
+      080F4E65656450726F636573734E616D650909507265636973696F6E02000453
+      697A6502000001044E616D650606456E64506567094669656C644E616D650606
+      456E645065670844617461547970650218084461746153697A6502320549734B
+      6579080F4E65656450726F636573734E616D650909507265636973696F6E0200
+      0453697A6502000001044E616D650608556E69744E616D65094669656C644E61
+      6D650608556E69744E616D650844617461547970650218084461746153697A65
+      02320549734B6579080F4E65656450726F636573734E616D6509095072656369
+      73696F6E02000453697A6502000001044E616D65060B44726177696E67436F64
+      65094669656C644E616D65060B44726177696E67436F64650844617461547970
+      650218084461746153697A6502320549734B6579080F4E65656450726F636573
+      734E616D650909507265636973696F6E02000453697A6502000000}
   end
-  object cdsZJJL: TClientDataSet
-    Aggregates = <>
-    Params = <>
-    ProviderName = 'dspZJJL'
-    Left = 33
+  object sdvZJJL: TsdDataView
+    Active = False
+    DataSet = sddZJJL
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'ID'
+      end
+      item
+        FieldName = 'BillsCode'
+      end
+      item
+        FieldName = 'Code'
+      end
+      item
+        FieldName = 'CertificateCode'
+      end
+      item
+        FieldName = 'BGLCode'
+      end
+      item
+        FieldName = 'PegName'
+      end
+      item
+        FieldName = 'BeginPeg'
+      end
+      item
+        FieldName = 'EndPeg'
+      end
+      item
+        FieldName = 'FBFXName'
+      end
+      item
+        FieldName = 'UnitName'
+      end
+      item
+        FieldName = 'DrawingCode'
+      end>
+    BeforeValueChange = sdvZJJLBeforeValueChange
+    Left = 40
     Top = 144
-    object cdsZJJLID: TIntegerField
-      FieldName = 'ID'
-    end
-    object cdsZJJLBillsID: TIntegerField
-      FieldName = 'BillsID'
-    end
-    object cdsZJJLCode: TWideStringField
-      FieldName = 'Code'
-      Size = 50
-    end
-    object cdsZJJLCertificateCode: TWideStringField
-      FieldName = 'CertificateCode'
-      Size = 50
-    end
-    object cdsZJJLBillsCode: TWideStringField
-      FieldName = 'BillsCode'
-      Size = 50
-    end
-    object cdsZJJLFormulaMemo: TMemoField
-      FieldName = 'FormulaMemo'
-      BlobType = ftMemo
-    end
-    object cdsZJJLRelaFile: TMemoField
-      FieldName = 'RelaFile'
-      BlobType = ftMemo
-      Size = 60535
-    end
-    object cdsZJJLType: TIntegerField
-      FieldName = 'Type'
-    end
-    object cdsZJJLBGLCode: TMemoField
-      FieldName = 'BGLCode'
-      BlobType = ftMemo
-      Size = 60535
-    end
-    object cdsZJJLPegName: TWideStringField
-      FieldName = 'PegName'
-      Size = 50
-    end
-    object cdsZJJLFBFXName: TWideStringField
-      FieldName = 'FBFXName'
-      Size = 255
-    end
-    object cdsZJJLBeginPeg: TWideStringField
-      FieldName = 'BeginPeg'
-      Size = 50
-    end
-    object cdsZJJLEndPeg: TWideStringField
-      FieldName = 'EndPeg'
-      Size = 50
-    end
-    object cdsZJJLUnitName: TWideStringField
-      FieldName = 'UnitName'
-      Size = 50
-    end
-    object cdsZJJLDrawingCode: TWideStringField
-      FieldName = 'DrawingCode'
-      Size = 50
-    end
   end
-  object cdsZJJLView: TClientDataSet
-    Aggregates = <>
-    Params = <>
-    AfterScroll = cdsZJJLViewAfterScroll
-    Left = 97
-    Top = 144
-    object cdsZJJLViewID: TIntegerField
-      FieldName = 'ID'
-    end
-    object cdsZJJLViewBillsID: TIntegerField
-      FieldName = 'BillsID'
-    end
-    object cdsZJJLViewCode: TWideStringField
-      FieldName = 'Code'
-      Size = 50
-    end
-    object cdsZJJLViewCertificateCode: TWideStringField
-      FieldName = 'CertificateCode'
-      Size = 50
-    end
-    object cdsZJJLViewBillsCode: TWideStringField
-      FieldName = 'BillsCode'
-      Size = 50
-    end
-    object cdsZJJLViewFormulaMemo: TMemoField
-      FieldName = 'FormulaMemo'
-      BlobType = ftMemo
-    end
-    object cdsZJJLViewRelaFile: TMemoField
-      FieldName = 'RelaFile'
-      BlobType = ftMemo
-      Size = 60535
-    end
-    object cdsZJJLViewType: TIntegerField
-      FieldName = 'Type'
-    end
-    object cdsZJJLViewBGLCode: TMemoField
-      FieldName = 'BGLCode'
-      BlobType = ftMemo
-      Size = 60535
-    end
-    object cdsZJJLViewPegName: TWideStringField
-      FieldName = 'PegName'
-      Size = 50
-    end
-    object cdsZJJLViewFBFXName: TWideStringField
-      FieldName = 'FBFXName'
-      Size = 50
-    end
-    object cdsZJJLViewBeginPeg: TWideStringField
-      FieldName = 'BeginPeg'
-      Size = 50
-    end
-    object cdsZJJLViewEndPeg: TWideStringField
-      FieldName = 'EndPeg'
-      Size = 50
-    end
-    object cdsZJJLViewUnitName: TWideStringField
-      FieldName = 'UnitName'
-      Size = 50
-    end
-    object cdsZJJLViewDrawingCode: TWideStringField
-      FieldName = 'DrawingCode'
-      Size = 50
-    end
+  object sdpHistory: TsdADOProvider
+    TableName = 'ZJJL_History'
+    Left = 120
+    Top = 16
+  end
+  object sddHistory: TsdDataSet
+    Active = False
+    Provider = sdpHistory
+    Left = 120
+    Top = 80
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D650909507265636973696F6E02000453697A6502000001044E616D
+      65060742696C6C734944094669656C644E616D65060742696C6C734944084461
+      7461547970650203084461746153697A6502040549734B6579080F4E65656450
+      726F636573734E616D650909507265636973696F6E02000453697A6502000001
+      044E616D65060454797065094669656C644E616D650604547970650844617461
+      547970650203084461746153697A6502040549734B6579080F4E65656450726F
+      636573734E616D650909507265636973696F6E02000453697A6502000001044E
+      616D6506094669656C644E616D65094669656C644E616D6506094669656C644E
+      616D650844617461547970650201084461746153697A6502320549734B657908
+      0F4E65656450726F636573734E616D650909507265636973696F6E0200045369
+      7A6502000001044E616D65060A4669656C6456616C7565094669656C644E616D
+      65060A4669656C6456616C75650844617461547970650210084461746153697A
+      650477EC00000549734B6579080F4E65656450726F636573734E616D65090950
+      7265636973696F6E02000453697A6502000000}
   end
 end

+ 339 - 220
DataModules/ZJJLDm.pas

@@ -5,7 +5,7 @@ interface
 uses
   ZjGrid,
   SysUtils, Classes, DB, DBClient, ADODB, sdIDTree, sdDB, Provider,
-  Windows, BillsTree;
+  Windows, BillsTree, sdProvider, Variants;
 
 type
   TZJJLType = (ztFx, ztGcl);
@@ -24,54 +24,26 @@ type
   TZJJLInfoRec = Record
     FBFXName: string;
     PegName: string;
+    BeginPeg: string;
+    EndPeg: 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;
-    cdsZJJLType: TIntegerField;
-
-    cdsZJJLView: TClientDataSet;
-    cdsZJJLViewID: TIntegerField;
-    cdsZJJLViewBillsID: TIntegerField;
-    cdsZJJLViewCode: TWideStringField;
-    cdsZJJLViewCertificateCode: TWideStringField;
-    cdsZJJLViewBillsCode: TWideStringField;
-    cdsZJJLViewFormulaMemo: TMemoField;
-    cdsZJJLViewType: TIntegerField;
-    cdsZJJLRelaFile: TMemoField;
-    cdsZJJLViewRelaFile: TMemoField;
-    cdsZJJLBGLCode: TMemoField;
-    cdsZJJLPegName: TWideStringField;
-    cdsZJJLFBFXName: TWideStringField;
-    cdsZJJLBeginPeg: TWideStringField;
-    cdsZJJLEndPeg: TWideStringField;
-    cdsZJJLUnitName: TWideStringField;
-    cdsZJJLDrawingCode: TWideStringField;
-    cdsZJJLViewBGLCode: TMemoField;
-    cdsZJJLViewPegName: TWideStringField;
-    cdsZJJLViewFBFXName: TWideStringField;
-    cdsZJJLViewBeginPeg: TWideStringField;
-    cdsZJJLViewEndPeg: TWideStringField;
-    cdsZJJLViewUnitName: TWideStringField;
-    cdsZJJLViewDrawingCode: TWideStringField;
-    procedure cdsZJJLViewAfterScroll(DataSet: TDataSet);
+    sdpZJJL: TsdADOProvider;
+    sddZJJL: TsdDataSet;
+    sdvZJJL: TsdDataView;
+    sdpHistory: TsdADOProvider;
+    sddHistory: TsdDataSet;
+    procedure sdvZJJLBeforeValueChange(AValue: TsdValue;
+      const NewValue: Variant; var Allow: Boolean);
   private
     FPhaseData: TObject;
     FCanModified: Boolean;
     FNewID: Integer;
     FOrgDataList: TList;
-    FDetailGrid: TZJGrid;
 
     procedure GenerateZJJLNode(ANode: TsdIDTreeNode; AType: Integer);
 
@@ -91,6 +63,21 @@ type
       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;
 
@@ -106,7 +93,7 @@ type
 
     procedure GenerateAll;
     procedure GenerateAllByB_Code;
-    procedure AssignedCurData;
+    procedure AssignedCurData(ARec: TsdDataRecord; ADetailGrid: TZJGrid);
 
     function GetInfoRecByCode(ABillsID: Integer): TZJJLInfoRec;
     function GetInfoRecByB_Code(ABillsID: Integer): TZJJLInfoRec;
@@ -117,14 +104,13 @@ type
     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;
+  BillsCompileDm, BillsMeasureDm, mPegFilter;
 
 {$R *.dfm}
 
@@ -135,15 +121,10 @@ 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;
@@ -157,18 +138,24 @@ end;
 
 procedure TZJJLData.Open(AConnection: TADOConnection);
 begin
-  atZJJL.Connection := AConnection;
-  cdsZJJL.Open;
-  cdsZJJL.IndexFieldNames := 'ID';
-  cdsZJJLView.CloneCursor(cdsZJJL, True);
-  cdsZJJLView.IndexFieldNames := 'ID';
+  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
-  cdsZJJL.ApplyUpdates(0);
+  sddZJJL.Save;
+  sddHistory.Save;
 end;
 
 function TZJJLData.CheckLastXmj(AID: Integer): Boolean;
@@ -182,34 +169,35 @@ begin
   Result := stnChild.Rec.ValueByName('B_Code').AsString <> '';
 end;
 
-procedure TZJJLData.AssignedCurData;
+procedure TZJJLData.AssignedCurData(ARec: TsdDataRecord; ADetailGrid: TZJGrid);
 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 := '变更令号:' + cdsZJJLViewBGLCode.AsString;
-  FDetailGrid.Cells[0, 1].Text := '桩号或部位:' + cdsZJJLViewPegName.AsString;
-  FDetailGrid.Cells[0, 2].Text := '分部分项工程:' + cdsZJJLViewFBFXName.AsString;
-  FDetailGrid.Cells[0, 3].Text := '计量单元:' + cdsZJJLViewUnitName.AsString;
-  FDetailGrid.Cells[0, 4].Text := '图号:' + cdsZJJLViewDrawingCode.AsString;
-  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;
+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;
@@ -268,32 +256,33 @@ end;
 
 procedure TZJJLData.DeleteAll;
 begin
-  cdsZJJL.First;
-  while not cdsZJJL.Eof do
-    cdsZJJL.Delete;
+  sddZJJL.DeleteAll;
 end;
 
 procedure TZJJLData.RestoreOrgData;
 
-  function CreateNodeData: TZJJLNode;
+  function CreateNodeData(ARec: TsdDataRecord): 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;
+
+    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;
-  cdsZJJL.First;
-  while not cdsZJJL.Eof do
+  for i := 0 to sddZJJL.RecordCount - 1 do
   begin
-    FOrgDataList.Add(CreateNodeData);
-    cdsZJJL.Next;
+    vRec := sddZJJL.Records[i];
+    FOrgDataList.Add(CreateNodeData(vRec));
   end;
 end;
 
@@ -326,11 +315,6 @@ begin
     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
@@ -339,85 +323,13 @@ begin
 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.PegName := GetFieldStrDef(vPeg, 'Name', '');
   Result.FBFXName := GetFBFXName(vNode, vPeg);
   Result.UnitName := GetFieldStrDef(vNode, 'Name', '');
   Result.DrawingCode := GetDrawingCode(vNode);
@@ -425,19 +337,16 @@ end;
 
 procedure TZJJLData.DetailGridCellTextChanged(Sender: TObject; Col,
   Row: Integer);
+var
+  Rec: TsdDataRecord;
 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;
+  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;
@@ -506,38 +415,49 @@ procedure TZJJLData.GenerateZJJLNode(ANode: TsdIDTreeNode;
       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
-  cdsZJJL.Append;
-  cdsZJJLID.AsInteger := FNewID;
-  cdsZJJLBillsID.AsInteger := ANode.ID;
-  cdsZJJLType.AsInteger := AType;
-  ZJJLNode := GetOrgZJJLNode(ANode.ID);
-
-  cdsZJJLCode.AsString := GetNewCode;
+  Rec := sddZJJL.Add;
+  Rec.ValueByName('ID').AsInteger := FNewID;
+  Rec.ValueByName('BillsID').AsInteger := ANode.ID;
+  Rec.ValueByName('Type').AsInteger := AType;
   if AType = Ord(ztFx) then
-    cdsZJJLBillsCode.AsString := ANode.Rec.ValueByName('Code').AsString
+    Rec.ValueByName('BillsCode').AsString := ANode.Rec.ValueByName('Code').AsString
   else if AType = Ord(ztGcl) then
-    cdsZJJLBillsCode.AsString := ANode.Rec.ValueByName('B_Code').AsString;
-  if Assigned(ZJJLNode) then
-  begin
-    cdsZJJLCertificateCode.AsString := ZJJLNode.FCertificateCode;
-    cdsZJJLFormulaMemo.AsString := ZJJLNode.FFormulaMemo;
-    cdsZJJLRelaFile.AsString := ZJJLNode.FRelaFile;
-  end;
-  cdsZJJL.Post;
+    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;
-
-  function GetBGLCode(ANode: TsdIDTreeNode): string;
-  begin
-    with TProjectData(TPhaseData(FPhaseData).ProjectData) do
-      Result := BillsMeasureData.GatherRelaBGL(ANode);
-  end;
-
 var
   vNode: TsdIDTreeNode;
 begin
@@ -564,7 +484,7 @@ var
 begin
   with TProjectData(TPhaseData(FPhaseData).ProjectData) do
   begin
-    Rec := BillsData.sddBills.FindKey('idxID', cdsZJJLViewBillsID.AsInteger);
+    Rec := BillsData.sddBills.FindKey('idxID', sdvZJJL.Current.ValueByName('BillsID').AsInteger);
     BillsMeasureData.sdvBillsMeasure.LocateInControl(Rec);
   end;
 end;
@@ -586,28 +506,227 @@ end;
 procedure TZJJLData.CheckZjjlVerison;
 
   procedure LoadVersion0Info;
-    var
-    sSql: string;
+  var
+    i: Integer;
+    Rec: TsdDataRecord;
     ZJJLInfoRec: TZJJLInfoRec;
   begin
-    cdsZJJL.First;
-    while not cdsZJJL.Eof do
+    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
-      ZJJLInfoRec := GetInfoRec(cdsZJJLBillsID.AsInteger, cdsZJJLType.AsInteger);
-      cdsZJJL.Edit;
-      cdsZJJLBGLCode.AsString := ZJJLInfoRec.BGLCode;
-      cdsZJJLPegName.AsString := ZJJLInfoRec.PegName;
-      cdsZJJLFBFXName.AsString := ZJJLInfoRec.FBFXName;
-      cdsZJJLUnitName.AsString := ZJJLInfoRec.UnitName;
-      cdsZJJLDrawingCode.AsString := ZJJLInfoRec.DrawingCode;
-      cdsZJJL.Post;
-      cdsZJJL.Next;
+      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
     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;
 
 end.

+ 63 - 41
Frames/ZJJLFme.dfm

@@ -2,7 +2,7 @@ object ZJJLFrame: TZJJLFrame
   Left = 0
   Top = 0
   Width = 390
-  Height = 517
+  Height = 722
   Font.Charset = ANSI_CHARSET
   Font.Color = clWindowText
   Font.Height = -12
@@ -85,7 +85,7 @@ object ZJJLFrame: TZJJLFrame
     Left = 0
     Top = 47
     Width = 390
-    Height = 190
+    Height = 325
     Align = alClient
     BevelOuter = bvNone
     TabOrder = 1
@@ -93,7 +93,7 @@ object ZJJLFrame: TZJJLFrame
       Left = 0
       Top = 18
       Width = 390
-      Height = 172
+      Height = 307
       Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection]
       OptionsEx = []
       ColCount = 4
@@ -104,6 +104,7 @@ object ZJJLFrame: TZJJLFrame
       Selection.TransparentColor = False
       FrozenCol = 0
       FrozenRow = 0
+      OnCurrentChanged = zgZJJLCurrentChanged
       OnMouseDown = zgZJJLMouseDown
       Align = alClient
     end
@@ -144,9 +145,9 @@ object ZJJLFrame: TZJJLFrame
   end
   object pnlZJJLProperty: TPanel
     Left = 0
-    Top = 237
+    Top = 372
     Width = 390
-    Height = 280
+    Height = 350
     Align = alBottom
     BevelOuter = bvNone
     TabOrder = 2
@@ -184,6 +185,28 @@ object ZJJLFrame: TZJJLFrame
         TabOrder = 0
       end
     end
+    object zgDetailInfo: TZJGrid
+      Left = 0
+      Top = 22
+      Width = 390
+      Height = 328
+      Options = [goRangeSelect, goRowSizing, goColSizing, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection, goWarpText]
+      OptionsEx = []
+      ColCount = 1
+      RowCount = 11
+      FixedRowCount = 0
+      FixedColCount = 0
+      ShowGridLine = False
+      DefaultColWidth = 330
+      Selection.AlphaBlend = False
+      Selection.TransparentColor = False
+      FrozenCol = 0
+      FrozenRow = 0
+      OnGetCellText = zgDetailInfoGetCellText
+      OnSetCellText = zgDetailInfoSetCellText
+      OnCellCanEdit = zgDetailInfoCellCanEdit
+      Align = alClient
+    end
   end
   object alBGL: TActionList
     Images = MainForm.Images
@@ -211,7 +234,40 @@ object ZJJLFrame: TZJJLFrame
       OnExecute = actnGenerateGclZJJLExecute
     end
   end
-  object zaZJJL: TZjGridDBA
+  object dxpmZJJL: TdxBarPopupMenu
+    BarManager = MainForm.dxBarManager
+    ItemLinks = <
+      item
+        Item = MainForm.dxbtnLocateBills
+        Visible = True
+      end
+      item
+        BeginGroup = True
+        Item = MainForm.dxbtnDelete
+        Visible = True
+      end>
+    UseOwnFont = False
+    OnPopup = dxpmZJJLPopup
+    Left = 104
+    Top = 160
+  end
+  object dxpmAutoGenerate: TdxBarPopupMenu
+    BarManager = MainForm.dxBarManager
+    ItemLinks = <
+      item
+        Item = MainForm.dxbtnFxZJJL
+        Visible = True
+      end
+      item
+        Item = MainForm.dxbtnGclZJJL
+        Visible = True
+      end>
+    UseOwnFont = False
+    OnPopup = dxpmAutoGeneratePopup
+    Left = 104
+    Top = 200
+  end
+  object saZJJL: TsdGridDBA
     Columns = <
       item
         Title.Caption = #32534#21495
@@ -228,7 +284,7 @@ object ZJJLFrame: TZJJLFrame
         Font.Name = #23435#20307
         Font.Style = []
         FieldName = 'BillsCode'
-        ReadOnly = True
+        ReadOnly = False
       end
       item
         Title.Caption = #20013#38388#35745#37327#34920#21495
@@ -266,41 +322,7 @@ object ZJJLFrame: TZJJLFrame
       end>
     Grid = zgZJJL
     ExtendRowCount = 0
-    Options = [aoAllowEdit, aoAllowDelete]
     Left = 152
     Top = 160
   end
-  object dxpmZJJL: TdxBarPopupMenu
-    BarManager = MainForm.dxBarManager
-    ItemLinks = <
-      item
-        Item = MainForm.dxbtnLocateBills
-        Visible = True
-      end
-      item
-        BeginGroup = True
-        Item = MainForm.dxbtnDelete
-        Visible = True
-      end>
-    UseOwnFont = False
-    OnPopup = dxpmZJJLPopup
-    Left = 104
-    Top = 160
-  end
-  object dxpmAutoGenerate: TdxBarPopupMenu
-    BarManager = MainForm.dxBarManager
-    ItemLinks = <
-      item
-        Item = MainForm.dxbtnFxZJJL
-        Visible = True
-      end
-      item
-        Item = MainForm.dxbtnGclZJJL
-        Visible = True
-      end>
-    UseOwnFont = False
-    OnPopup = dxpmAutoGeneratePopup
-    Left = 104
-    Top = 200
-  end
 end

+ 119 - 12
Frames/ZJJLFme.pas

@@ -6,9 +6,17 @@ uses
   ZJJLDm,
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, ExtCtrls, StdCtrls, DBCtrls, Mask, JimLabels, DB, ComCtrls,
-  ToolWin, ActnList, ZjGridDBA, ZJGrid, dxBar;
+  ToolWin, ActnList, ZjGridDBA, ZJGrid, dxBar, sdGridDBA, sdDB;
 
 type
+  TRowIndex = (riBGLCode, riPegName, riBeginPeg, riEndPeg, riFBFXName, riUnitName, riDrawingCode,
+    riFormulaMemoTitle, riFormulaMemoValue, riRelaFileTitle, riRelaFileValue);
+const
+  RowFields: array [TRowIndex] of string = ('BGLCode', 'PegName', 'BeginPeg', 'EndPeg', 'FBFXName', 'UnitName', 'DrawingCode',
+    '', 'FormulaMemo', '', 'RelaFile');
+  RowFormats: array [TRowIndex] of string = ('变更令号:', '部位:', '起始桩号:', '终止桩号:', '分部分项工程:', '计量单元:', '图号:',
+    '计算式说明:', '', '计算草图几何尺寸:', '');
+type
   TZJJLFrame = class(TFrame)
     labTitle: TJimGradLabel;
     alBGL: TActionList;
@@ -18,7 +26,6 @@ type
     tobaTop: TToolBar;
     tobtnGenerate: TToolButton;
     lePreText: TLabeledEdit;
-    zaZJJL: TZjGridDBA;
     pnlZJJL: TPanel;
     zgZJJL: TZJGrid;
     pnlListTitle: TPanel;
@@ -33,6 +40,8 @@ type
     dxpmAutoGenerate: TdxBarPopupMenu;
     actnGenerateFxZJJL: TAction;
     actnGenerateGclZJJL: TAction;
+    saZJJL: TsdGridDBA;
+    zgDetailInfo: TZJGrid;
     procedure actnGenerateExecute(Sender: TObject);
     procedure lePreTextExit(Sender: TObject);
     procedure zgZJJLMouseDown(Sender: TObject; Button: TMouseButton;
@@ -44,6 +53,13 @@ type
     procedure actnGenerateFxZJJLExecute(Sender: TObject);
     procedure actnGenerateGclZJJLExecute(Sender: TObject);
     procedure actnGenerateUpdate(Sender: TObject);
+    procedure zgDetailInfoGetCellText(Sender: TObject;
+      const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+    procedure zgZJJLCurrentChanged(Sender: TObject; Col, Row: Integer);
+    procedure zgDetailInfoSetCellText(Sender: TObject;
+      const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+    procedure zgDetailInfoCellCanEdit(Sender: TObject;
+      const ACoord: TPoint; var Allow: Boolean);
   private
     FZJJLData: TZJJLData;
     FDataReadOnly: Boolean;
@@ -51,6 +67,9 @@ type
 
     procedure RefreshTitle;
     procedure GenerateZJJL;
+
+    procedure DetailGridCellTextChanged(Sender: TObject; Col, Row: Integer);
+    procedure InitDetailGrid;
   public
     constructor Create(AParent: TFrame; AZJJLData: TZJJLData);
     destructor Destroy; override;
@@ -64,7 +83,7 @@ implementation
 
 uses
   MergeTextFrm, PhaseData, MainFrm, ProjectData, UtilMethods,
-  PhaseProperty;
+  PhaseProperty, Math;
 
 {$R *.dfm}
 
@@ -87,8 +106,11 @@ end;
 procedure TZJJLFrame.ResetFrameLink(AZJJLData: TZJJLData);
 begin
   FZJJLData := AZJJLData;
-  zaZJJL.DataSet := FZJJLData.cdsZJJLView;
-  AlignControl(FZJJLData.DetailGrid, pnlZJJLProperty, alClient);
+  saZJJL.DataView := FZJJLData.sdvZJJL;
+  InitDetailGrid;
+  if (saZJJL.DataView.RecordCount > 0) then
+    saZJJL.DataView.LocateInControl(saZJJL.DataView.Records[0]);
+  zgDetailInfo.Invalidate;
 end;
 
 procedure TZJJLFrame.actnGenerateExecute(Sender: TObject);
@@ -118,8 +140,8 @@ begin
   FDataReadOnly := Value;
   actnGenerate.Enabled := not FDataReadOnly;
   lePreText.Enabled := not FDataReadOnly;
-  zaZJJL.Column('Code').ReadOnly := FDataReadOnly;
-  zaZJJL.Column('CertificateCode').ReadOnly := FDataReadOnly;
+  saZJJL.Columns.ColumnByName('Code').ReadOnly := FDataReadOnly;
+  saZJJL.Columns.ColumnByName('CertificateCode').ReadOnly := FDataReadOnly;
 end;
 
 procedure TZJJLFrame.zgZJJLMouseDown(Sender: TObject; Button: TMouseButton;
@@ -127,9 +149,9 @@ procedure TZJJLFrame.zgZJJLMouseDown(Sender: TObject; Button: TMouseButton;
 begin
   if Button = mbRight then
     dxpmZJJL.PopupFromCursorPos
-  else if (ssDouble in Shift) and (zgZJJL.CurCol = 1) then
+  else if (ssDouble in Shift) and (zgZJJL.CurCol = 1) and (zgZJJL.CurRow > 0) then
   begin
-    if FZJJLData.cdsZJJLView.RecordCount > 0 then
+    if saZJJL.DataView.RecordCount > 0 then
       FZJJLData.LocateBills;
   end;
 end;
@@ -146,7 +168,7 @@ end;
 
 procedure TZJJLFrame.actnLocateBillsUpdate(Sender: TObject);
 begin
-  TAction(Sender).Enabled := FZJJLData.cdsZJJLView.RecordCount > 0;
+  TAction(Sender).Enabled := Assigned(FZJJLData.sdvZJJL.Current);
 end;
 
 procedure TZJJLFrame.RefreshTitle;
@@ -191,8 +213,10 @@ begin
     0: FZJJLData.GenerateAll;
     1: FZJJLData.GenerateAllByB_Code;
   end;
-  FZJJLData.AssignedCurData;
-  RefreshTitle;
+  RefreshTitle; 
+  if (saZJJL.DataView.RecordCount > 0) then
+    saZJJL.DataView.LocateInControl(saZJJL.DataView.Records[0]);
+  zgDetailInfo.Invalidate;
 end;
 
 procedure TZJJLFrame.actnGenerateGclZJJLExecute(Sender: TObject);
@@ -213,4 +237,87 @@ begin
     TAction(Sender).Enabled := not StageDataReadOnly;
 end;
 
+procedure TZJJLFrame.DetailGridCellTextChanged(Sender: TObject; Col,
+  Row: Integer);
+var
+  Rec: TsdDataRecord;
+begin
+  Rec := saZJJL.DataView.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 TZJJLFrame.zgDetailInfoGetCellText(Sender: TObject;
+  const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+
+  function GetDefaultValue(ARec: TsdDataRecord; AFieldName: string): string;
+  begin
+    if Assigned(ARec) and (AFieldName <> '') then
+      Result := ARec.ValueByName(AFieldName).AsString
+    else
+      Result := '';
+  end;
+
+  function GetText(ARow: TRowIndex): string;
+  var
+    Rec: TsdDataRecord;
+  begin
+    Rec := saZJJL.DataView.Current;
+    if DisplayText then
+      Result := RowFormats[ARow] + GetDefaultValue(Rec, RowFields[ARow])
+    else
+      Result := GetDefaultValue(Rec, RowFields[ARow]);
+  end;
+
+begin
+  Value := GetText(TRowIndex(ACoord.Y));
+end;
+
+procedure TZJJLFrame.InitDetailGrid;
+var
+  iRowIndex: Integer;
+begin
+  zgDetailInfo.DefaultColWidth := zgDetailInfo.Width - 25;
+  for iRowIndex := 0 to zgDetailInfo.RowCount - 1 do
+    zgDetailInfo[0, iRowIndex].Align := gaTopLeft;
+  zgDetailInfo.RowHeights[Integer(riFormulaMemoValue)] := 57;
+  zgDetailInfo.RowHeights[Integer(riRelaFileValue)] := 57;
+end;
+
+procedure TZJJLFrame.zgZJJLCurrentChanged(Sender: TObject; Col,
+  Row: Integer);
+begin
+  zgDetailInfo.Invalidate;
+end;
+
+procedure TZJJLFrame.zgDetailInfoSetCellText(Sender: TObject;
+  const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+var
+  Rec: TsdDataRecord;
+  sFieldName: string;
+begin
+  Rec := saZJJL.DataView.Current;
+  if Assigned(Rec) then
+  begin
+    sFieldName := RowFields[TRowIndex(ACoord.Y)];
+    if (sFieldName <> '') then
+    begin
+      saZJJL.DataView.Text[saZJJL.DataView.IndexOf(Rec), saZJJL.DataView.FindColumn(sFieldName).Index] := Value;
+    end;
+  end;
+end;
+
+procedure TZJJLFrame.zgDetailInfoCellCanEdit(Sender: TObject;
+  const ACoord: TPoint; var Allow: Boolean);
+var
+  sFieldName: string;
+begin
+  sFieldName := RowFields[TRowIndex(ACoord.Y)];
+  Allow := sFieldName <> '';
+end;
+
 end.

+ 6 - 5
Units/Connections.pas

@@ -482,11 +482,12 @@ var
   vCon: TADOConnection;
 begin
   Result := False;
-  vCon := TADOConnection.Create(nil);
-  vCon.LoginPrompt := False;
-  sConnectFile := GetTempFileName;
-  sTempFile := GetTempFileName;
   try
+    sConnectFile := GetTempFileName;
+    sTempFile := GetTempFileName;
+    vCon := TADOConnection.Create(nil);
+    vCon.LoginPrompt := False;
+
     if FileExists(AFileName) then
     begin
       CopyFileOrFolder(AFileName, sTempFile);
@@ -503,9 +504,9 @@ begin
       Result := True;
     end;
   finally
+    vCon.Free;
     DeleteFile(PChar(sConnectFile));
     DeleteFile(PChar(sTempFile));
-    vCon.Free;
   end;
 end;
 

+ 7 - 4
Units/DataBaseTables.pas

@@ -984,7 +984,7 @@ const
 
     // 变更令号
     (FieldName: 'BGLCode'; FieldType: ftMemo; Size: 60535; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
-    // 部位:取了个这么奇葩的名字不怪我。。原来这玩意叫桩号或部位,所以就用了Peg。。
+    // 部位:取了个这么奇葩的名字。。原来这玩意叫桩号; 后来非要把部位拼过来,就变成桩号或部位; 现在变成只有部位。。
     (FieldName: 'PegName'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
     // 分布分项
     (FieldName: 'FBFXName'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
@@ -998,10 +998,13 @@ const
     (FieldName: 'DrawingCode'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
   );
 
-  SZjjlHistory = 'ZjjlHistory';
-  tdZjjlHistory: array [0..1] of TScFieldDef =(
+  SZJJL_History = 'ZJJL_History';
+  tdZJJL_History: array [0..4] of TScFieldDef =(
     (FieldName: 'ID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
-    (FieldName: 'ZjjlID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False)
+    (FieldName: 'BillsID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Type'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'FieldName'; FieldType: ftString; Size: 50; Precision: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'FieldValue'; FieldType: ftMemo; Size: 60535; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
   );
 
   // 报表数据

+ 1 - 1
Units/PhaseProperty.pas

@@ -146,7 +146,7 @@ end;
 
 procedure TPhaseProperties.SetZjjlVersion(const Value: Integer);
 begin
-  FPropertyInqurity.Value['ZjjlVerison'] := Value;
+  FPropertyInqurity.Value['ZjjlVersion'] := Value;
 end;
 
 end.

+ 2 - 33
Units/ProjectData.pas

@@ -263,7 +263,7 @@ implementation
 uses UtilMethods, Globals, ProjectCommands, sdIDTree, StageDm,
   ZJJLDm, PHPWebDm, XMLDoc, XMLIntf, ConstUnit, PasswordInputFrm,
   mProgressProFrm, mDataRecord, ConditionalDefines, DbTreeImport,
-  StrUtils;
+  StrUtils, sdProvider;
 
 { TProjectData }
 
@@ -889,37 +889,6 @@ procedure TProjectData.CopyPhaseData;
     ExecuteSql(sSql);
   end;
 
-  procedure UpdateZJJLData;
-
-    function EscString(const AStr: string): string;
-    begin
-      Result := AnsiReplaceStr(AStr, '''', '''''');
-    end;
-
-  const
-    sUpdateSql = 'Update P_ZJJL' +
-                 '  Set BGLCode = ''%s'', PegName = ''%s'', FBFXName = ''%s'',' +
-                 '      UnitName = ''%s'', DrawingCode = ''%s''' +
-                 '  Where ID = %d';
-  var
-    sSql: string;
-    ZJJLInfoRec: TZJJLInfoRec;
-  begin
-    with PhaseData.ZJJLData do
-    begin
-      cdsZJJL.First;
-      while not cdsZJJL.Eof do
-      begin
-        ZJJLInfoRec := GetInfoRec(cdsZJJLBillsID.AsInteger, cdsZJJLType.AsInteger);
-        sSql := Format(sUpdateSql, [EscString(ZJJLInfoRec.BGLCode), EscString(ZJJLInfoRec.PegName),
-            EscString(ZJJLInfoRec.FBFXName), EscString(ZJJLInfoRec.UnitName), EscString(ZJJLInfoRec.DrawingCode),
-            cdsZJJLID.AsInteger]);
-        ExecuteSql(sSql);
-        cdsZJJL.Next;
-      end;
-    end;
-  end;
-
   procedure CopyZJJLBillsData;
   var
     sSql: string;
@@ -938,7 +907,7 @@ procedure TProjectData.CopyPhaseData;
     sSql := 'Select ID, BillsID, Code, CertificateCode, BillsCode, FormulaMemo, RelaFile,' +
             '    BGLCode, PegName, FBFXName, BeginPeg, EndPeg, UnitName, DrawingCode' +
             '  Into P_ZJJL' +
-            '  From ' + PhaseData.ZJJLData.atZJJL.TableName +
+            '  From ' + PhaseData.ZJJLData.sdpZJJL.TableName +
             '  In ' + Format('''%s''', [AFileName]);
     ExecuteSql(sSql);
     CopyZJJLBillsData;

+ 1 - 0
Units/UpdateDataBase.pas

@@ -174,6 +174,7 @@ begin
     Updater.AddTableDef(SPhaseProperty, @tdPhaseProperty, Length(tdPhaseProperty), False, False);
     Updater.AddTableDef(SPhasePay, @tdPhasePay, Length(tdPhasePay), False, False);
     Updater.AddTableDef(SZJJL, @tdZJJL, Length(tdZJJL), False, False);
+    Updater.AddTableDef(SZJJL_History, @tdZJJL_History, length(tdZJJL_History), False, False);
     Updater.AddTableDef(SReportData, @tdReportData, Length(tdReportData), False, False);
     Updater.ExcuteUpdate;
   finally

+ 176 - 2
Units/mPegFilter.pas

@@ -3,9 +3,11 @@ unit mPegFilter;
 interface
 
 uses
-  Classes, SysUtils;
+  Classes, SysUtils, PerlRegEx;
 
 type
+  // analyse Peg Num
+  // YK1+000 --> K1+000
   TPegFilter = class
   private
     FBeginPeg: string;
@@ -24,11 +26,55 @@ type
     property EndPegNum: Double read FEndPegNum;
   end;
 
+  // filter begin/end Peg, keep orginal Peg
+  // GLK1+000 --> GLK1+000
+  TPegInfo = class
+    FPeg: string;
+    FOffset: Integer;
+    FLength: Integer;
+  end;
+
+  TPegStrFilter = class
+  private
+    FToRegStr: string;
+    FPegRegStr: string;
+    FPegStr: string;
+
+    FPegList: TList;
+    FBeginPegList: TList;
+    FEndPegList: TList;
+
+    procedure ClearHistory;
+    procedure FilterPeg;
+    procedure FilterBeginAndEnd;
+    procedure AnalysePeg;
+
+    function MergePeg(Pegs: TList): string;
+
+    procedure SetPegStr(const Value: string);
+    function GetBeginPeg: string;
+    function GetEndPeg: string;
+    function GetSubPegCount: Integer;
+    function GetSubPeg(AIndex: Integer): string;
+  public
+    constructor Create;
+    destructor Destory;
+
+    property PegRegStr: string read FPegRegStr;
+    property ToRegStr: string read FToRegStr;
+
+    property PegStr: string read FPegStr write SetPegStr;
+    property BeginPeg: string read GetBeginPeg;
+    property EndPeg: string read GetEndPeg;
+    property SubPegCount: Integer read GetSubPegCount;
+    property SubPeg[AIndex: Integer]: string read GetSubPeg;
+  end;
+
 function PegFilter: TPegFilter;
 
 implementation
 
-uses Math;
+uses Math, ZhAPI;
 
 var
   FPegFilter: TPegFilter;
@@ -191,6 +237,134 @@ begin
   Result := StringReplace(Result, ' ', '', [rfReplaceAll]);
 end;
 
+{ TPegStrFilter }
+
+procedure TPegStrFilter.AnalysePeg;
+begin
+  ClearHistory;
+  FilterPeg;
+  FilterBeginAndEnd;
+end;
+
+procedure TPegStrFilter.ClearHistory;
+begin
+  ClearObjects(FPegList);
+  FPegList.Clear;
+  FBeginPegList.Clear;
+  FEndPegList.Clear;
+end;
+
+constructor TPegStrFilter.Create;
+begin
+  FPegRegStr := '[a-zA-z]{0,2}[kK]\d+[+£«][0-9.]+';
+  FToRegStr := '[-£­~¡«]';
+
+  FPegList := TList.Create;
+  FBeginPegList := TList.Create;
+  FEndPegList := TList.Create;
+end;
+
+destructor TPegStrFilter.Destory;
+begin
+  FEndPegList.Free;
+  FBeginPegList.Free;
+  ClearObjects(FPegList);
+  FPegList.Free;
+end;
+
+procedure TPegStrFilter.FilterBeginAndEnd;
+var
+  vToReg: TPerlRegEx;
+  vPeg1, vPeg2: TPegInfo;
+  i, iPos: Integer;
+begin
+  vToReg := TPerlRegEx.Create;
+  vToReg.RegEx := FToRegStr;
+  if FPegList.Count > 0 then
+  begin
+    for i := 1 to FPegList.Count - 1 do
+    begin
+      iPos := i;
+      vPeg1 := TPegInfo(FPegList.Items[i - 1]);
+      vPeg2 := TPegInfo(FPegList.Items[i]);
+      vToReg.Subject := Copy(FPegStr, vPeg1.FOffSet + vPeg1.FLength, vPeg2.FOffSet - (vPeg1.FOffSet + vPeg1.FLength));
+      if vToReg.Match then
+        Break;
+    end;
+
+    for i := 0 to FPegList.Count - 1 do
+    begin
+      if i < iPos then
+        FBeginPegList.Add(FPegList.Items[i])
+      else
+        FEndPegList.Add(FPegList.Items[i]);
+    end;
+  end;
+  vToReg.Free;
+end;
+
+procedure TPegStrFilter.FilterPeg;
+var
+  vPegReg: TPerlRegEx;
+  vPegInfo: TPegInfo;
+begin
+  vPegReg := TPerlRegEx.Create;
+  vPegReg.Subject := PegStr;
+  vPegReg.RegEx := PegRegStr;
+  while vPegReg.MatchAgain do
+  begin
+    vPegInfo := TPegInfo.Create;
+    vPegInfo.FPeg := vPegReg.MatchedText;
+    vPegInfo.FOffset := vPegReg.MatchedOffset;
+    vPegInfo.FLength := vPegReg.MatchedLength;
+    FPegList.Add(vPegInfo);
+  end;
+  vPegReg.Free;
+end;
+
+function TPegStrFilter.GetBeginPeg: string;
+begin
+  Result := MergePeg(FBeginPegList);
+end;
+
+function TPegStrFilter.GetEndPeg: string;
+begin
+  Result := MergePeg(FEndPegList);
+end;
+
+function TPegStrFilter.GetSubPeg(AIndex: Integer): string;
+begin
+  if (AIndex < 0) or (AIndex >= SubPegCount) then
+    Result := ''
+  else
+    Result := TPegInfo(FPegList.Items[AIndex]).FPeg;
+end;
+
+function TPegStrFilter.GetSubPegCount: Integer;
+begin
+  Result := FPegList.Count;
+end;
+
+function TPegStrFilter.MergePeg(Pegs: TList): string;
+var
+  i: Integer;
+begin
+  Result := '';
+  for i := 0 to Pegs.Count - 1 do
+  begin
+    if i = 0 then
+      Result := TPegInfo(Pegs.Items[i]).FPeg
+    else
+      Result := Result + '/' + TPegInfo(Pegs.Items[i]).FPeg;
+  end;
+end;
+
+procedure TPegStrFilter.SetPegStr(const Value: string);
+begin
+  FPegStr := Value;
+  AnalysePeg;
+end;
+
 initialization
   FPegFilter := nil;
 finalization