Prechádzať zdrojové kódy

Merge branch 'master' of http://192.168.1.12:3000/maixinrong/measure

TonyKang 7 rokov pred
rodič
commit
061df70373
95 zmenil súbory, kde vykonal 7102 pridanie a 624 odobranie
  1. 13 0
      DataModules/BGLDm.dfm
  2. 135 1
      DataModules/BGLDm.pas
  3. 6 0
      DataModules/BillsCompileDm.dfm
  4. 93 1
      DataModules/BillsCompileDm.pas
  5. 8 1
      DataModules/BillsDm.dfm
  6. 31 1
      DataModules/BillsGatherDm.pas
  7. 7 0
      DataModules/BillsMeasureDm.dfm
  8. 135 6
      DataModules/BillsMeasureDm.pas
  9. 23 18
      DataModules/DealBillsDm.dfm
  10. 26 1
      DataModules/DealBillsDm.pas
  11. 78 1
      DataModules/ProjectManagerDm.pas
  12. 2 2
      DataModules/ReportMemoryDm/rmBillsGatherDm.pas
  13. 5 1
      DataModules/ReportMemoryDm/rmGclBillsBGDm.pas
  14. 6 3
      DataModules/StageDm.pas
  15. 50 3
      DataModules/ZJJLDm.dfm
  16. 245 35
      DataModules/ZJJLDm.pas
  17. 31 3
      Dprs/PWFree/Measure_Cloud.dpr
  18. 0 283
      Dprs/PWFree/Measure_GuangDong_Cloud.dpr
  19. 2 2
      Dprs/Pro/Measure.dof
  20. 13 1
      Dprs/Pro/Measure.dpr
  21. BIN
      Dprs/Pro/Measure.res
  22. 2 2
      Dprs/Pro/Measure_Cloud.dof
  23. 28 1
      Dprs/Pro/Measure_Cloud.dpr
  24. BIN
      Dprs/Pro/Measure_Cloud.res
  25. 2 2
      Dprs/Pro/Measure_GuangDong.dof
  26. 13 1
      Dprs/Pro/Measure_GuangDong.dpr
  27. BIN
      Dprs/Pro/Measure_GuangDong.res
  28. 2 2
      Dprs/Pro/Measure_GuangDong_Cloud.dof
  29. 13 1
      Dprs/Pro/Measure_GuangDong_Cloud.dpr
  30. BIN
      Dprs/Pro/Measure_GuangDong_Cloud.res
  31. 2 2
      Dprs/Pro/Measure_GuangDong_TZ.dof
  32. 13 1
      Dprs/Pro/Measure_GuangDong_TZ.dpr
  33. BIN
      Dprs/Pro/Measure_GuangDong_TZ.res
  34. 2 2
      Dprs/Pro/Measure_TZ.dof
  35. 13 1
      Dprs/Pro/Measure_TZ.dpr
  36. BIN
      Dprs/Pro/Measure_TZ.res
  37. 2 2
      Dprs/Trail/Measure.dof
  38. 13 1
      Dprs/Trail/Measure.dpr
  39. BIN
      Dprs/Trail/Measure.res
  40. 2 2
      Dprs/Trail/Measure_GuangDong.dof
  41. 13 1
      Dprs/Trail/Measure_GuangDong.dpr
  42. BIN
      Dprs/Trail/Measure_GuangDong.res
  43. 2 2
      Forms/BGLSelectFrm.pas
  44. 44 24
      Forms/BatchInsertBillsFrm.dfm
  45. 38 3
      Forms/BatchInsertBillsFrm.pas
  46. 77 1
      Forms/MainFrm.dfm
  47. 82 2
      Forms/MainFrm.pas
  48. 187 105
      Forms/ProjectPropertiesFrm.dfm
  49. 12 0
      Forms/ProjectPropertiesFrm.pas
  50. 1 1
      Forms/ReportsFrm.dfm
  51. 3 1
      Forms/ReportsFrm.pas
  52. 1 1
      Forms/SignOnlineReportsFrm.pas
  53. 3 0
      Frames/BGLFme.dfm
  54. 56 1
      Frames/BGLFme.pas
  55. 50 11
      Frames/BillsCompileFme.dfm
  56. 24 1
      Frames/BillsCompileFme.pas
  57. 630 3
      Frames/BillsGatherFme.dfm
  58. 33 4
      Frames/BillsGatherFme.pas
  59. 41 2
      Frames/BillsMeasureFme.dfm
  60. 33 2
      Frames/BillsMeasureFme.pas
  61. 3 1
      Frames/OtherMeasureFme.pas
  62. 54 3
      Frames/ProjectFme.pas
  63. 9 1
      Frames/ZJJLFme.dfm
  64. 52 13
      Frames/ZJJLFme.pas
  65. 276 0
      SubTenderGather/stgExcelExport.pas
  66. 429 0
      SubTenderGather/stgGather.pas
  67. 738 0
      SubTenderGather/stgGatherCacheData.pas
  68. 137 0
      SubTenderGather/stgGatherControl.pas
  69. 304 0
      SubTenderGather/stgGatherDm.dfm
  70. 281 0
      SubTenderGather/stgGatherDm.pas
  71. 25 0
      SubTenderGather/stgGatherUtils.pas
  72. 665 0
      SubTenderGather/stgResultFrm.dfm
  73. 190 0
      SubTenderGather/stgResultFrm.pas
  74. 258 0
      SubTenderGather/stgSelectFileFrm.dfm
  75. 320 0
      SubTenderGather/stgSelectFileFrm.pas
  76. 214 0
      SubTenderGather/stgSubGatherFile.pas
  77. 68 0
      SubTenderGather/stgSubGatherFileDm.dfm
  78. 36 0
      SubTenderGather/stgSubGatherFileDm.pas
  79. 30 0
      SubTenderGather/stgTables.pas
  80. 2 2
      Units/CacheTree.pas
  81. 7 1
      Units/CalcDecimal.pas
  82. 112 4
      Units/ColVisibleManager.pas
  83. 22 0
      Units/ConfigDoc.pas
  84. 1 1
      Units/Connections.pas
  85. 34 8
      Units/DataBaseTables.pas
  86. 1 1
      Units/DetailExcelImport.pas
  87. 15 7
      Units/GclBillsGatherModel.pas
  88. 1 1
      Units/MCacheTree.pas
  89. 271 0
      Units/MeasureGatherZJJL.pas
  90. 13 1
      Units/ProjectCommands.pas
  91. 139 30
      Units/ProjectData.pas
  92. 20 0
      Units/ProjectProperty.pas
  93. 1 0
      Units/UpdateDataBase.pas
  94. 22 2
      Units/UtilMethods.pas
  95. 6 0
      Units/mDataRecord.pas

+ 13 - 0
DataModules/BGLDm.dfm

@@ -61,12 +61,19 @@ object BGLData: TBGLData
       FieldName = 'BGLType'
       Size = 10
     end
+    object cdsBGLIsCloud: TBooleanField
+      FieldName = 'IsCloud'
+    end
+    object cdsBGLWebID: TIntegerField
+      FieldName = 'WebID'
+    end
   end
   object cdsBGLView: TClientDataSet
     Aggregates = <>
     Params = <>
     BeforePost = cdsBGLViewBeforePost
     BeforeDelete = cdsBGLViewBeforeDelete
+    AfterScroll = cdsBGLViewAfterScroll
     OnNewRecord = cdsBGLViewNewRecord
     Left = 96
     Top = 128
@@ -111,6 +118,12 @@ object BGLData: TBGLData
       FieldName = 'BGLType'
       Size = 10
     end
+    object cdsBGLViewIsCloud: TBooleanField
+      FieldName = 'IsCloud'
+    end
+    object cdsBGLViewWebID: TIntegerField
+      FieldName = 'WebID'
+    end
   end
   object dsBGL: TDataSource
     DataSet = cdsBGLView

+ 135 - 1
DataModules/BGLDm.pas

@@ -7,6 +7,8 @@ uses
   sdDB;
 
 type
+  TAfterCurrentBGLChanged = procedure of object;
+
   TBGLSelectInfo = class(TObject)
   private
     FB_Code: string;
@@ -96,6 +98,10 @@ type
     cdsBGBillsViewQuantity: TFloatField;
     cdsBGBillsViewTotalPrice: TFloatField;
     cdsBGBillsViewUsedQuantity: TFloatField;
+    cdsBGLIsCloud: TBooleanField;
+    cdsBGLWebID: TIntegerField;
+    cdsBGLViewIsCloud: TBooleanField;
+    cdsBGLViewWebID: TIntegerField;
     procedure cdsBGBillsViewAfterInsert(DataSet: TDataSet);
     procedure cdsBGBillsViewAfterPost(DataSet: TDataSet);
     procedure cdsBGBillsViewQuantityChange(Sender: TField);
@@ -110,8 +116,10 @@ type
     procedure cdsBGBillsViewPriceSetText(Sender: TField;
       const Text: String);
     procedure cdsBGLViewCodeChange(Sender: TField);
+    procedure cdsBGLViewAfterScroll(DataSet: TDataSet);
   private
     FProjectData: TObject;
+    FAfterCurrentBGLChanged: TAfterCurrentBGLChanged;
 
     procedure GatherBGLTotalPrice(ABGLID: Integer);
     procedure UpdateBGLTotalPrice(ABGLID: Integer; ADiffer: Double);
@@ -134,20 +142,26 @@ type
     procedure Close;
     procedure Save;
 
+    function GetBGLCanEdit(ASerialNo: Integer): Boolean;
+
     function AllBGLTotalPrice: Double;
 
+    function AllCloudBGLWebID: string;
+    procedure LoadCloudBGL(const ABGLs: string);
+
     procedure AddBGL(const sCode: string);
     procedure ApplyBGL(AOrgBGL, ANewBGL: TBGLSelectInfo); overload;
 
     procedure BatchWritePos_Reason;
 
     property ProjectData: TObject read FProjectData;
+    property AfterCurrentBGLChanged: TAfterCurrentBGLChanged read FAfterCurrentBGLChanged write FAfterCurrentBGLChanged;
   end;
 
 implementation
 
 uses
-  ZhAPI, Math, ProjectData, BillsDm, Variants, UtilMethods;
+  ZhAPI, Math, ProjectData, BillsDm, Variants, UtilMethods, superobject;
 
 {$R *.dfm}
 
@@ -426,6 +440,14 @@ var
   iIncrement: Integer;
   sNewCode: string;
 begin
+  if cdsBGLViewIsCloud.AsBoolean then
+  begin
+    cdsBGLViewCode.Tag := 0;
+    WarningMessage('当前变更令不允许编辑。');
+    DataSet.Cancel;
+    Abort;
+  end;
+
   // 变更令号不可为空
   if cdsBGLViewCode.AsString = '' then
   begin
@@ -486,6 +508,8 @@ procedure TBGLData.cdsBGLViewBeforeDelete(DataSet: TDataSet);
 begin
   if CheckBGLUsed(cdsBGLViewID.AsInteger) then
     raise Exception.Create('变更令下变更清单已被应用到清单,不可删除!');
+  if cdsBGLViewIsCloud.AsBoolean then
+    raise Exception.Create('云端获取的变更令不允许删除!');
   DeleteBGBills(cdsBGLViewID.AsInteger);
 end;
 
@@ -511,6 +535,8 @@ procedure TBGLData.cdsBGBillsViewBeforeDelete(DataSet: TDataSet);
 begin
   if cdsBGBillsViewUsedQuantity.AsFloat <> 0 then
     raise Exception.Create('变更清单已被应用至清单,不可删除!');
+  if cdsBGLViewIsCloud.AsBoolean then
+    raise Exception.Create('云端获取的变更清单不允许删除!');
 end;
 
 function TBGLData.CheckBGLUsed(ABGID: Integer): Boolean;
@@ -652,4 +678,112 @@ begin
   end;
 end;
 
+function TBGLData.AllCloudBGLWebID: string;
+begin
+  Result := '';
+  cdsBGL.First;
+  while not cdsBGL.Eof do
+  begin
+   if cdsBGLIsCloud.AsBoolean then
+   begin
+    if Result = '' then
+      Result := IntToStr(cdsBGLWebID.AsInteger)
+    else
+      Result := Result + ',' + IntToStr(cdsBGLWebID.AsInteger);
+   end;
+   cdsBGL.Next;
+  end;
+end;
+
+procedure TBGLData.LoadCloudBGL(const ABGLs: string);
+
+  procedure AddCloudBGLBills(ABGLID: Integer; ABGBills: ISuperObject);
+  var
+    i, iNewID: Integer;
+    vJ: ISuperObject;
+  begin
+    for i := 0 to ABGBills.AsArray.Length - 1 do
+    begin
+      iNewID := GetNewIDOfIndex(cdsBGBills);
+      vJ := ABGBills.AsArray.O[i];
+      cdsBGBills.Append;
+      cdsBGBillsID.AsInteger := iNewID;
+      cdsBGBillsBGID.AsInteger := ABGLID;
+      cdsBGBillsB_Code.AsString := vJ.S['lnum'];
+      cdsBGBillsName.AsString := vJ.S['lname'];
+      cdsBGBillsUnits.AsString := vJ.S['unit'];
+      cdsBGBillsPrice.AsFloat := vJ.D['unitprice'];
+      cdsBGBillsQuantity.AsFloat := vJ.D['samount'];
+      cdsBGBillsTotalPrice.AsFloat := TotalPriceRoundTo(cdsBGBillsPrice.AsFloat * cdsBGBillsQuantity.AsFloat);
+      cdsBGBills.Post;
+      UpdateBGLTotalPrice(ABGLID, cdsBGBillsTotalPrice.AsFloat);
+    end;
+  end;
+
+  procedure AddCloudBGL(ABGL: ISuperObject);
+  var
+    iNewID, iCreatePhaseID: Integer;
+    vBGBills: ISuperObject;
+  begin
+    iNewID := GetNewIDOfIndex(cdsBGL);
+    iCreatePhaseID := TProjectData(FProjectData).PhaseIndex;
+    cdsBGL.Append;
+    cdsBGLID.AsInteger := iNewID;
+    cdsBGLCode.AsString := ABGL.S['pnum'];
+    cdsBGLName.AsString := ABGL.S['pname'];
+    cdsBGLPos_Reason.AsString := ABGL.S['description'];
+    cdsBGLDirection.AsString := ABGL.S['basis'];
+    cdsBGLDrawingCode.AsString := ABGL.S['cnum'];
+    cdsBGLApprovalCode.AsString := ABGL.S['bnum'];
+    cdsBGLCreatePhaseID.AsInteger := iCreatePhaseID;
+    cdsBGLBGLType.AsString := ABGL.S['changeNature'];
+    cdsBGLIsCloud.AsBoolean := True;
+    cdsBGLWebID.AsInteger := ABGL.I['cid'];
+    cdsBGL.Post;
+    AddCloudBGLBills(iNewID, ABGL.O['changeBills']);
+  end;
+
+var
+  vJ: ISuperObject;
+  i: Integer;
+begin
+  vJ := SO(ABGLs);
+  try
+    if not Assigned(vJ.AsArray) then Exit;
+    for i := 0 to vJ.AsArray.Length - 1 do
+      AddCloudBGL(vJ.AsArray.O[i]);
+  finally
+    vJ := nil;
+  end;
+end;
+
+function TBGLData.GetBGLCanEdit(ASerialNo: Integer): Boolean;
+var
+  i: Integer;
+  bk: TBookmark;
+begin
+  cdsBGLView.DisableControls;
+  bk := cdsBGLView.GetBookmark;
+  cdsBGLView.First;
+  i := 0;
+  while (i < ASerialNo) and not cdsBGLView.Eof do
+  begin
+    cdsBGLView.Next;
+    Inc(i);
+  end;
+  if i = ASerialNo then
+    Result := not cdsBGLViewIsCloud.AsBoolean
+  else
+    Result := False;
+  cdsBGLView.GotoBookmark(bk);
+  cdsBGLView.FreeBookmark(bk);
+  cdsBGLView.EnableControls;
+end;
+
+procedure TBGLData.cdsBGLViewAfterScroll(DataSet: TDataSet);
+begin
+  if Assigned(FAfterCurrentBGLChanged) then
+    FAfterCurrentBGLChanged;
+end;
+
 end.

+ 6 - 0
DataModules/BillsCompileDm.dfm

@@ -94,6 +94,12 @@ object BillsCompileData: TBillsCompileData
       end
       item
         FieldName = 'ChapterParentID'
+      end
+      item
+        FieldName = 'ApprovalCode'
+      end
+      item
+        FieldName = 'IsGatherZJJL'
       end>
     AfterAddRecord = sdvBillsCompileAfterAddRecord
     BeforeValueChange = sdvBillsCompileBeforeValueChange

+ 93 - 1
DataModules/BillsCompileDm.pas

@@ -6,7 +6,9 @@ uses
   BillsDm, StandardBillsFme,
   SysUtils, Classes, sdDB, BillsTree, sdIDTree, DB;
 
-type
+type   
+  TRefreshGridRowEvent = procedure (ARowIndex: Integer) of object;
+  
   TBillsCompileData = class(TDataModule)
     sdvBillsCompile: TsdDataView;
     procedure sdvBillsCompileGetText(var Text: String;
@@ -28,6 +30,7 @@ type
     FBillsCompileTree: TCompileBillsIDTree;
 
     FOnRecChange: TRecChangeEvent;
+    FRefreshRow: TRefreshGridRowEvent;
 
     function GatherChildrenOrg(ANode: TsdIDTreeNode): Double;
     procedure UpdateRecordOrg(ABillsID: Integer; ATotalPrice: Double);
@@ -96,6 +99,7 @@ type
     property Active: Boolean read GetActive;
 
     property OnRecChange: TRecChangeEvent read FOnRecChange write SetOnRecChange;
+    property RefreshRow: TRefreshGridRowEvent read FRefreshRow write FRefreshRow;
   end;
 
 implementation
@@ -294,6 +298,68 @@ end;
 
 procedure TBillsCompileData.sdvBillsCompileBeforeValueChange(
   AValue: TsdValue; const NewValue: Variant; var Allow: Boolean);
+  
+  function CheckParentExist(ANode: TBillsIDTreeNode): Boolean;
+  var
+    vParent: TBillsIDTreeNode;
+  begin
+    Result := False;
+    vParent := TBillsIDTreeNode(ANode.Parent);
+    while Assigned(vParent) and not Result do
+    begin
+      if vParent.Rec.IsGatherZJJL.AsBoolean then
+        Result := True;
+      vParent := TBillsIDTreeNode(vParent.Parent);
+    end;
+  end;
+
+  procedure CancelParentCheck(ANode: TBillsIDTreeNode);
+  var
+    vParent: TBillsIDTreeNode;
+  begin
+    vParent := TBillsIDTreeNode(ANode.Parent);
+    while Assigned(vParent) do
+    begin
+      if vParent.Rec.IsGatherZJJL.AsBoolean then
+        vParent.Rec.IsGatherZJJL.AsBoolean := False;
+      vParent := TBillsIDTreeNode(vParent.Parent);
+    end;
+  end;
+
+  function CheckChildrenExist(ANode: TBillsIDTreeNode): Boolean;
+  var
+    iChild: Integer;
+    vChild: TBillsIDTreeNode;
+  begin
+    Result := False;
+    for iChild := 0 to ANode.ChildCount - 1 do
+    begin
+      vChild := TBillsIDTreeNode(ANode.ChildNodes[iChild]);
+      if vChild.Rec.IsGatherZJJL.AsBoolean or CheckChildrenExist(vChild) then
+      begin
+        Result := True;
+        Break;
+      end;
+    end;
+  end;
+
+  procedure CancelChildrenCheck(ANode: TBillsIDTreeNode);
+  var
+    iChild: Integer;
+    vChild: TBillsIDTreeNode;
+  begin
+    for iChild := 0 to ANode.ChildCount - 1 do
+    begin
+      vChild := TBillsIDTreeNode(ANode.ChildNodes[iChild]);
+      if vChild.Rec.IsGatherZJJL.AsBoolean then
+        vChild.Rec.IsGatherZJJL.AsBoolean := False
+      else
+        CancelChildrenCheck(vChild);
+    end;
+  end;
+
+var
+  vNode: TBillsIDTreeNode;
 begin
   if SameText(AValue.FieldName, 'OrgQuantity') or
       SameText(AValue.FieldName, 'MisQuantity') or
@@ -306,6 +372,32 @@ begin
     TBillsRecord(AValue.Owner).CacheOrgTP := AValue.Owner.ValueByName('OrgTotalPrice').AsFloat;
     TBillsRecord(AValue.Owner).CacheMisTP := AValue.Owner.ValueByName('MisTotalPrice').AsFloat;
     TBillsRecord(AValue.Owner).CacheOthTP := AValue.Owner.ValueByName('OthTotalPrice').AsFloat;
+  end
+  else if SameText(AValue.FieldName, 'IsGatherZJJL') then
+  begin
+    Allow := (TProjectData(FProjectData).ProjProperties.PhaseCount = 0) or TProjectData(FProjectData).CanUnlockInfo;
+    vNode := TBillsIDTreeNode(BillsCompileTree.FindNode(AValue.Owner.ValueByName('ID').AsInteger));
+    if Allow then
+    begin
+      if CheckParentExist(vNode) then
+      begin
+        if QuestMessage('父项已勾选,继续将取消父项勾选。') then
+          CancelParentCheck(vNode)
+        else
+          Allow := False;
+      end
+      else if CheckChildrenExist(vNode) then
+      begin
+        if QuestMessage('子项已勾选,继续将取消子项勾选。') then
+          CancelChildrenCheck(vNode)
+        else
+          Allow := False;
+      end;
+    end
+    else
+      WarningMessage('开始计量后,计量汇总列不可编辑,如需修改,请先解锁。');
+    if not Allow and Assigned(FRefreshRow) then
+      RefreshRow(vNode.MajorIndex);
   end;
 end;
 

+ 8 - 1
DataModules/BillsDm.dfm

@@ -264,6 +264,13 @@ object BillsData: TBillsData
       6502000001044E616D65060D425F436F646543686170746572094669656C644E
       616D65060D425F436F6465436861707465720844617461547970650203084461
       746153697A6502040549734B6579080F4E65656450726F636573734E616D6509
-      09507265636973696F6E02000453697A6502000000}
+      09507265636973696F6E02000453697A6502000001044E616D65060C41707072
+      6F76616C436F6465094669656C644E616D65060C417070726F76616C436F6465
+      0844617461547970650218084461746153697A6502320549734B6579080F4E65
+      656450726F636573734E616D650909507265636973696F6E02000453697A6502
+      000001044E616D65060C49734761746865725A4A4A4C094669656C644E616D65
+      060C49734761746865725A4A4A4C084461746154797065020508446174615369
+      7A6502010549734B6579080F4E65656450726F636573734E616D650909507265
+      636973696F6E02000453697A6502000000}
   end
 end

+ 31 - 1
DataModules/BillsGatherDm.pas

@@ -36,6 +36,7 @@ type
     destructor Destroy; override;
 
     procedure RefreshBills;
+    function GetAllBillsJson: string;
 
     property ProjectData: TObject read FProjectData;
     property MainBillsTree: TsdIDTree read GetMainBillsTree;
@@ -44,7 +45,7 @@ type
 implementation
 
 uses
-  ProjectData, PhaseData, StageDm, BillsDm, UtilMethods,
+  ProjectData, PhaseData, StageDm, BillsDm, UtilMethods, superobject,
   ZhAPI, BillsCompileDm, DealBillsDm, BGLDm, BillsTree, BillsMeasureDm;
 
 {$R *.dfm}
@@ -399,4 +400,33 @@ begin
     Text := '';
 end;
 
+function TBillsGatherData.GetAllBillsJson: string;
+
+  function GetBillsJson(Rec: TsdDataRecord): ISuperObject;
+  begin
+    Result := SO;
+    Result.S['lnum'] := Rec.ValueByName('B_Code').AsString;
+    Result.S['lname'] := Rec.ValueByName('Name').AsString;
+    Result.S['unit'] := Rec.ValueByName('Units').AsString;
+    Result.D['unitprice'] := Rec.ValueByName('Price').AsFloat;
+    Result.D['amount'] := Rec.ValueByName('DealQuantity').AsFloat;
+  end;
+
+var
+  vJa, vJbills: ISuperObject;
+  i: Integer;
+  Rec: TsdDataRecord;
+begin
+  vJa := SA([]);
+  try
+    for i := 0 to sddGclBills.RecordCount - 1 do
+    begin
+      Rec := sddGclBills.Records[i];
+      vJa.AsArray.Add(GetBillsJson(Rec));
+    end;
+  finally
+    Result := vJa.AsJSon;
+  end;
+end;
+
 end.

+ 7 - 0
DataModules/BillsMeasureDm.dfm

@@ -220,8 +220,15 @@ object BillsMeasureData: TBillsMeasureData
       end
       item
         FieldName = 'PM_AddTotalPrice'
+      end
+      item
+        FieldName = 'ApprovalCode'
+      end
+      item
+        FieldName = 'IsGatherZJJL'
       end>
     AfterAddRecord = sdvBillsMeasureAfterAddRecord
+    BeforeValueChange = sdvBillsMeasureBeforeValueChange
     AfterValueChanged = sdvBillsMeasureAfterValueChanged
     AfterClose = sdvBillsMeasureAfterClose
     AfterOpen = sdvBillsMeasureAfterOpen

+ 135 - 6
DataModules/BillsMeasureDm.pas

@@ -4,7 +4,7 @@ interface
 
 uses
   BillsDm, BillsTree, FormulaCalc, sdIDTree, StageDm,
-  SysUtils, Classes, sdDB, DB;
+  SysUtils, Classes, sdDB, DB, CalcDecimal;
 
 type 
   TLocateZJJLEvent = procedure (ABillsID: Integer) of object;
@@ -24,6 +24,8 @@ type
     procedure sdvBillsMeasureAfterClose(Sender: TObject);
     procedure sdvBillsMeasureAfterValueChanged(AValue: TsdValue);
     procedure sdvBillsMeasureCurrentChanged(ARecord: TsdDataRecord);
+    procedure sdvBillsMeasureBeforeValueChange(AValue: TsdValue;
+      const NewValue: Variant; var Allow: Boolean);
   private
     FProjectData: TObject;
     FBillsData: TBillsData;
@@ -46,6 +48,7 @@ type
 
     function GetStageData: TStageData;
     procedure SetOnRecChange(const Value: TRecChangeEvent);
+    function GetDecimal: TCalcDecimal;
   public
     constructor Create(AProjectData: TObject);
     destructor Destroy; override;
@@ -54,6 +57,7 @@ type
     procedure Close;
     procedure ReConnectTree;
 
+    function CheckNodeGatherCalc(ANode: TMeasureBillsIDTreeNode): Boolean;
     procedure CalculateAll;
 
     procedure ResetPhaseStageLink;
@@ -79,6 +83,7 @@ type
     property ProjectData: TObject read FProjectData;
     property BillsData: TBillsData read FBillsData;
     property BillsMeasureTree: TMeasureBillsIDTree read FBillsMeasureTree;
+    property Decimal: TCalcDecimal read GetDecimal;
 
     property StageData: TStageData read GetStageData;
     property ShowParentData: Boolean read FShowParentData write FShowParentData;
@@ -89,7 +94,7 @@ implementation
 
 uses
   ProjectData, PhaseData, Math, ZhAPI, BillsCommand, BGLSelectFrm,
-  BGLDm, UtilMethods, mDataRecord, ConstUnit, Variants;
+  BGLDm, UtilMethods, mDataRecord, ConstUnit, Variants, ConditionalDefines;
 
 {$R *.dfm}
 
@@ -434,7 +439,7 @@ begin
   if not CheckValidData then
     Allow := False;
   if not Allow then Exit;
-  
+
   vNode := TBillsIDTreeNode(BillsMeasureTree.FindNode(GetBillsID));
 
   CheckLockedData;
@@ -923,8 +928,8 @@ begin
   with ANode.Rec do
   begin
     fDividend := ValueByName('AddGatherTotalPrice').AsFloat;
-    fDivisor := ValueByName('TotalPrice').AsFloat + ValueByName('AddQcTotalPrice').AsFloat
-        + ValueByName('AddPcTotalPrice').AsFloat;
+    fDivisor := CommonCalcRoundTo(ValueByName('TotalPrice').AsFloat + ValueByName('AddQcTotalPrice').AsFloat
+        + ValueByName('AddPcTotalPrice').AsFloat);
     if fDivisor <> 0 then
       ValueByName('AddCompleteRate').AsFloat := AdvRoundTo(fDividend/fDivisor*100)
     else
@@ -1038,7 +1043,7 @@ function TBillsMeasureData.FindNodeWithZJJL(ANode: TsdIDTreeNode): TsdIDTreeNode
 
   function CheckNodeHasZJJL(ANode: TsdIDTreeNode): Boolean;
   begin
-    Result := Assigned(TProjectData(FProjectData).PhaseData.ZJJLData.sddZJJL.Locate('BillsID', ANode.ID));
+    Result := Assigned(TProjectData(FProjectData).PhaseData.ZJJLData.FindZJJLRecord(ANode.ID));
   end;
 
   function FindChildWithZJJL(ANode: TsdIDTreeNode): TsdIDTreeNode;
@@ -1085,4 +1090,128 @@ begin
     Result := ANode;
 end;
 
+procedure TBillsMeasureData.sdvBillsMeasureBeforeValueChange(
+  AValue: TsdValue; const NewValue: Variant; var Allow: Boolean);
+
+   function CheckParentExist(ANode: TBillsIDTreeNode): Boolean;
+   var
+     vParent: TBillsIDTreeNode;
+   begin
+     Result := False;
+     vParent := TBillsIDTreeNode(ANode.Parent);
+     while Assigned(vParent) and not Result do
+     begin
+       if vParent.Rec.IsGatherZJJL.AsBoolean then
+         Result := True;
+       vParent := TBillsIDTreeNode(vParent.Parent);
+     end;
+   end;
+
+   procedure CancelParentCheck(ANode: TBillsIDTreeNode);
+   var
+     vParent: TBillsIDTreeNode;
+   begin
+     vParent := TBillsIDTreeNode(ANode.Parent);
+     while Assigned(vParent) do
+     begin
+       if vParent.Rec.IsGatherZJJL.AsBoolean then
+         vParent.Rec.IsGatherZJJL.AsBoolean := False;
+       vParent := TBillsIDTreeNode(vParent.Parent);
+     end;
+   end;
+
+   function CheckChildrenExist(ANode: TBillsIDTreeNode): Boolean;
+   var
+     iChild: Integer;
+     vChild: TBillsIDTreeNode;
+   begin
+     Result := False;
+     for iChild := 0 to ANode.ChildCount - 1 do
+     begin
+       vChild := TBillsIDTreeNode(ANode.ChildNodes[iChild]);
+       if vChild.Rec.IsGatherZJJL.AsBoolean or CheckChildrenExist(vChild) then
+       begin
+         Result := True;
+         Break;
+       end;
+     end;
+   end;
+
+   procedure CancelChildrenCheck(ANode: TBillsIDTreeNode);
+   var
+     iChild: Integer;
+     vChild: TBillsIDTreeNode;
+   begin
+     for iChild := 0 to ANode.ChildCount - 1 do
+     begin
+       vChild := TBillsIDTreeNode(ANode.ChildNodes[iChild]);
+       if vChild.Rec.IsGatherZJJL.AsBoolean then
+         vChild.Rec.IsGatherZJJL.AsBoolean := False
+       else
+         CancelChildrenCheck(vChild);
+     end;
+   end;
+
+var
+  vNode: TBillsIDTreeNode;
+begin
+  vNode := TBillsIDTreeNode(BillsMeasureTree.FindNode(AValue.Owner.ValueByName('ID').AsInteger));
+  if SameText(AValue.FieldName, 'IsGatherZJJL') and NewValue then
+  begin
+    if CheckParentExist(vNode) then
+    begin
+      if QuestMessage('父项已勾选,继续将取消父项勾选。') then
+        CancelParentCheck(vNode)
+      else
+        Allow := False;
+    end
+    else if CheckChildrenExist(vNode) then
+    begin
+      if QuestMessage('子项已勾选,继续将取消子项勾选。') then
+        CancelChildrenCheck(vNode)
+      else
+        Allow := False;
+    end;
+  end;
+end;
+
+function TBillsMeasureData.CheckNodeGatherCalc(
+  ANode: TMeasureBillsIDTreeNode): Boolean;
+var
+  fLeafSumDeal, fLeafSumQc, fLeafSumGather: Double;
+  i, iCount: Integer;
+  vChild: TMeasureBillsIDTreeNode;
+begin
+  if Assigned(ANode.StageRec) then
+  begin
+    fLeafSumDeal := 0;
+    fLeafSumQc := 0;
+    fLeafSumGather := 0;
+    iCount := ANode.PosterityCount;
+    i := 0;
+    vChild := TMeasureBillsIDTreeNode(ANode.NextNode);
+    while i < iCount do
+    begin
+      if not vChild.HasChildren and Assigned(vChild.StageRec) then
+      begin
+        fLeafSumDeal := fLeafSumDeal + vChild.StageRec.DealTotalPrice.AsFloat;
+        fLeafSumQc := fLeafSumQc + vChild.StageRec.QcTotalPrice.AsFloat;
+        fLeafSumGather := fLeafSumGather + vChild.StageRec.GatherTotalPrice.AsFloat;
+      end;
+      vChild := TMeasureBillsIDTreeNode(vChild.NextNode);
+      Inc(i);
+    end;
+    Result := Decimal.TotalPrice.CheckSameNum(fLeafSumDeal, ANode.StageRec.DealTotalPrice.AsFloat) and
+              Decimal.TotalPrice.CheckSameNum(fLeafSumQc, ANode.StageRec.QcTotalPrice.AsFloat) and
+              Decimal.TotalPrice.CheckSameNum(fLeafSumGather, ANode.StageRec.GatherTotalPrice.AsFloat);
+  end
+  else
+    Result := True;
+end;
+
+function TBillsMeasureData.GetDecimal: TCalcDecimal;
+begin
+  Result := TProjectData(FProjectData).ProjProperties.DecimalManager.Common;
+end;
+
 end.

+ 23 - 18
DataModules/DealBillsDm.dfm

@@ -18,24 +18,29 @@ object DealBillsData: TDealBillsData
     FieldListData = {
       0101044E616D6506024944094669656C644E616D650602494408446174615479
       70650203084461746153697A6502040549734B6579080F4E65656450726F6365
-      73734E616D65090001044E616D650606425F436F6465094669656C644E616D65
-      0606425F436F64650844617461547970650201084461746153697A6503FF0005
-      49734B6579080F4E65656450726F636573734E616D65090001044E616D650604
-      4E616D65094669656C644E616D6506044E616D65084461746154797065021808
-      4461746153697A6503FF000549734B6579080F4E65656450726F636573734E61
-      6D65090001044E616D650605556E697473094669656C644E616D650605556E69
-      74730844617461547970650218084461746153697A6503FF000549734B657908
-      0F4E65656450726F636573734E616D65090001044E616D650605507269636509
-      4669656C644E616D650605507269636508446174615479706502060844617461
-      53697A6502080549734B6579080F4E65656450726F636573734E616D65090001
-      044E616D6506085175616E74697479094669656C644E616D6506085175616E74
-      6974790844617461547970650206084461746153697A6502080549734B657908
-      0F4E65656450726F636573734E616D65090001044E616D65060A546F74616C50
-      72696365094669656C644E616D65060A546F74616C5072696365084461746154
-      7970650206084461746153697A6502080549734B6579080F4E65656450726F63
-      6573734E616D65090001044E616D650609496E646578436F6465094669656C64
-      4E616D650609496E646578436F64650844617461547970650201084461746153
-      697A6502320549734B6579080F4E65656450726F636573734E616D65090000}
+      73734E616D650909507265636973696F6E02000453697A6502000001044E616D
+      650606425F436F6465094669656C644E616D650606425F436F64650844617461
+      547970650201084461746153697A6503FF000549734B6579080F4E6565645072
+      6F636573734E616D650909507265636973696F6E02000453697A650200000104
+      4E616D6506044E616D65094669656C644E616D6506044E616D65084461746154
+      7970650218084461746153697A6503FF000549734B6579080F4E65656450726F
+      636573734E616D650909507265636973696F6E02000453697A6502000001044E
+      616D650605556E697473094669656C644E616D650605556E6974730844617461
+      547970650218084461746153697A6503FF000549734B6579080F4E6565645072
+      6F636573734E616D650909507265636973696F6E02000453697A650200000104
+      4E616D6506055072696365094669656C644E616D650605507269636508446174
+      61547970650206084461746153697A6502080549734B6579080F4E6565645072
+      6F636573734E616D650909507265636973696F6E02000453697A650200000104
+      4E616D6506085175616E74697479094669656C644E616D6506085175616E7469
+      74790844617461547970650206084461746153697A6502080549734B6579080F
+      4E65656450726F636573734E616D650909507265636973696F6E02000453697A
+      6502000001044E616D65060A546F74616C5072696365094669656C644E616D65
+      060A546F74616C50726963650844617461547970650206084461746153697A65
+      02080549734B6579080F4E65656450726F636573734E616D6509095072656369
+      73696F6E02000453697A6502000001044E616D650609496E646578436F646509
+      4669656C644E616D650609496E646578436F6465084461746154797065020108
+      4461746153697A6502320549734B6579080F4E65656450726F636573734E616D
+      650909507265636973696F6E02000453697A6502000000}
   end
   object sdvDealBills: TsdDataView
     Active = False

+ 26 - 1
DataModules/DealBillsDm.pas

@@ -31,6 +31,7 @@ type
     procedure EnableEvent;
 
     function DealRecord(const AB_Code: string): TsdDataRecord;
+    function GetAllDealBillsJson: string;
 
     property ProjectData: TObject read FProjectData;
   end;
@@ -38,7 +39,7 @@ type
 implementation
 
 uses
-  UtilMethods;
+  UtilMethods, superobject;
 
 {$R *.dfm}
 
@@ -80,6 +81,30 @@ begin
   sddDealBills.BeforeAddRecord := sddDealBillsBeforeAddRecord;
 end;
 
+function TDealBillsData.GetAllDealBillsJson: string;
+var
+  vJa, vJbills: ISuperObject;
+  i: Integer;
+  Rec: TsdDataRecord;
+begin
+  vJa := SA([]);
+  try
+    for i := 0 to sddDealBills.RecordCount - 1 do
+    begin
+      Rec := sddDealBills.Records[i];
+      vJbills := SO;
+      vJbills.S['lnum'] := Rec.ValueByName('B_Code').AsString;
+      vJbills.S['lname'] := Rec.ValueByName('Name').AsString;
+      vJbills.S['unit'] := Rec.ValueByName('Units').AsString;
+      vJbills.D['unitprice'] := Rec.ValueByName('Price').AsFloat;
+      vJbills.D['amount'] := Rec.ValueByName('Quantity').AsFloat;
+      vJa.AsArray.Add(vJbills);
+    end;
+  finally
+    Result := vJa.AsJSon;
+  end;
+end;
+
 function TDealBillsData.GetNewID: Integer;
 var
   idx: TsdIndex;

+ 78 - 1
DataModules/ProjectManagerDm.pas

@@ -59,6 +59,8 @@ type
     procedure RestoreTender(AID: Integer);
     procedure RefreshSeedID;
 
+    procedure CalculateParentInfo(AID: Integer);
+
     function BackupPath(AProjectID: Integer): String;
     procedure AddOpenTenderBackup(AProjectID: Integer);
     procedure AddSaveTenderBackup(AProjectID: Integer);
@@ -69,7 +71,7 @@ type
 implementation
 
 uses
-  UtilMethods, UpdateDataBase, ProjectCommands, PHPWebDm, ConstUnit;
+  UtilMethods, UpdateDataBase, ProjectCommands, PHPWebDm, ConstUnit, Math;
 
 {$R *.dfm}
 
@@ -103,12 +105,16 @@ begin
 end;
 
 procedure TProjectManagerData.Delete;
+var
+  orgParentID: Integer;
 begin
   if HasProject then
   begin
+    orgParentID := FProjectsTree.Selected.ParentID;
     DeleteAttachmentFiles(FProjectsTree.Selected);
     DeleteAllTenderFiles(FProjectsTree.Selected);
     FProjectsTree.DeleteNode(FProjectsTree.Selected);
+    CalculateParentInfo(orgParentID);
     Save;
   end;
 end;
@@ -655,4 +661,75 @@ begin
   end;
 end;
 
+procedure TProjectManagerData.CalculateParentInfo(AID: Integer);
+
+  procedure ResetDigit(ANode: TsdIDTreeNode);
+  var
+    iChild, iCommonDigit, iDealPayDigit: Integer;
+    vChild: TsdIDTreeNode;
+  begin
+    iCommonDigit := 0;
+    iDealPayDigit := 0;
+    for iChild := 0 to ANode.ChildCount - 1 do
+    begin
+      vChild := ANode.ChildNodes[iChild];
+      iCommonDigit := Max(iCommonDigit, vChild.Rec.ValueByName('CommonDigit').AsInteger);
+      iDealPayDigit := Max(iDealPayDigit, vChild.Rec.ValueByName('DealPayDigit').AsInteger);
+    end;
+    ANode.Rec.ValueByName('CommonDigit').AsInteger := iCommonDigit;
+    ANode.Rec.ValueByName('DealPayDigit').AsInteger := iDealPayDigit;
+  end;
+
+  procedure ReCalculateInfo(ANode: TsdIDTreeNode);
+  var
+    fDeal, fDeal_BGL, fPhase, fEndDeal, fEndChange, fEnd, fPre, fPhasePay: Double;
+    iChild, iCommonDigit, iDealPayDigit: Integer;
+    vChild: TsdIDTreeNode;
+  begin
+    fDeal := 0;
+    fDeal_BGL := 0;
+    fPhase := 0;
+    fEndDeal := 0;
+    fEndChange := 0;
+    fEnd := 0;
+    fPre := 0;
+    fPhasePay := 0;
+    iCommonDigit := - ANode.Rec.ValueByName('CommonDigit').AsInteger;
+    iDealPayDigit := - ANode.Rec.ValueByName('DealPayDigit').AsInteger;
+    for iChild := 0 to ANode.ChildCount - 1 do
+    begin
+      vChild := ANode.ChildNodes[iChild];
+      fDeal := fDeal + vChild.Rec.ValueByName('DealTotalPrice').AsFloat;
+      fDeal_BGL := fDeal_BGL + vChild.Rec.ValueByName('Deal_BGLTotalPrice').AsFloat;
+      fPhase := fPhase + vChild.Rec.ValueByName('PhaseTotalPrice').AsFloat;
+      fEndDeal := fEndDeal + vChild.Rec.ValueByName('EndDealTotalPrice').AsFloat;
+      fEndChange := fEndChange + vChild.Rec.ValueByName('EndChangeTotalPrice').AsFloat;
+      fEnd := fEnd + vChild.Rec.ValueByName('EndTotalPrice').AsFloat;
+      fPre := fPre + vChild.Rec.ValueByName('PreTotalPrice').AsFloat;
+      fPhasePay := fPhasePay + vChild.Rec.ValueByName('PhasePay').AsFloat;
+    end;
+    ANode.Rec.ValueByName('DealTotalPrice').AsFloat := CommonRoundTo(fDeal, iCommonDigit);
+    ANode.Rec.ValueByName('Deal_BGLTotalPrice').AsFloat := CommonRoundTo(fDeal_BGL, iCommonDigit);
+    ANode.Rec.ValueByName('PhaseTotalPrice').AsFloat := CommonRoundTo(fPhase, iCommonDigit);
+    ANode.Rec.ValueByName('EndDealTotalPrice').AsFloat := CommonRoundTo(fEndDeal, iCommonDigit);
+    ANode.Rec.ValueByName('EndChangeTotalPrice').AsFloat := CommonRoundTo(fEndChange, iCommonDigit);
+    ANode.Rec.ValueByName('EndTotalPrice').AsFloat := CommonRoundTo(fEnd, iCommonDigit);
+    ANode.Rec.ValueByName('PreTotalPrice').AsFloat := CommonRoundTo(fPre, iCommonDigit);
+    ANode.Rec.ValueByName('PhasePay').AsFloat := CommonRoundTo(fPhasePay, iDealPayDigit);
+  end;
+
+var
+  vNode, vChild: TsdIDTreeNode;
+  iChild: Integer;
+begin
+  if AID = -1 then Exit;
+  vNode := ProjectsTree.FindNode(AID);
+  if (not Assigned(vNode)) or (vNode.Rec.ValueByName('Type').AsInteger = 1) then Exit;
+
+  ResetDigit(vNode);
+  ReCalculateInfo(vNode);
+
+  CalculateParentInfo(vNode.ParentID);
+end;
+
 end.

+ 2 - 2
DataModules/ReportMemoryDm/rmBillsGatherDm.pas

@@ -1153,7 +1153,7 @@ end;
 
 procedure TrmBillsGatherData.CalculateGatherData;
 begin
-  if GatherType in [bgtFinal08, bgtFinal16, bgtEstimate1, bgtG_Final04] then
+  if GatherType in [bgtFinal08, bgtFinal16, bgtEstimate, bgtEstimate1, bgtG_Final04] then
     FCacheTree.ReCalcGatherData;
   if GatherType in [bgtFinal07, bgtFinal11, bgtFinal19] then
     FGclList.ReCalcualteGatherNode;
@@ -1200,7 +1200,7 @@ begin
   WriteEstimateNode(TReportCacheNode(FCacheTree.FirstNode));
   if GatherType = bgtG_Final06_1 then
     ReWriteENodeDataAsGather(TReportCacheNode(FCacheTree.FirstNode), '土地征用及拆迁补偿费用合计');
-  if GatherType = bgtEstimate1 then
+  if GatherType in [bgtEstimate, bgtEstimate1] then
     WriteEstimateGatherNode;
 end;
 

+ 5 - 1
DataModules/ReportMemoryDm/rmGclBillsBGDm.pas

@@ -152,6 +152,10 @@ begin
       WriteFlowBills;
   finally
     ClearObjects(FGclList);
+    if FrmGatherType = rmgtGather then
+      cdsBills.IndexFieldNames := 'IndexCode'
+    else if FrmGatherType = rmgtFlow then
+      cdsBills.IndexFieldNames := 'SerialNo;IndexCode';
     cdsBills.EnableControls;
     Result := cdsBills;
   end;
@@ -461,7 +465,7 @@ var
 begin
   PhaseData := TPhaseData.Create(FProjectData);
   try
-    PhaseData.SimpleOpen(Format('%s\Phase%d.dat', [FProjectData.TempPath, APhaseIndex]));
+    PhaseData.SimpleOpen2(Format('%s\Phase%d.dat', [FProjectData.TempPath, APhaseIndex]));
     cdsBills.Append;
     cdsBillsName.AsString := Format('µÚ %d ÆÚ', [APhaseIndex]);
     cdsBillsSerialNo.AsInteger := APhaseIndex;

+ 6 - 3
DataModules/StageDm.pas

@@ -25,9 +25,6 @@ type
     FBeforeChangeQuantity: Double;
     FBeforeChangeTotalPrice: Double;
 
-    procedure BeforeBatchOperation;
-    procedure AfterBatchOperation;
-
     procedure UpdateParentRecord(ABillsID: Integer; ATotalPrice: Double; const AFieldName: string);
     procedure UpdateComplete(ABillsID: Integer; AQuantity, ATotalPrice: Double);
 
@@ -78,6 +75,9 @@ type
     procedure Open(AConnection: TADOConnection);
     procedure Save;
 
+    procedure BeforeBatchOperation;
+    procedure AfterBatchOperation;
+
     // 计算任一清单节点的价差金额,并增量汇总至父项
     procedure CalculatePriceMargin(ABillsID: Integer);
     // 计算材料调差节点
@@ -484,12 +484,15 @@ end;
 procedure TStageData.UpdateParentRecord(ABillsID: Integer;
   ATotalPrice: Double; const AFieldName: string);
 var
+  vNode: TMeasureBillsIDTreeNode;
   iParentID: Integer;
   Rec: TsdDataRecord;
 begin
   iParentID := MainBillsTree.FindNode(ABillsID).ParentID;
   if iParentID = -1 then Exit;
+  vNode := TMeasureBillsIDTreeNode(MainBillsTree.FindNode(iParentID));
   Rec := StageRecordWithAdd(iParentID);
+  vNode.StageRec := TStageRecord(Rec);
   Rec.ValueByName(AFieldName).AsFloat := TotalPriceRoundTo(
       Rec.ValueByName(AFieldName).AsFloat + ATotalPrice);
   Rec.ValueByName('End' + AFieldName).AsFloat := TotalPriceRoundTo(

+ 50 - 3
DataModules/ZJJLDm.dfm

@@ -3,7 +3,7 @@ object ZJJLData: TZJJLData
   Left = 704
   Top = 204
   Height = 241
-  Width = 269
+  Width = 283
   object sdpZJJL: TsdADOProvider
     TableName = 'ZJJL'
     Left = 42
@@ -62,7 +62,23 @@ object ZJJLData: TZJJLData
       73696F6E02000453697A6502000001044E616D65060B44726177696E67436F64
       65094669656C644E616D65060B44726177696E67436F64650844617461547970
       650218084461746153697A6502320549734B6579080F4E65656450726F636573
-      734E616D650909507265636973696F6E02000453697A6502000000}
+      734E616D650909507265636973696F6E02000453697A6502000001044E616D65
+      060D47617468657242696C6C734944094669656C644E616D65060D4761746865
+      7242696C6C7349440844617461547970650203084461746153697A6502040549
+      734B6579080F4E65656450726F636573734E616D650909507265636973696F6E
+      02000453697A6502000001044E616D650606425F436F6465094669656C644E61
+      6D650606425F436F64650844617461547970650218084461746153697A650232
+      0549734B6579080F4E65656450726F636573734E616D65090950726563697369
+      6F6E02000453697A6502000001044E616D6506044E616D65094669656C644E61
+      6D6506044E616D650844617461547970650218084461746153697A6503C80005
+      49734B6579080F4E65656450726F636573734E616D650909507265636973696F
+      6E02000453697A6502000001044E616D650605556E697473094669656C644E61
+      6D650605556E6974730844617461547970650218084461746153697A65021405
+      49734B6579080F4E65656450726F636573734E616D650909507265636973696F
+      6E02000453697A6502000001044E616D6506055072696365094669656C644E61
+      6D65060550726963650844617461547970650206084461746153697A65020805
+      49734B6579080F4E65656450726F636573734E616D650909507265636973696F
+      6E02000453697A6502000000}
   end
   object sdvZJJL: TsdDataView
     Active = False
@@ -110,6 +126,7 @@ object ZJJLData: TZJJLData
       end>
     AfterDeleteRecord = sdvZJJLAfterDeleteRecord
     BeforeValueChange = sdvZJJLBeforeValueChange
+    OnCurrentChanged = sdvZJJLCurrentChanged
     Left = 40
     Top = 144
   end
@@ -139,6 +156,36 @@ object ZJJLData: TZJJLData
       7A6502000001044E616D65060A4669656C6456616C7565094669656C644E616D
       65060A4669656C6456616C75650844617461547970650210084461746153697A
       650477EC00000549734B6579080F4E65656450726F636573734E616D65090950
-      7265636973696F6E02000453697A6502000000}
+      7265636973696F6E02000453697A6502000001044E616D650606425F436F6465
+      094669656C644E616D650606425F436F64650844617461547970650218084461
+      746153697A6502320549734B6579080F4E65656450726F636573734E616D6509
+      09507265636973696F6E02000453697A6502000001044E616D6506044E616D65
+      094669656C644E616D6506044E616D6508446174615479706502180844617461
+      53697A6503C8000549734B6579080F4E65656450726F636573734E616D650909
+      507265636973696F6E02000453697A6502000001044E616D650605556E697473
+      094669656C644E616D650605556E697473084461746154797065021808446174
+      6153697A6502140549734B6579080F4E65656450726F636573734E616D650909
+      507265636973696F6E02000453697A6502000001044E616D6506055072696365
+      094669656C644E616D6506055072696365084461746154797065020608446174
+      6153697A6502080549734B6579080F4E65656450726F636573734E616D650909
+      507265636973696F6E02000453697A6502000000}
+  end
+  object sdpZJJLDetail: TsdADOProvider
+    TableName = 'ZJJL_Detail'
+    Left = 200
+    Top = 16
+  end
+  object sddZJJLDetail: TsdDataSet
+    Active = False
+    Provider = sdpZJJLDetail
+    Left = 200
+    Top = 80
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D650909507265636973696F6E02000453697A6502000001044E616D
+      65060742696C6C734944094669656C644E616D65060742696C6C734944084461
+      7461547970650203084461746153697A6502040549734B6579080F4E65656450
+      726F636573734E616D650909507265636973696F6E02000453697A6502000000}
   end
 end

+ 245 - 35
DataModules/ZJJLDm.pas

@@ -3,12 +3,13 @@ unit ZJJLDm;
 interface
 
 uses
-  ZjGrid,
+  ZjGrid, MeasureGatherZJJL,
   SysUtils, Classes, DB, DBClient, ADODB, sdIDTree, sdDB, Provider,
   Windows, BillsTree, sdProvider, Variants;
 
 type
-  TZJJLType = (ztFx, ztGcl);
+  TZJJLType = (ztFx, ztGcl, ztGclGather); 
+  TRefreshDetailGridEvent = procedure of Object;
 
   TZJJLNode = class
   private
@@ -37,15 +38,20 @@ type
     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;
@@ -54,6 +60,7 @@ type
     procedure GenerateLastXmj(ANode: TsdIDTreeNode);
     procedure GenerateNode(ANode: TsdIDTreeNode);
 
+    function CheckLeafNodeMeasureExist(AID: Integer): Boolean;
     procedure GenerateLeafNode(ANode: TsdIDTreeNode);
     procedure GenerateNodeByB_Code(ANode: TsdIDTreeNode);
 
@@ -61,6 +68,7 @@ type
     procedure RestoreOrgData;
 
     procedure DeleteHistory(ABillsID, AType: Integer);
+    procedure DeleteGatherHistory(ARecord: TsdDataRecord);
 
     procedure DetailGridCellCanEdit(Sender: TObject; const ACoord: TPoint;
       var Allow: Boolean);
@@ -96,24 +104,30 @@ type
 
     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;
+  BillsCompileDm, BillsMeasureDm, mPegFilter, Math;
 
 {$R *.dfm}
 
@@ -151,6 +165,11 @@ begin
   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;
@@ -159,6 +178,7 @@ procedure TZJJLData.Save;
 begin
   sddZJJL.Save;
   sddHistory.Save;
+  sddZJJLDetail.Save;
 end;
 
 function TZJJLData.CheckLastXmj(AID: Integer): Boolean;
@@ -260,6 +280,7 @@ end;
 procedure TZJJLData.DeleteAll;
 begin
   sddZJJL.DeleteAll;
+  sddZJJLDetail.DeleteAll;
 end;
 
 procedure TZJJLData.RestoreOrgData;
@@ -372,37 +393,15 @@ begin
 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
+      CheckLeafNodeMeasureExist(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;
@@ -443,7 +442,7 @@ begin
   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('Code').AsString := GetFieldValue('Code', GetNewCode(FNewID));
   Rec.ValueByName('CertificateCode').AsString := GetFieldValue('CertificateCode', '');
   Rec.ValueByName('FormulaMemo').AsString := GetFieldValue('FormulaMemo', '');
   Rec.ValueByName('RelaFile').AsString := GetFieldValue('RelaFile', '');
@@ -457,6 +456,10 @@ begin
   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;
 
@@ -534,9 +537,12 @@ procedure TZJJLData.CheckZjjlVerison;
     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);
+      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;
 
@@ -679,16 +685,30 @@ procedure TZJJLData.SetHistory(const AFieldName, AValue: string;
 var
   HistoryRec: TsdDataRecord;
 begin
-  HistoryRec := sddHistory.FindKey('idxHistory', VarArrayOf([AZJJL_Rec.ValueByName('BillsID').AsInteger,
-    AZJJL_Rec.ValueByName('Type').AsInteger, AFieldName]));
+  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;
-    HistoryRec.ValueByName('BillsID').AsInteger := AZJJL_Rec.ValueByName('BillsID').AsInteger;
+    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;
@@ -725,7 +745,7 @@ procedure TZJJLData.sdvZJJLBeforeValueChange(AValue: TsdValue;
 var
   sNewValue: string;
 begin
-  if CheckFieldNeedHistory(AValue.FieldName) then
+  if CheckFieldNeedHistory(AValue.FieldName) and not TPhaseData(FPhaseData).StageDataReadOnly then
   begin
     sNewValue := VarToStrDef(NewValue, '');
     if sNewValue <> AValue.AsString then
@@ -735,7 +755,10 @@ end;
 
 procedure TZJJLData.sdvZJJLAfterDeleteRecord(ARecord: TsdDataRecord);
 begin
-  DeleteHistory(ARecord.ValueByName('BillsID').AsInteger, ARecord.ValueByName('Type').AsInteger);
+  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);
@@ -756,4 +779,191 @@ begin
   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.

+ 31 - 3
Dprs/PWFree/Measure_Cloud.dpr

@@ -222,20 +222,33 @@ uses
   RenameSignReportFrm in '..\..\Forms\RenameSignReportFrm.pas' {RenameSignReportForm},
   rmWeiWuZjjlGatherDm in '..\..\DataModules\ReportMemoryDm\rmWeiWuZjjlGatherDm.pas' {rmWeiWuZjjlGatherData: TDataModule},
   SetGuestFrm in '..\..\Forms\SetGuestFrm.pas' {SetGuestForm},
+  ReportManagerFrm in '..\..\Forms\ReportManagerFrm.pas',
+  ReportManagerDM in '..\..\DataModules\ReportManagerDM.pas' {Reports: TDataModule},
+  ReportHistoryFrm in '..\..\Forms\ReportHistoryFrm.pas' {ReportHistoryForm},
   ProjGatherDealPay in '..\..\ProjGather\ProjGatherDealPay.pas',
   ProjGatherProperties in '..\..\ProjGather\ProjGatherProperties.pas',
   rpgDealPayDm in '..\..\Report\ProjGather\rpgDealPayDm.pas' {rgpDealPayData: TDataModule},
   superobject in '..\..\Units\superobject\superobject.pas',
   FileDownLoadFrm in '..\..\Forms\FileDownLoadFrm.pas' {FileDownLoadForm},
-  ReportManagerFrm in '..\..\Forms\ReportManagerFrm.pas' {ReportManagerForm},
-  ReportManagerDM in '..\..\DataModules\ReportManagerDM.pas' {Reports: TDataModule},
-  ReportHistoryFrm in '..\..\Forms\ReportHistoryFrm.pas' {ReportHistoryForm};
+  MeasureGatherZJJL in '..\..\Units\MeasureGatherZJJL.pas',
+  stgGatherControl in '..\..\SubTenderGather\stgGatherControl.pas',
+  stgGatherCacheData in '..\..\SubTenderGather\stgGatherCacheData.pas',
+  stgGatherDm in '..\..\SubTenderGather\stgGatherDm.pas' {stgGatherData: TDataModule},
+  stgGatherUtils in '..\..\SubTenderGather\stgGatherUtils.pas',
+  stgResultFrm in '..\..\SubTenderGather\stgResultFrm.pas' {stgResultForm},
+  stgExcelExport in '..\..\SubTenderGather\stgExcelExport.pas',
+  stgSubGatherFile in '..\..\SubTenderGather\stgSubGatherFile.pas',
+  stgSubGatherFileDm in '..\..\SubTenderGather\stgSubGatherFileDm.pas' {stgSubGatherData: TDataModule},
+  stgTables in '..\..\SubTenderGather\stgTables.pas',
+  stgGather in '..\..\SubTenderGather\stgGather.pas',
+  stgSelectFileFrm in '..\..\SubTenderGather\stgSelectFileFrm.pas' {stgSelectFileForm};
 
 {$R *.res}
 
 var
   Mutex: THandle;
   IPForm: TIPForm;
+  vFDForm: TFileDownLoadForm;
   sInfo, sURL, sName: string;
 
 begin
@@ -289,6 +302,21 @@ begin
             Application.Terminate;
           end;
 
+          ltUpdate:  // 升级
+          begin
+            if Application.MessageBox(PChar(sInfo), '系统提示', MB_OKCANCEL + MB_ICONQUESTION) = ID_OK then
+            begin
+              vFDForm := TFileDownLoadForm.Create(nil);
+              try
+                vFDForm.URL := sURL;
+                vFDForm.ShowModal;
+              finally
+                vFDForm.Free;
+              end;
+            end;
+            Application.Terminate;
+          end;
+
           ltDisCon:
           begin
             Application.MessageBox('网络错误,请稍后重试!', '操作提醒', MB_OK + MB_ICONWARNING);

+ 0 - 283
Dprs/PWFree/Measure_GuangDong_Cloud.dpr

@@ -1,283 +0,0 @@
-program Measure_GuangDong_Cloud;
-
-{$R '..\..\res\uac.res' '..\..\res\uac.rc'}
-
-uses
-  Windows,
-  ShareMem,
-  Forms,
-  Controls,
-  MainFrm in '..\..\Forms\MainFrm.pas' {MainForm},
-  ProjectManagerFme in '..\..\Frames\ProjectManagerFme.pas' {ProjectManagerFrame: TFrame},
-  UtilMethods in '..\..\Units\UtilMethods.pas',
-  ProjectManagerDm in '..\..\DataModules\ProjectManagerDm.pas' {ProjectManagerData: TDataModule},
-  Connections in '..\..\Units\Connections.pas',
-  TransFile in '..\..\Units\TransFile.pas',
-  ZhAPI in '..\..\Units\ZhAPI.pas',
-  CompactDB in '..\..\Units\CompactDB.pas',
-  OpenProjectManager in '..\..\Units\OpenProjectManager.pas',
-  ProjectData in '..\..\Units\ProjectData.pas',
-  UpdateDataBase in '..\..\Units\UpdateDataBase.pas',
-  DataBaseTables in '..\..\Units\DataBaseTables.pas',
-  ConfigDoc in '..\..\Units\ConfigDoc.pas',
-  SupportUnit in '..\..\Units\SupportUnit.pas',
-  StandardLibs in '..\..\Units\StandardLibs.pas',
-  StandardLib in '..\..\Units\StandardLib.pas',
-  NewProjectFrm in '..\..\Forms\NewProjectFrm.pas' {NewProjectForm},
-  ProjectFme in '..\..\Frames\ProjectFme.pas' {ProjectFrame: TFrame},
-  StandardBillsDm in '..\..\DataModules\StandardBillsDm.pas' {StandardBillsData: TDataModule},
-  StandardBillsFme in '..\..\Frames\StandardBillsFme.pas' {StandardBillsFrame: TFrame},
-  StandardLibsFme in '..\..\Frames\StandardLibsFme.pas' {StandardLibsFrame: TFrame},
-  BillsDm in '..\..\DataModules\BillsDm.pas' {BillsData: TDataModule},
-  Globals in '..\..\Units\Globals.pas',
-  StageDm in '..\..\DataModules\StageDm.pas' {StageData: TDataModule},
-  ExcelImport in '..\..\Units\ExcelImport.pas',
-  CacheTree in '..\..\Units\CacheTree.pas',
-  MCacheTree in '..\..\Units\MCacheTree.pas',
-  ProjectPropertiesFrm in '..\..\Forms\ProjectPropertiesFrm.pas' {ProjectPropertiesForm},
-  ProjectProperty in '..\..\Units\ProjectProperty.pas',
-  FormulaCalc in '..\..\Units\FormulaCalc.pas',
-  BillsCommand in '..\..\Units\BillsCommand.pas',
-  PhaseData in '..\..\Units\PhaseData.pas',
-  PhaseProperty in '..\..\Units\PhaseProperty.pas',
-  BillsClipboard in '..\..\Units\BillsClipboard.pas',
-  BillsTree in '..\..\Units\BillsTree.pas',
-  ProjectCommands in '..\..\Units\ProjectCommands.pas',
-  PhaseCompareDm in '..\..\DataModules\PhaseCompareDm.pas' {PhaseCompareData: TDataModule},
-  PhaseCompareFme in '..\..\Frames\PhaseCompareFme.pas' {PhaseCompareFrame: TFrame},
-  OptionFrm in '..\..\Forms\OptionFrm.pas' {OptionForm},
-  DealPaymentDm in '..\..\DataModules\DealPaymentDm.pas' {DealPaymentData: TDataModule},
-  DealPaymentFme in '..\..\Frames\DealPaymentFme.pas' {DealPaymentFrame: TFrame},
-  PhasePayDm in '..\..\DataModules\PhasePayDm.pas' {PhasePayData: TDataModule},
-  ZJJLDm in '..\..\DataModules\ZJJLDm.pas' {ZJJLData: TDataModule},
-  BillsGatherDm in '..\..\DataModules\BillsGatherDm.pas' {BillsGatherData: TDataModule},
-  BillsGatherFme in '..\..\Frames\BillsGatherFme.pas' {BillsGatherFrame: TFrame},
-  LoginFrm in '..\..\Forms\LoginFrm.pas' {LoginFrm},
-  PHPWebDm in '..\..\DataModules\PHPWebDm.pas' {PHPWeb: TDataModule},
-  MD5Unit in '..\..\Units\MD5Unit.pas',
-  ConstUnit in '..\..\Units\ConstUnit.pas',
-  ExportExcel in '..\..\Units\ExportExcel.pas',
-  mEncryptEditions in '..\..\Encrypt\mEncryptEditions.pas',
-  mEncryptUnit in '..\..\Encrypt\mEncryptUnit.pas',
-  CryptUtils in '..\..\Encrypt\CryptUtils.pas',
-  EncryptDog in '..\..\Encrypt\EncryptDog.pas',
-  mEncryptPWD in '..\..\Encrypt\mEncryptPWD.pas',
-  mEncryptTypes in '..\..\Encrypt\mEncryptTypes.pas',
-  mR1Encrypt in '..\..\Encrypt\mR1Encrypt.pas',
-  mS4Utils in '..\..\Encrypt\mS4Utils.pas',
-  mSNSEncrypt in '..\..\Encrypt\mSNSEncrypt.pas',
-  Rockey1 in '..\..\Encrypt\Rockey1.pas',
-  mConnectEncrypt in '..\..\Encrypt\NetClient\mConnectEncrypt.pas',
-  FindUserFrm in '..\..\Forms\FindUserFrm.pas' {FindUserForm},
-  CslJson in '..\..\Units\CslJson.pas',
-  OrderCheckerFme in '..\..\Frames\OrderCheckerFme.pas' {OrderCheckerFrame: TFrame},
-  CheckerFme in '..\..\Frames\CheckerFme.pas' {CheckerFrame: TFrame},
-  WebNewTenderFrm in '..\..\Forms\WebNewTenderFrm.pas' {WebNewTenderForm},
-  ScFileArchiver in '..\..\Encrypt\ScFileArchiver.pas',
-  SearchDm in '..\..\DataModules\SearchDm.pas' {SearchData: TDataModule},
-  DealBillsDm in '..\..\DataModules\DealBillsDm.pas' {DealBillsData: TDataModule},
-  BGLDm in '..\..\DataModules\BGLDm.pas' {BGLData: TDataModule},
-  StaffDm in '..\..\DataModules\StaffDm.pas' {StaffData: TDataModule},
-  BillsCompileDm in '..\..\DataModules\BillsCompileDm.pas' {BillsCompileData: TDataModule},
-  BillsMeasureDm in '..\..\DataModules\BillsMeasureDm.pas' {BillsMeasureData: TDataModule},
-  ReportManager in '..\..\Units\ReportManager.pas',
-  BGLSelectFrm in '..\..\Forms\BGLSelectFrm.pas' {BGLSelectForm},
-  BillsCompileFme in '..\..\Frames\BillsCompileFme.pas' {BillsCompileFrame: TFrame},
-  BillsMeasureFme in '..\..\Frames\BillsMeasureFme.pas' {BillsMeasureFrame: TFrame},
-  BatchReplaceBillsFrm in '..\..\Forms\BatchReplaceBillsFrm.pas' {BatchReplaceBillsForm},
-  ZJJLFme in '..\..\Frames\ZJJLFme.pas' {ZJJLFrame: TFrame},
-  BGLFme in '..\..\Frames\BGLFme.pas' {BGLFrame: TFrame},
-  MergeTextFrm in '..\..\Forms\MergeTextFrm.pas' {MergeTextForm},
-  ReportsFrm in '..\..\Forms\ReportsFrm.pas' {ReportsForm},
-  ReportAdjustFrm in '..\..\Forms\ReportAdjustFrm.pas' {ReportAdjustForm},
-  SearchFme in '..\..\Frames\SearchFme.pas' {SearchFrame: TFrame},
-  AuthFrm in '..\..\Forms\AuthFrm.pas' {AuthorizeForm},
-  AboutFrm in '..\..\Forms\AboutFrm.pas' {AboutForm},
-  ImportExcelHintFrm in '..\..\Forms\ImportExcelHintFrm.pas' {ImportExcelHintForm},
-  PasswordInputFrm in '..\..\Forms\PasswordInputFrm.pas' {PasswordInputForm},
-  BatchInsertBillsFrm in '..\..\Forms\BatchInsertBillsFrm.pas' {BatchInsertBillsForm},
-  MainDataListDm in '..\..\DataModules\MainDataListDm.pas' {MainListData: TDataModule},
-  mProgressFrm in '..\..\Forms\mProgressFrm.pas' {mProgress},
-  rmGclBillsBGDm in '..\..\DataModules\ReportMemoryDm\rmGclBillsBGDm.pas' {rmGclBillsBGData: TDataModule},
-  rmGclBillsCompareDm in '..\..\DataModules\ReportMemoryDm\rmGclBillsCompareDm.pas' {rmGclBillsCompareData: TDataModule},
-  rmBGLExecutionDm in '..\..\DataModules\ReportMemoryDm\rmBGLExecutionDm.pas' {rmBGLExecutionData: TDataModule},
-  rmBillsGatherDm in '..\..\DataModules\ReportMemoryDm\rmBillsGatherDm.pas' {rmBillsGatherData: TDataModule},
-  rmFxBillsAddDm in '..\..\DataModules\ReportMemoryDm\rmFxBillsAddDm.pas' {rmFxBillsAddData: TDataModule},
-  rmFxBillsCompareDm in '..\..\DataModules\ReportMemoryDm\rmFxBillsCompareDm.pas' {rmFxBillsCompareData: TDataModule},
-  rmGclBillsAddDm in '..\..\DataModules\ReportMemoryDm\rmGclBillsAddDm.pas' {rmGclBillsAddData: TDataModule},
-  rmGridHeaderDm in '..\..\DataModules\ReportMemoryDm\rmGridHeaderDm.pas' {rmGridHeaderData: TDataModule},
-  rmCacheData in '..\..\DataModules\ReportMemoryDm\rmCacheData.pas',
-  rmSelectProjectFrm in '..\..\Forms\rmSelectProjectFrm.pas' {ProjectSelectForm},
-  ConditionalDefines in '..\..\Units\ConditionalDefines.pas',
-  ProgressHintFrm in '..\..\Forms\ProgressHintFrm.pas' {ProgressHintForm},
-  rmGclBillsAuditCompareDm in '..\..\DataModules\ReportMemoryDm\rmGclBillsAuditCompareDm.pas' {rmGclBillsAuditCompareData: TDataModule},
-  rmTestFrm in '..\..\DataModules\ReportMemoryDm\rmTestFrm.pas' {rmTestForm},
-  CheckAndClearFrm in '..\..\Forms\CheckAndClearFrm.pas' {CheckAndClearForm},
-  DealBillsFrm in '..\..\Forms\DealBillsFrm.pas' {DealBillsForm},
-  TenderBackupFrm in '..\..\Forms\TenderBackupFrm.pas' {TenderBackupForm},
-  TenderBackupDm in '..\..\DataModules\TenderBackupDm.pas' {TenderBackupData: TDataModule},
-  BillsBookmarkDm in '..\..\DataModules\BillsBookmarkDm.pas' {BillsBookmarkData: TDataModule},
-  BookmarkFme in '..\..\Frames\BookmarkFme.pas' {BookmarkFrame: TFrame},
-  rmDealInfosDm in '..\..\DataModules\ReportMemoryDm\rmDealInfosDm.pas' {rmDealInfosData: TDataModule},
-  rmXmjBGLDetailDm in '..\..\DataModules\ReportMemoryDm\rmXmjBGLDetailDm.pas' {rmXmjBGLDetailData: TDataModule},
-  WelcomeFrm in '..\..\Forms\WelcomeFrm.pas' {Form1},
-  rmOtherReport1Dm in '..\..\DataModules\ReportMemoryDm\rmOtherReport1Dm.pas' {rmOtherReport1Data: TDataModule},
-  CheckerMemoFrm in '..\..\Forms\CheckerMemoFrm.pas' {CheckerMemoForm},
-  CslHint in '..\..\Units\CslHint.pas',
-  IPFrm in '..\..\Forms\IPFrm.pas' {IPForm},
-  TenderBackupManager in '..\..\Units\TenderBackupManager.pas',
-  UpFileFrame in '..\..\Forms\UpFileFrame.pas',
-  UpFileManageFrame in '..\..\Forms\UpFileManageFrame.pas',
-  UpFileManageUnit in '..\..\Units\UpFileManageUnit.pas',
-  SheetSelectFrm in '..\..\Forms\SheetSelectFrm.pas' {SheetSelectForm},
-  Checker in '..\..\Units\Checker.pas',
-  ReportInteractInfo in '..\..\Units\ReportInteractInfo.pas',
-  AuditSelectFrm in '..\..\Forms\ReportInteractFrms\AuditSelectFrm.pas' {AuditSelctForm},
-  DealBillsFme in '..\..\Frames\DealBillsFme.pas' {DealBillsFrame: TFrame},
-  rmGclBillsPlaneDm in '..\..\DataModules\ReportMemoryDm\rmGclBillsPlaneDm.pas' {rmGclBillsPlaneData: TDataModule},
-  StageCompareDm in '..\..\DataModules\StageCompareDm.pas' {StageCompareData: TDataModule},
-  mDataRecord in '..\..\Units\mDataRecord.pas',
-  BGLClipboard in '..\..\Units\BGLClipboard.pas',
-  rmMentalCustomized1Dm in '..\..\DataModules\ReportMemoryDm\rmMentalCustomized1Dm.pas' {rmMentalCustomized1Data: TDataModule},
-  rmGcl_XmjBillsDm in '..\..\DataModules\ReportMemoryDm\rmGcl_XmjBillsDm.pas' {rmGcl_XmjBillsData: TDataModule},
-  rmCustomized2Dm in '..\..\DataModules\ReportMemoryDm\rmCustomized2Dm.pas' {rmCustomized2Data: TDataModule},
-  CalcDecimal in '..\..\Units\CalcDecimal.pas',
-  BillsPasteSelectFrm in '..\..\Forms\BillsPasteSelectFrm.pas' {BillsPasteSelectForm},
-  DetailExcelImport in '..\..\Units\DetailExcelImport.pas',
-  mProgressProFrm in '..\..\Forms\mProgressProFrm.pas' {ProgressProForm},
-  BaseClipboard in '..\..\Units\BaseClipboard.pas',
-  PriceMarginBillsDm in '..\..\DataModules\PriceMarginBillsDm.pas' {PriceMarginBillsData: TDataModule},
-  ProjectGLDm in '..\..\DataModules\ProjectGLDm.pas' {ProjectGLData: TDataModule},
-  GclBillsGatherModel in '..\..\Units\GclBillsGatherModel.pas',
-  DetailGLDm in '..\..\DataModules\DetailGLDm.pas' {DetailGLData: TDataModule},
-  rmHaBaiCustomizedDm in '..\..\DataModules\ReportMemoryDm\rmHaBaiCustomizedDm.pas' {rmHaBaiCustomizedData: TDataModule},
-  PriceMarginBillsFme in '..\..\Frames\PriceMarginBillsFme.pas' {PriceMarginBillsFrame: TFrame},
-  PriceMarginFme in '..\..\Frames\PriceMarginFme.pas' {PriceMarginFrame: TFrame},
-  ProjectGLFme in '..\..\Frames\ProjectGLFme.pas' {ProjectGLFrame: TFrame},
-  SelectDetailGLsFrm in '..\..\Forms\SelectDetailGLsFrm.pas' {SelectDetailGLsForm},
-  DealPayPlanFrm in '..\..\Forms\DealPayPlanFrm.pas' {DealPayPlanForm},
-  tpBaseGatherData in '..\..\TenderPartition\tpBaseGatherData.pas',
-  tpGatherGcl in '..\..\TenderPartition\tpGatherGcl.pas',
-  tpGatherTree in '..\..\TenderPartition\tpGatherTree.pas',
-  tpMainData in '..\..\TenderPartition\tpMainData.pas',
-  tpMainFrm in '..\..\TenderPartition\tpMainFrm.pas' {tpMainForm},
-  tpNoPegDm in '..\..\TenderPartition\tpNoPegDm.pas' {tpNoPegData: TDataModule},
-  tpPartTender in '..\..\TenderPartition\tpPartTender.pas',
-  tpPartTenderFme in '..\..\TenderPartition\tpPartTenderFme.pas' {tpPartTenderFrame: TFrame},
-  tpPartTenderSet in '..\..\TenderPartition\tpPartTenderSet.pas',
-  tpPartTenderSetFme in '..\..\TenderPartition\tpPartTenderSetFme.pas' {tpPartTenderSetFrame: TFrame},
-  tpPeg in '..\..\TenderPartition\tpPeg.pas',
-  tpPeg_GclDm in '..\..\TenderPartition\tpPeg_GclDm.pas' {tpPeg_GclData: TDataModule},
-  tpPeg_GclFme in '..\..\TenderPartition\tpPeg_GclFme.pas' {tpPeg_GclFrame: TFrame},
-  tpPegBlock in '..\..\TenderPartition\tpPegBlock.pas',
-  tpPegGclGatherDm in '..\..\TenderPartition\tpPegGclGatherDm.pas' {tpPegGclGatherData: TDataModule},
-  tpPegGclGatherFme in '..\..\TenderPartition\tpPegGclGatherFme.pas' {tpPegGclGatherFrame: TFrame},
-  tpPegPartSettingFrm in '..\..\TenderPartition\tpPegPartSettingFrm.pas' {tpPegPartSettingForm},
-  tpPricePartSettingFrm in '..\..\TenderPartition\tpPricePartSettingFrm.pas' {tpPricePartSettingForm},
-  tpSelectTenderDm in '..\..\TenderPartition\tpSelectTenderDm.pas' {tpSelectTenderData: TDataModule},
-  tpSelectTenderNode in '..\..\TenderPartition\tpSelectTenderNode.pas',
-  tpSelectTendersFrm in '..\..\TenderPartition\tpSelectTendersFrm.pas' {SelectTendersForm},
-  tpTrialPegInputFrm in '..\..\TenderPartition\tpTrialPegInputFrm.pas' {TrialPegInputForm},
-  mPegFilter in '..\..\Units\mPegFilter.pas',
-  ReportPrepare in '..\..\Report\ReportPrepare.pas',
-  rdpBillsGatherDm in '..\..\Report\DataPrepare\rdpBillsGatherDm.pas' {rdpBillsGatherData: TDataModule},
-  rdpTables in '..\..\Report\DataPrepare\rdpTables.pas',
-  ColVisibleManager in '..\..\Units\ColVisibleManager.pas',
-  ReportConnection in '..\..\Report\ReportConnection.pas',
-  rgpGatherControl in '..\..\Report\ProjGather\rgpGatherControl.pas',
-  rpgBillsCalcDm in '..\..\Report\ProjGather\rpgBillsCalcDm.pas' {rpgBillsCalcData: TDataModule},
-  rpgBillsDm in '..\..\Report\ProjGather\rpgBillsDm.pas' {rpgBillsData: TDataModule},
-  rpgGatherControl in '..\..\Report\ProjGather\rpgGatherControl.pas',
-  rpgGatherData in '..\..\Report\ProjGather\rpgGatherData.pas',
-  rpgGatherProjDm in '..\..\Report\ProjGather\rpgGatherProjDm.pas' {rpgGatherProjData: TDataModule},
-  rProjGatherTables in '..\..\Report\ProjGather\rProjGatherTables.pas',
-  ProjGatherTree in '..\..\ProjGather\ProjGatherTree.pas',
-  ProjGather in '..\..\ProjGather\ProjGather.pas',
-  CalcData in '..\..\Units\CalcData.pas',
-  GatherProjInfo in '..\..\ProjGather\GatherProjInfo.pas',
-  ProjGatherCalcData in '..\..\ProjGather\ProjGatherCalcData.pas',
-  ProjGatherSelectFrm in '..\..\ProjGather\ProjGatherSelectFrm.pas' {ProjGatherSelectForm},
-  DealBillsExcelImport in '..\..\Units\DealBillsExcelImport.pas',
-  ExcelImport_Bills in '..\..\Units\ExcelImport_Bills.pas',
-  ExcelImport_GclBills in '..\..\Units\ExcelImport_GclBills.pas',
-  DbTreeImport in '..\..\Units\DbTreeImport.pas',
-  DbTreeDm in '..\..\DataModules\DbTreeDm.pas',
-  DebugUsers in '..\..\Units\DebugUsers.pas',
-  OtherMeasurePhaseDm in '..\..\DataModules\OtherMeasurePhaseDm.pas' {OtherMeasurePhaseData: TDataModule},
-  OtherMeasureOnceDm in '..\..\DataModules\OtherMeasureOnceDm.pas' {OtherMeasureOnceData: TDataModule},
-  OMPhaseRecord in '..\..\Units\DataRecord\OMPhaseRecord.pas',
-  OtherMeasureFme in '..\..\Frames\OtherMeasureFme.pas' {OtherMeasureFrame: TFrame},
-  ProjGatherSelectFme in '..\..\ProjGather\ProjGatherSelectFme.pas' {ProjGatherSelectFrame: TFrame},
-  rpgZoneGatherControl in '..\..\Report\ProjGather\Zone\rpgZoneGatherControl.pas',
-  rpgZoneProjGatherSelectFrm in '..\..\Report\ProjGather\Zone\rpgZoneProjGatherSelectFrm.pas' {rpgZoneProjGatherSelectForm},
-  UpFileSelectOnLineFrm in '..\..\Forms\UpFileSelectOnLineFrm.pas' {UpFileSelectOnLineForm},
-  LogUtils in '..\..\Units\LogUtils.pas',
-  ReportPdfHelper in '..\..\Units\ReportPdfHelper.pas',
-  SelectOnlineSignPhaseFrm in '..\..\Forms\SelectOnlineSignPhaseFrm.pas' {SelectOnlineSignPhaseForm},
-  SignOnlineReportsFrm in '..\..\Forms\SignOnlineReportsFrm.pas' {SignOnlineReportsForm},
-  SignReports in '..\..\Units\SignReports.pas',
-  VirtualTrees in '..\..\..\SmartCost\Components\virtualtree\VirtualTrees.pas',
-  TemplateManagerHelper in '..\..\Units\TemplateManagerHelper.pas',
-  RenameSignReportFrm in '..\..\Forms\RenameSignReportFrm.pas' {RenameSignReportForm},
-  rmWeiWuZjjlGatherDm in '..\..\DataModules\ReportMemoryDm\rmWeiWuZjjlGatherDm.pas' {rmWeiWuZjjlGatherData: TDataModule},
-  SetGuestFrm in '..\..\Forms\SetGuestFrm.pas' {SetGuestForm},
-  ProjGatherDealPay in '..\..\ProjGather\ProjGatherDealPay.pas',
-  ProjGatherProperties in '..\..\ProjGather\ProjGatherProperties.pas',
-  rpgDealPayDm in '..\..\Report\ProjGather\rpgDealPayDm.pas' {rgpDealPayData: TDataModule},
-  superobject in '..\..\Units\superobject\superobject.pas',
-  FileDownLoadFrm in '..\..\Forms\FileDownLoadFrm.pas' {FileDownLoadForm},
-  ReportManagerFrm in '..\..\Forms\ReportManagerFrm.pas' {ReportManagerForm},
-  ReportManagerDM in '..\..\DataModules\ReportManagerDM.pas' {Reports: TDataModule},
-  ReportHistoryFrm in '..\..\Forms\ReportHistoryFrm.pas' {ReportHistoryForm};
-
-{$R *.res}
-
-var
-  Mutex: THandle;
-  IPForm: TIPForm;
-
-begin
-  Mutex := CreateMutex(nil, True, G_AppHandleName);
-
-  if GetLastError = ERROR_ALREADY_EXISTS then
-    Application.MessageBox('程序正在运行, 请勿重复打开该软件!', '系统提示', MB_OK + MB_ICONINFORMATION)
-  else
-  begin
-    Application.CreateHandle;
-    Application.Initialize;
-    Application.Title := '纵横公路工程结算决算计量一体化软件广东云版';
-
-    {$IFDEF _mCloud}
-      IPForm := TIPForm.Create(nil);
-      try
-        if not IPForm.HasIP then
-        begin
-          IPForm.ShowModal;
-          if IPForm.ModalResult <> mrOK then
-          begin
-            Application.Terminate;
-            Exit;
-          end;
-        end;
-      finally
-        IPForm.Free;
-      end;
-
-      if not LoginForm then
-      begin
-        Application.Terminate;
-        Exit;
-      end;
-    {$ENDIF}
-
-
-    if CheckDogExists then
-    begin
-      Application.CreateForm(TMainForm, MainForm);
-  Application.CreateForm(TSetGuestForm, SetGuestForm);
-  end;
-    Application.Run;
-  end;
-
-  ReleaseMutex(Mutex);
-end.

+ 2 - 2
Dprs/Pro/Measure.dof

@@ -115,7 +115,7 @@ AutoIncBuild=1
 MajorVer=3
 MinorVer=1
 Release=7
-Build=211
+Build=2156
 Debug=0
 PreRelease=0
 Special=0
@@ -126,7 +126,7 @@ CodePage=936
 [Version Info Keys]
 CompanyName=珠海纵横创新软件有限公司
 FileDescription=纵横结算决算计量一体化专业版
-FileVersion=3.1.7.211
+FileVersion=3.1.7.2156
 InternalName=
 LegalCopyright=版权所有(C)珠海纵横创新软件有限公司2003-2016
 LegalTrademarks=Measure

+ 13 - 1
Dprs/Pro/Measure.dpr

@@ -222,7 +222,19 @@ uses
   ProjGatherDealPay in '..\..\ProjGather\ProjGatherDealPay.pas',
   ProjGatherProperties in '..\..\ProjGather\ProjGatherProperties.pas',
   rpgDealPayDm in '..\..\Report\ProjGather\rpgDealPayDm.pas' {rgpDealPayData: TDataModule},
-  superobject in '..\..\Units\superobject\superobject.pas';
+  superobject in '..\..\Units\superobject\superobject.pas',
+  MeasureGatherZJJL in '..\..\Units\MeasureGatherZJJL.pas',
+  stgExcelExport in '..\..\SubTenderGather\stgExcelExport.pas',
+  stgGather in '..\..\SubTenderGather\stgGather.pas',
+  stgGatherCacheData in '..\..\SubTenderGather\stgGatherCacheData.pas',
+  stgGatherControl in '..\..\SubTenderGather\stgGatherControl.pas',
+  stgGatherDm in '..\..\SubTenderGather\stgGatherDm.pas' {stgGatherData: TDataModule},
+  stgGatherUtils in '..\..\SubTenderGather\stgGatherUtils.pas',
+  stgResultFrm in '..\..\SubTenderGather\stgResultFrm.pas' {stgResultForm},
+  stgSelectFileFrm in '..\..\SubTenderGather\stgSelectFileFrm.pas' {stgSelectFileForm},
+  stgSubGatherFile in '..\..\SubTenderGather\stgSubGatherFile.pas',
+  stgSubGatherFileDm in '..\..\SubTenderGather\stgSubGatherFileDm.pas' {stgSubGatherData: TDataModule},
+  stgTables in '..\..\SubTenderGather\stgTables.pas';
 
 {$R *.res}
 

BIN
Dprs/Pro/Measure.res


+ 2 - 2
Dprs/Pro/Measure_Cloud.dof

@@ -115,7 +115,7 @@ AutoIncBuild=1
 MajorVer=3
 MinorVer=1
 Release=7
-Build=211
+Build=2156
 Debug=0
 PreRelease=0
 Special=0
@@ -126,7 +126,7 @@ CodePage=936
 [Version Info Keys]
 CompanyName=珠海纵横创新软件有限公司
 FileDescription=纵横结算决算计量一体化云版
-FileVersion=3.1.7.211
+FileVersion=3.1.7.2156
 InternalName=
 LegalCopyright=版权所有(C)珠海纵横创新软件有限公司2003-2016
 LegalTrademarks=Measure

+ 28 - 1
Dprs/Pro/Measure_Cloud.dpr

@@ -229,7 +229,19 @@ uses
   ProjGatherProperties in '..\..\ProjGather\ProjGatherProperties.pas',
   rpgDealPayDm in '..\..\Report\ProjGather\rpgDealPayDm.pas' {rgpDealPayData: TDataModule},
   superobject in '..\..\Units\superobject\superobject.pas',
-  FileDownLoadFrm in '..\..\Forms\FileDownLoadFrm.pas' {FileDownLoadForm};
+  FileDownLoadFrm in '..\..\Forms\FileDownLoadFrm.pas' {FileDownLoadForm},
+  MeasureGatherZJJL in '..\..\Units\MeasureGatherZJJL.pas',
+  stgExcelExport in '..\..\SubTenderGather\stgExcelExport.pas',
+  stgGather in '..\..\SubTenderGather\stgGather.pas',
+  stgGatherCacheData in '..\..\SubTenderGather\stgGatherCacheData.pas',
+  stgGatherControl in '..\..\SubTenderGather\stgGatherControl.pas',
+  stgGatherDm in '..\..\SubTenderGather\stgGatherDm.pas' {stgGatherData: TDataModule},
+  stgGatherUtils in '..\..\SubTenderGather\stgGatherUtils.pas',
+  stgResultFrm in '..\..\SubTenderGather\stgResultFrm.pas' {stgResultForm},
+  stgSelectFileFrm in '..\..\SubTenderGather\stgSelectFileFrm.pas' {stgSelectFileForm},
+  stgSubGatherFile in '..\..\SubTenderGather\stgSubGatherFile.pas',
+  stgSubGatherFileDm in '..\..\SubTenderGather\stgSubGatherFileDm.pas' {stgSubGatherData: TDataModule},
+  stgTables in '..\..\SubTenderGather\stgTables.pas';
 
 {$R *.res}
 
@@ -289,6 +301,21 @@ begin
             Application.Terminate;
           end;
 
+          ltUpdate:  // 升级
+          begin
+            if Application.MessageBox(PChar(sInfo), '系统提示', MB_OKCANCEL + MB_ICONQUESTION) = ID_OK then
+            begin
+              vFDForm := TFileDownLoadForm.Create(nil);
+              try
+                vFDForm.URL := sURL;
+                vFDForm.ShowModal;
+              finally
+                vFDForm.Free;
+              end;
+            end;
+            Application.Terminate;
+          end;
+
           ltDisCon:
           begin
             Application.MessageBox('网络错误,请稍后重试!', '操作提醒', MB_OK + MB_ICONWARNING);

BIN
Dprs/Pro/Measure_Cloud.res


+ 2 - 2
Dprs/Pro/Measure_GuangDong.dof

@@ -115,7 +115,7 @@ AutoIncBuild=1
 MajorVer=3
 MinorVer=1
 Release=7
-Build=211
+Build=2156
 Debug=0
 PreRelease=0
 Special=0
@@ -126,7 +126,7 @@ CodePage=936
 [Version Info Keys]
 CompanyName=珠海纵横创新软件有限公司
 FileDescription=纵横结算决算计量一体化广东专业版
-FileVersion=3.1.7.211
+FileVersion=3.1.7.2156
 InternalName=
 LegalCopyright=版权所有(C)珠海纵横创新软件有限公司2003-2016
 LegalTrademarks=Measure

+ 13 - 1
Dprs/Pro/Measure_GuangDong.dpr

@@ -222,7 +222,19 @@ uses
   ProjGatherDealPay in '..\..\ProjGather\ProjGatherDealPay.pas',
   ProjGatherProperties in '..\..\ProjGather\ProjGatherProperties.pas',
   rpgDealPayDm in '..\..\Report\ProjGather\rpgDealPayDm.pas' {rgpDealPayData: TDataModule},
-  superobject in '..\..\Units\superobject\superobject.pas';
+  superobject in '..\..\Units\superobject\superobject.pas',
+  MeasureGatherZJJL in '..\..\Units\MeasureGatherZJJL.pas',
+  stgExcelExport in '..\..\SubTenderGather\stgExcelExport.pas',
+  stgGather in '..\..\SubTenderGather\stgGather.pas',
+  stgGatherCacheData in '..\..\SubTenderGather\stgGatherCacheData.pas',
+  stgGatherControl in '..\..\SubTenderGather\stgGatherControl.pas',
+  stgGatherDm in '..\..\SubTenderGather\stgGatherDm.pas' {stgGatherData: TDataModule},
+  stgGatherUtils in '..\..\SubTenderGather\stgGatherUtils.pas',
+  stgResultFrm in '..\..\SubTenderGather\stgResultFrm.pas' {stgResultForm},
+  stgSelectFileFrm in '..\..\SubTenderGather\stgSelectFileFrm.pas' {stgSelectFileForm},
+  stgSubGatherFile in '..\..\SubTenderGather\stgSubGatherFile.pas',
+  stgSubGatherFileDm in '..\..\SubTenderGather\stgSubGatherFileDm.pas' {stgSubGatherData: TDataModule},
+  stgTables in '..\..\SubTenderGather\stgTables.pas';
 
 {$R *.res}
 

BIN
Dprs/Pro/Measure_GuangDong.res


+ 2 - 2
Dprs/Pro/Measure_GuangDong_Cloud.dof

@@ -115,7 +115,7 @@ AutoIncBuild=1
 MajorVer=3
 MinorVer=1
 Release=7
-Build=211
+Build=2156
 Debug=0
 PreRelease=0
 Special=0
@@ -126,7 +126,7 @@ CodePage=936
 [Version Info Keys]
 CompanyName=珠海纵横创新软件有限公司
 FileDescription=纵横结算决算计量一体化广东云版
-FileVersion=3.1.7.211
+FileVersion=3.1.7.2156
 InternalName=
 LegalCopyright=版权所有(C)珠海纵横创新软件有限公司2003-2016
 LegalTrademarks=Measure

+ 13 - 1
Dprs/Pro/Measure_GuangDong_Cloud.dpr

@@ -228,7 +228,19 @@ uses
   ProjGatherProperties in '..\..\ProjGather\ProjGatherProperties.pas',
   rpgDealPayDm in '..\..\Report\ProjGather\rpgDealPayDm.pas' {rgpDealPayData: TDataModule},
   superobject in '..\..\Units\superobject\superobject.pas',
-  FileDownLoadFrm in '..\..\Forms\FileDownLoadFrm.pas' {FileDownLoadForm};
+  FileDownLoadFrm in '..\..\Forms\FileDownLoadFrm.pas' {FileDownLoadForm},
+  MeasureGatherZJJL in '..\..\Units\MeasureGatherZJJL.pas',
+  stgExcelExport in '..\..\SubTenderGather\stgExcelExport.pas',
+  stgGather in '..\..\SubTenderGather\stgGather.pas',
+  stgGatherCacheData in '..\..\SubTenderGather\stgGatherCacheData.pas',
+  stgGatherControl in '..\..\SubTenderGather\stgGatherControl.pas',
+  stgGatherDm in '..\..\SubTenderGather\stgGatherDm.pas' {stgGatherData: TDataModule},
+  stgGatherUtils in '..\..\SubTenderGather\stgGatherUtils.pas',
+  stgResultFrm in '..\..\SubTenderGather\stgResultFrm.pas' {stgResultForm},
+  stgSelectFileFrm in '..\..\SubTenderGather\stgSelectFileFrm.pas' {stgSelectFileForm},
+  stgSubGatherFile in '..\..\SubTenderGather\stgSubGatherFile.pas',
+  stgSubGatherFileDm in '..\..\SubTenderGather\stgSubGatherFileDm.pas' {stgSubGatherData: TDataModule},
+  stgTables in '..\..\SubTenderGather\stgTables.pas';
 
 {$R *.res}
 

BIN
Dprs/Pro/Measure_GuangDong_Cloud.res


+ 2 - 2
Dprs/Pro/Measure_GuangDong_TZ.dof

@@ -115,7 +115,7 @@ AutoIncBuild=0
 MajorVer=3
 MinorVer=1
 Release=7
-Build=210
+Build=2155
 Debug=0
 PreRelease=0
 Special=0
@@ -126,7 +126,7 @@ CodePage=936
 [Version Info Keys]
 CompanyName=珠海纵横创新软件有限公司
 FileDescription=纵横0号台账广东专业版
-FileVersion=3.1.7.210
+FileVersion=3.1.7.2155
 InternalName=
 LegalCopyright=版权所有(C)珠海纵横创新软件有限公司2003-2016
 LegalTrademarks=Measure

+ 13 - 1
Dprs/Pro/Measure_GuangDong_TZ.dpr

@@ -222,7 +222,19 @@ uses
   ProjGatherDealPay in '..\..\ProjGather\ProjGatherDealPay.pas',
   ProjGatherProperties in '..\..\ProjGather\ProjGatherProperties.pas',
   rpgDealPayDm in '..\..\Report\ProjGather\rpgDealPayDm.pas' {rgpDealPayData: TDataModule},
-  superobject in '..\..\Units\superobject\superobject.pas';
+  superobject in '..\..\Units\superobject\superobject.pas',
+  MeasureGatherZJJL in '..\..\Units\MeasureGatherZJJL.pas',
+  stgExcelExport in '..\..\SubTenderGather\stgExcelExport.pas',
+  stgGather in '..\..\SubTenderGather\stgGather.pas',
+  stgGatherCacheData in '..\..\SubTenderGather\stgGatherCacheData.pas',
+  stgGatherControl in '..\..\SubTenderGather\stgGatherControl.pas',
+  stgGatherDm in '..\..\SubTenderGather\stgGatherDm.pas' {stgGatherData: TDataModule},
+  stgGatherUtils in '..\..\SubTenderGather\stgGatherUtils.pas',
+  stgResultFrm in '..\..\SubTenderGather\stgResultFrm.pas' {stgResultForm},
+  stgSelectFileFrm in '..\..\SubTenderGather\stgSelectFileFrm.pas' {stgSelectFileForm},
+  stgSubGatherFile in '..\..\SubTenderGather\stgSubGatherFile.pas',
+  stgSubGatherFileDm in '..\..\SubTenderGather\stgSubGatherFileDm.pas' {stgSubGatherData: TDataModule},
+  stgTables in '..\..\SubTenderGather\stgTables.pas';
 
 {$R *.res}
 

BIN
Dprs/Pro/Measure_GuangDong_TZ.res


+ 2 - 2
Dprs/Pro/Measure_TZ.dof

@@ -115,7 +115,7 @@ AutoIncBuild=1
 MajorVer=3
 MinorVer=1
 Release=7
-Build=211
+Build=2156
 Debug=0
 PreRelease=0
 Special=0
@@ -126,7 +126,7 @@ CodePage=936
 [Version Info Keys]
 CompanyName=珠海纵横创新软件有限公司
 FileDescription=纵横0号台账专业版
-FileVersion=3.1.7.211
+FileVersion=3.1.7.2156
 InternalName=
 LegalCopyright=版权所有(C)珠海纵横创新软件有限公司2003-2016
 LegalTrademarks=Measure

+ 13 - 1
Dprs/Pro/Measure_TZ.dpr

@@ -222,7 +222,19 @@ uses
   ProjGatherDealPay in '..\..\ProjGather\ProjGatherDealPay.pas',
   ProjGatherProperties in '..\..\ProjGather\ProjGatherProperties.pas',
   rpgDealPayDm in '..\..\Report\ProjGather\rpgDealPayDm.pas' {rgpDealPayData: TDataModule},
-  superobject in '..\..\Units\superobject\superobject.pas';
+  superobject in '..\..\Units\superobject\superobject.pas',
+  MeasureGatherZJJL in '..\..\Units\MeasureGatherZJJL.pas',
+  stgExcelExport in '..\..\SubTenderGather\stgExcelExport.pas',
+  stgGather in '..\..\SubTenderGather\stgGather.pas',
+  stgGatherCacheData in '..\..\SubTenderGather\stgGatherCacheData.pas',
+  stgGatherControl in '..\..\SubTenderGather\stgGatherControl.pas',
+  stgGatherDm in '..\..\SubTenderGather\stgGatherDm.pas' {stgGatherData: TDataModule},
+  stgGatherUtils in '..\..\SubTenderGather\stgGatherUtils.pas',
+  stgResultFrm in '..\..\SubTenderGather\stgResultFrm.pas' {stgResultForm},
+  stgSelectFileFrm in '..\..\SubTenderGather\stgSelectFileFrm.pas' {stgSelectFileForm},
+  stgSubGatherFile in '..\..\SubTenderGather\stgSubGatherFile.pas',
+  stgSubGatherFileDm in '..\..\SubTenderGather\stgSubGatherFileDm.pas' {stgSubGatherData: TDataModule},
+  stgTables in '..\..\SubTenderGather\stgTables.pas';
 
 {$R *.res}
 

BIN
Dprs/Pro/Measure_TZ.res


+ 2 - 2
Dprs/Trail/Measure.dof

@@ -115,7 +115,7 @@ AutoIncBuild=1
 MajorVer=3
 MinorVer=1
 Release=7
-Build=211
+Build=2156
 Debug=0
 PreRelease=0
 Special=0
@@ -126,7 +126,7 @@ CodePage=936
 [Version Info Keys]
 CompanyName=珠海纵横创新软件有限公司
 FileDescription=纵横结算决算计量一体化学习版
-FileVersion=3.1.7.211
+FileVersion=3.1.7.2156
 InternalName=
 LegalCopyright=版权所有(C)珠海纵横创新软件有限公司2003-2016
 LegalTrademarks=Measure

+ 13 - 1
Dprs/Trail/Measure.dpr

@@ -222,7 +222,19 @@ uses
   ProjGatherDealPay in '..\..\ProjGather\ProjGatherDealPay.pas',
   ProjGatherProperties in '..\..\ProjGather\ProjGatherProperties.pas',
   rpgDealPayDm in '..\..\Report\ProjGather\rpgDealPayDm.pas' {rgpDealPayData: TDataModule},
-  superobject in '..\..\Units\superobject\superobject.pas';
+  superobject in '..\..\Units\superobject\superobject.pas',
+  MeasureGatherZJJL in '..\..\Units\MeasureGatherZJJL.pas',
+  stgExcelExport in '..\..\SubTenderGather\stgExcelExport.pas',
+  stgGather in '..\..\SubTenderGather\stgGather.pas',
+  stgGatherCacheData in '..\..\SubTenderGather\stgGatherCacheData.pas',
+  stgGatherControl in '..\..\SubTenderGather\stgGatherControl.pas',
+  stgGatherDm in '..\..\SubTenderGather\stgGatherDm.pas' {stgGatherData: TDataModule},
+  stgGatherUtils in '..\..\SubTenderGather\stgGatherUtils.pas',
+  stgResultFrm in '..\..\SubTenderGather\stgResultFrm.pas' {stgResultForm},
+  stgSelectFileFrm in '..\..\SubTenderGather\stgSelectFileFrm.pas' {stgSelectFileForm},
+  stgSubGatherFile in '..\..\SubTenderGather\stgSubGatherFile.pas',
+  stgSubGatherFileDm in '..\..\SubTenderGather\stgSubGatherFileDm.pas' {stgSubGatherData: TDataModule},
+  stgTables in '..\..\SubTenderGather\stgTables.pas';
 
 {$R *.res}
 

BIN
Dprs/Trail/Measure.res


+ 2 - 2
Dprs/Trail/Measure_GuangDong.dof

@@ -115,7 +115,7 @@ AutoIncBuild=1
 MajorVer=3
 MinorVer=1
 Release=7
-Build=142
+Build=2156
 Debug=0
 PreRelease=0
 Special=0
@@ -126,7 +126,7 @@ CodePage=936
 [Version Info Keys]
 CompanyName=珠海纵横创新软件有限公司
 FileDescription=纵横结算决算计量一体化广东学习版
-FileVersion=3.1.7.142
+FileVersion=3.1.7.2156
 InternalName=
 LegalCopyright=版权所有(C)珠海纵横创新软件有限公司2003-2016
 LegalTrademarks=Measure

+ 13 - 1
Dprs/Trail/Measure_GuangDong.dpr

@@ -222,7 +222,19 @@ uses
   ProjGatherDealPay in '..\..\ProjGather\ProjGatherDealPay.pas',
   ProjGatherProperties in '..\..\ProjGather\ProjGatherProperties.pas',
   rpgDealPayDm in '..\..\Report\ProjGather\rpgDealPayDm.pas' {rgpDealPayData: TDataModule},
-  superobject in '..\..\Units\superobject\superobject.pas';
+  superobject in '..\..\Units\superobject\superobject.pas',
+  MeasureGatherZJJL in '..\..\Units\MeasureGatherZJJL.pas',
+  stgExcelExport in '..\..\SubTenderGather\stgExcelExport.pas',
+  stgGather in '..\..\SubTenderGather\stgGather.pas',
+  stgGatherCacheData in '..\..\SubTenderGather\stgGatherCacheData.pas',
+  stgGatherControl in '..\..\SubTenderGather\stgGatherControl.pas',
+  stgGatherDm in '..\..\SubTenderGather\stgGatherDm.pas' {stgGatherData: TDataModule},
+  stgGatherUtils in '..\..\SubTenderGather\stgGatherUtils.pas',
+  stgResultFrm in '..\..\SubTenderGather\stgResultFrm.pas' {stgResultForm},
+  stgSelectFileFrm in '..\..\SubTenderGather\stgSelectFileFrm.pas' {stgSelectFileForm},
+  stgSubGatherFile in '..\..\SubTenderGather\stgSubGatherFile.pas',
+  stgSubGatherFileDm in '..\..\SubTenderGather\stgSubGatherFileDm.pas' {stgSubGatherData: TDataModule},
+  stgTables in '..\..\SubTenderGather\stgTables.pas';
 
 {$R *.res}
 

BIN
Dprs/Trail/Measure_GuangDong.res


+ 2 - 2
Forms/BGLSelectFrm.pas

@@ -314,8 +314,8 @@ begin
     begin
       fCur := QuantityRoundTo(StrToFloatDef(zgBGL.Cells[5, zgBGL.CurRow].Text, 0));
       fValid := StrToFloatDef(zgBGL.Cells[4, zgBGL.CurRow].Text, 0);
-      if ((fValid >= 0) and (fCur <= fValid)) or
-         ((fValid < 0) and (fCur >= fValid)) then
+      if ((fValid >= 0) and (QuantityRoundTo(fValid - fCur) >= 0)) or
+         ((fValid < 0) and (QuantityRoundTo(fCur - fValid) >= 0)) then
         zgBGL.Cells[5, zgBGL.CurRow].Text := FloatToStr(fCur)
       else
       begin

+ 44 - 24
Forms/BatchInsertBillsFrm.dfm

@@ -1,11 +1,10 @@
 object BatchInsertBillsForm: TBatchInsertBillsForm
   Left = 384
   Top = 229
+  Width = 795
+  Height = 420
   BorderIcons = [biSystemMenu]
-  BorderStyle = bsSingle
   Caption = #25209#37327#25554#20837#21518#39033
-  ClientHeight = 382
-  ClientWidth = 779
   Color = clBtnFace
   Font.Charset = ANSI_CHARSET
   Font.Color = clWindowText
@@ -18,12 +17,15 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
   TextHeight = 12
   object pnlButton: TPanel
     Left = 0
-    Top = 354
-    Width = 779
+    Top = 361
+    Width = 787
     Height = 28
     Align = alBottom
     BevelOuter = bvNone
     TabOrder = 0
+    DesignSize = (
+      787
+      28)
     object lblHint: TLabel
       Left = 6
       Top = 8
@@ -43,6 +45,7 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
       Top = 1
       Width = 72
       Height = 23
+      Anchors = [akTop, akRight]
       Caption = #30830'  '#23450
       TabOrder = 0
       OnClick = btnOKClick
@@ -52,6 +55,7 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
       Top = 1
       Width = 72
       Height = 23
+      Anchors = [akTop, akRight]
       Caption = #21462'  '#28040
       ModalResult = 2
       TabOrder = 1
@@ -60,27 +64,30 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
   object pnlAllGrid: TPanel
     Left = 0
     Top = 0
-    Width = 779
-    Height = 354
+    Width = 787
+    Height = 361
     Align = alClient
     BevelOuter = bvNone
     TabOrder = 1
     object pnlPositon_Bills: TPanel
       Left = 0
       Top = 0
-      Width = 480
-      Height = 354
+      Width = 488
+      Height = 361
       Align = alClient
       BevelOuter = bvNone
       TabOrder = 0
       object pnlPosition: TPanel
         Left = 0
         Top = 0
-        Width = 480
-        Height = 194
+        Width = 488
+        Height = 201
         Align = alClient
         BevelOuter = bvNone
         TabOrder = 0
+        DesignSize = (
+          488
+          201)
         object lblPostion: TLabel
           Left = 8
           Top = 8
@@ -95,7 +102,7 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
           ParentFont = False
         end
         object zgPosition: TZJGrid
-          Left = 3
+          Left = 8
           Top = 27
           Width = 474
           Height = 166
@@ -111,12 +118,14 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
           OnCellTextChanged = zgPositionCellTextChanged
           OnCustomPaste = zgPositionCustomPaste
           OnMouseDown = zgPositionMouseDown
+          Anchors = [akLeft, akTop, akRight, akBottom]
         end
         object pnlPositionSpr: TPanel
           Left = 99
           Top = 14
           Width = 378
           Height = 2
+          Anchors = [akLeft, akTop, akRight]
           BevelInner = bvLowered
           BevelOuter = bvNone
           TabOrder = 1
@@ -124,15 +133,18 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
       end
       object pnlBills: TPanel
         Left = 0
-        Top = 194
-        Width = 480
+        Top = 201
+        Width = 488
         Height = 135
         Align = alBottom
         BevelOuter = bvNone
         TabOrder = 1
+        DesignSize = (
+          488
+          135)
         object lblBills: TLabel
           Left = 8
-          Top = 8
+          Top = 1
           Width = 48
           Height = 12
           Caption = #28165#21333#32534#21495
@@ -144,8 +156,8 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
           ParentFont = False
         end
         object zgBills: TZJGrid
-          Left = 2
-          Top = 27
+          Left = 7
+          Top = 22
           Width = 475
           Height = 105
           OptionsEx = []
@@ -159,13 +171,15 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
           FrozenCol = 0
           FrozenRow = 0
           OnCellTextChanged = zgBillsCellTextChanged
-          OnMouseDown = zgPositionMouseDown
+          OnMouseDown = zgBillsMouseDown
+          Anchors = [akLeft, akTop, akRight, akBottom]
         end
         object pnlBillsSpr: TPanel
           Left = 62
-          Top = 14
+          Top = 7
           Width = 414
           Height = 2
+          Anchors = [akLeft, akTop, akRight]
           BevelInner = bvLowered
           BevelOuter = bvNone
           TabOrder = 1
@@ -173,8 +187,8 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
       end
       object pnlOther: TPanel
         Left = 0
-        Top = 329
-        Width = 480
+        Top = 336
+        Width = 488
         Height = 25
         Align = alBottom
         BevelOuter = bvNone
@@ -230,13 +244,16 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
       end
     end
     object pnlDealBills: TPanel
-      Left = 480
+      Left = 488
       Top = 0
       Width = 299
-      Height = 354
+      Height = 361
       Align = alRight
       BevelOuter = bvNone
       TabOrder = 1
+      DesignSize = (
+        299
+        361)
       object lblDealBills: TLabel
         Left = 5
         Top = 8
@@ -254,7 +271,7 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
         Left = 0
         Top = 27
         Width = 295
-        Height = 322
+        Height = 328
         Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection]
         OptionsEx = []
         RowCount = 7
@@ -266,12 +283,14 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
         FrozenCol = 0
         FrozenRow = 0
         OnMouseDown = zgDealBillsMouseDown
+        Anchors = [akLeft, akTop, akRight, akBottom]
       end
       object pnlDealBillsSpr: TPanel
         Left = 58
         Top = 14
         Width = 236
         Height = 2
+        Anchors = [akLeft, akTop, akRight]
         BevelInner = bvLowered
         BevelOuter = bvNone
         TabOrder = 1
@@ -390,6 +409,7 @@ object BatchInsertBillsForm: TBatchInsertBillsForm
     object actnInsertCol: TAction
       Caption = #25554#20837#19968#21015
       OnExecute = actnInsertColExecute
+      OnUpdate = actnInsertColUpdate
     end
   end
 end

+ 38 - 3
Forms/BatchInsertBillsFrm.pas

@@ -53,6 +53,10 @@ type
       Row: Integer);
     procedure dxpmInsertBillsPopup(Sender: TObject);
     procedure actnInsertColExecute(Sender: TObject);
+    procedure zgBillsMouseDown(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: Integer);
+    procedure actnInsertColUpdate(Sender: TObject);
+    procedure FormResize(Sender: TObject);
   private
     FInsertType: TInsertType;
     FBillsCompileData: TBillsCompileData;
@@ -80,7 +84,7 @@ procedure AddLeafBills(ABillsCompileData: TBillsCompileData; AInsertType: TInser
 implementation
 
 uses
-  sdDB, UtilMethods, ProjectData, MainFrm;
+  sdDB, UtilMethods, ProjectData, MainFrm, Globals;
 
 {$R *.dfm}
 
@@ -158,8 +162,11 @@ end;
 procedure TBatchInsertBillsForm.Init(ABillsCompileData: TBillsCompileData;
   AInsertType: TInsertType);
 begin
-  ClientHeight := 382;
-  ClientWidth := 779;
+  ClientHeight := SupportManager.ConfigInfo.BatchInsertFrmHeight;
+  ClientWidth := SupportManager.ConfigInfo.BatchInsertFrmWidth;
+  pnlBills.Height := Trunc((pnlPositon_Bills.Height - pnlOther.Height)/22*9);
+
+  OnResize := FormResize;
 
   FBillsCompileData := ABillsCompileData;
   sgdDealBills.DataView := TProjectData(ABillsCompileData.ProjectData).DealBillsData.sdvDealBills;
@@ -341,7 +348,10 @@ procedure TBatchInsertBillsForm.zgPositionMouseDown(Sender: TObject;
   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
 begin
   if Button = mbRight then
+  begin
+    dxpmInsertBills.Tag := 0;
     dxpmInsertBills.PopupFromCursorPos;
+  end;
 end;
 
 procedure TBatchInsertBillsForm.zgBillsCellTextChanged(Sender: TObject;
@@ -453,4 +463,29 @@ begin
   zgBills.Cells[0, zgBills.RowCount-1].Text := 'Çåµ¥' + IntToStr(zgBills.RowCount-1);
 end;
 
+procedure TBatchInsertBillsForm.zgBillsMouseDown(Sender: TObject;
+  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+begin
+  if Button = mbRight then
+  begin
+    dxpmInsertBills.Tag := 1;
+    dxpmInsertBills.PopupFromCursorPos;
+  end;
+end;
+
+procedure TBatchInsertBillsForm.actnInsertColUpdate(Sender: TObject);
+begin
+  if dxpmInsertBills.Tag = 0 then
+    TAction(Sender).Caption := '²åÈëÒ»ÁÐ'
+  else
+    TAction(Sender).Caption := '²åÈëÒ»ÐÐ';
+end;
+
+procedure TBatchInsertBillsForm.FormResize(Sender: TObject);
+begin
+  SupportManager.ConfigInfo.BatchInsertFrmHeight := ClientHeight;
+  SupportManager.ConfigInfo.BatchInsertFrmWidth := ClientWidth;
+  pnlBills.Height := Trunc((pnlPositon_Bills.Height - pnlOther.Height)/22*9);
+end;
+
 end.

+ 77 - 1
Forms/MainFrm.dfm

@@ -4,6 +4,7 @@ object MainForm: TMainForm
   Width = 750
   Height = 538
   ActiveControl = jpsMainProjectsManager
+  Caption = 'me'
   Color = clBtnFace
   Font.Charset = ANSI_CHARSET
   Font.Color = clWindowText
@@ -390,6 +391,7 @@ object MainForm: TMainForm
           Visible = True
         end
         item
+          BeginGroup = True
           Item = dxsiImportExcel
           Visible = True
         end
@@ -398,6 +400,7 @@ object MainForm: TMainForm
           Visible = True
         end
         item
+          BeginGroup = True
           Item = dxbtnExportCloudTenderFile
           Visible = True
         end
@@ -406,8 +409,18 @@ object MainForm: TMainForm
           Visible = True
         end
         item
+          BeginGroup = True
           Item = dxbtnImportDmf
           Visible = True
+        end
+        item
+          BeginGroup = True
+          Item = dxbtnExportSumBaseFile
+          Visible = True
+        end
+        item
+          Item = dxbtnImportSubTenderGather
+          Visible = True
         end>
     end
     object dxsiEdit: TdxBarSubItem
@@ -625,7 +638,7 @@ object MainForm: TMainForm
       Caption = #20840#37096#35745#31639
       Category = 0
       Hint = #20840#37096#35745#31639
-      Visible = ivNever
+      Visible = ivAlways
       ImageIndex = 15
     end
     object dxbtnNewSubProject: TdxBarButton
@@ -1000,6 +1013,10 @@ object MainForm: TMainForm
         item
           Item = dxbtnTenderPartition
           Visible = True
+        end
+        item
+          Item = dxbtnGatherSubTender
+          Visible = True
         end>
     end
     object dxbtnTenderPartition: TdxBarButton
@@ -1124,6 +1141,53 @@ object MainForm: TMainForm
       Hint = #23450#20301#33267#21488#36134#20998#35299
       Visible = ivAlways
     end
+    object dxbtnGclGatherZJJL: TdxBarButton
+      Caption = #35745#37327#27719#24635#26684#24335
+      Category = 0
+      Hint = #35745#37327#27719#24635#26684#24335
+      Visible = ivAlways
+    end
+    object dxbtnExportSumBaseFile: TdxBarButton
+      Action = actnExportSumBaseFile
+      Category = 0
+      Hint = #23548#20986#24635#21253#22522#20934#25991#20214
+    end
+    object dxbtnGatherSubTender: TdxBarButton
+      Caption = #20998#21253#26631#27573#27719#24635
+      Category = 0
+      Hint = #20998#21253#26631#27573#27719#24635
+      Visible = ivAlways
+      OnClick = dxbtnGatherSubTenderClick
+    end
+    object dxbtnExportTenderError: TdxBarButton
+      Caption = #23548#20986#21333#26631#27573#38169#35823#20449#24687
+      Category = 0
+      Hint = #23548#20986#21333#26631#27573#38169#35823#20449#24687
+      Visible = ivAlways
+    end
+    object dxbtnExportAllError: TdxBarButton
+      Caption = #23548#20986#20840#37096#38169#35823#20449#24687
+      Category = 0
+      Hint = #23548#20986#20840#37096#38169#35823#20449#24687
+      Visible = ivAlways
+    end
+    object dxbtnExportStgResultExcel: TdxBarButton
+      Caption = #23548#20986#20998#21253#27719#24635#32467#26524
+      Category = 0
+      Hint = #23548#20986#20998#21253#27719#24635#32467#26524
+      Visible = ivAlways
+      ImageIndex = 13
+    end
+    object dxbtnExportStgResult: TdxBarButton
+      Caption = #23548#20986#20998#21253#27719#24635#32467#26524
+      Category = 0
+      Hint = #23548#20986#20998#21253#27719#24635#32467#26524
+      Visible = ivAlways
+    end
+    object dxbtnImportSubTenderGather: TdxBarButton
+      Action = actnImportSubTenderGather
+      Category = 0
+    end
   end
   object Images: TImageList
     DrawingStyle = dsTransparent
@@ -3297,6 +3361,18 @@ object MainForm: TMainForm
       OnExecute = actnImportDmfExecute
       OnUpdate = actnImportCloudTenderFileUpdate
     end
+    object actnExportSumBaseFile: TAction
+      Category = 'File'
+      Caption = #23548#20986#24635#21253#22522#20934#25991#20214
+      OnExecute = actnExportSumBaseFileExecute
+      OnUpdate = actnUnlockInfoUpdate
+    end
+    object actnImportSubTenderGather: TAction
+      Category = 'File'
+      Caption = #23548#20837#20998#21253#27719#24635#25968#25454
+      OnExecute = actnImportSubTenderGatherExecute
+      OnUpdate = actnImportSubTenderGatherUpdate
+    end
   end
   object dxpmTabSet: TdxBarPopupMenu
     BarManager = dxBarManager

+ 82 - 2
Forms/MainFrm.pas

@@ -168,6 +168,16 @@ type
     dxbtnLocateZJJL: TdxBarButton;
     dxbtnEpure: TdxBarButton;
     dxbtnLocateCompileBills: TdxBarButton;
+    dxbtnGclGatherZJJL: TdxBarButton;
+    dxbtnExportSumBaseFile: TdxBarButton;
+    actnExportSumBaseFile: TAction;
+    dxbtnGatherSubTender: TdxBarButton;
+    dxbtnExportTenderError: TdxBarButton;
+    dxbtnExportAllError: TdxBarButton;
+    dxbtnExportStgResultExcel: TdxBarButton;
+    dxbtnExportStgResult: TdxBarButton;
+    dxbtnImportSubTenderGather: TdxBarButton;
+    actnImportSubTenderGather: TAction;
     procedure FormCreate(Sender: TObject);
     procedure FormDestroy(Sender: TObject);
     procedure jtsProjectsChange(Sender: TObject; NewTab: Integer;
@@ -213,6 +223,10 @@ type
     procedure dxbtnTenderPartitionClick(Sender: TObject);
     procedure actnImportDmfExecute(Sender: TObject);
     procedure dxbtnHelpCenterClick(Sender: TObject);
+    procedure actnExportSumBaseFileExecute(Sender: TObject);
+    procedure dxbtnGatherSubTenderClick(Sender: TObject);
+    procedure actnImportSubTenderGatherExecute(Sender: TObject);
+    procedure actnImportSubTenderGatherUpdate(Sender: TObject);
   private
     FProjectManagerFrame: TProjectManagerFrame;
     FProjectFrames: TList;
@@ -250,7 +264,8 @@ uses
   ProjectProperty, ConstUnit, PHPWebDm, Math, ShellAPI,
   FindUserFrm, ImportExcelHintFrm, ConfigDoc, ExportExcel,
   ProjectCommands, BillsCompileDm, tpMainFrm,
-  DealBillsExcelImport, ExcelImport_Bills, DetailExcelImport;
+  DealBillsExcelImport, ExcelImport_Bills, DetailExcelImport,
+  stgGatherControl, stgSelectFileFrm;
 
 {$R *.dfm}
 {$R MeasureIcons.RES}
@@ -380,6 +395,8 @@ begin
   ClearObjects(FProjectFrames);
   FProjectFrames.Free;
   FProjectManagerFrame.Free;
+  if DirectoryExists(GetAppTempPath) then
+    DeleteFileOrFolder(GetAppTempPath);
 end;
 
 function TMainForm.OpenProject(ARec: TsdDataRecord): TProjectFrame;
@@ -642,7 +659,7 @@ begin
 end;
 
 procedure TMainForm.actnUnlockInfoUpdate(Sender: TObject);
-begin
+begin                       
   TAction(Sender).Enabled := (jtsProjects.Tabs.Count > 1) and Assigned(CurProjectFrame);
 end;
 
@@ -872,4 +889,67 @@ begin
   MeasureLog.AppendLogTo(AE.Message);
 end;
 
+procedure TMainForm.actnExportSumBaseFileExecute(Sender: TObject);
+var
+  sFileName: string;
+  Exportor: TTenderExport;
+  Rec: TsdDataRecord;
+begin
+  // 导出前先保存
+  CurProjectFrame.ProjectData.SaveAndCheck;
+  // 导出云版专用
+  sFileName := SupportManager.ConfigInfo.OutputPath + CurProjectFrame.ProjectData.ProjectName + '.sbf';
+  if SaveFile(sFileName, '.sbf') then
+  begin
+    if FileExists(sFileName) and not QuestMessage(Format('存在同名文件“%s”,是否替换?', [ExtractFileName(sFileName)])) then
+      Exit;
+
+    Screen.Cursor := crHourGlass;
+    try
+      Rec := ProjectManagerFrame.Rec(CurProjectFrame.ProjectData.ProjectID);
+      Exportor := TTenderExport.Create(Rec, sFileName);
+      try
+        Exportor.Execute;
+      finally
+        Exportor.Free;
+      end;
+    finally
+      Screen.Cursor := crDefault;
+    end;
+  end;
+end;
+
+procedure TMainForm.dxbtnGatherSubTenderClick(Sender: TObject);
+var
+  gc: TstgGatherControl;
+begin
+  gc := TstgGatherControl.Create;
+  Screen.Cursor := crHourGlass;
+  try
+    if SelectFileForSubTenderGather(gc) then
+      gc.Gather;
+  finally
+    gc.Free;
+    Screen.Cursor := crDefault;
+  end;
+end;
+
+procedure TMainForm.actnImportSubTenderGatherExecute(Sender: TObject);
+var
+  sFileName: string;
+begin
+  if CurProjectFrame.ProjectData.ProjProperties.PhaseCount = 0 then
+    WarningMessage('未开始计量,请在开始计量后再导入分包汇总数据。')
+  else if CurProjectFrame.ProjectData.StageDataReadOnly then
+    WarningMessage('当前正在查看数据非最新数据,请切换至最新一期再导入分包汇总数据。')
+  else if QuestMessage('导入将清空标段本期所有计量数据(合同计量、数量变更计量),确定继续?') and SelectFile(sFileName, '.sgf') then
+    CurProjectFrame.ProjectData.ImportSubTenderGather(sFileName);
+end;
+
+procedure TMainForm.actnImportSubTenderGatherUpdate(Sender: TObject);
+begin
+  TAction(Sender).Enabled := (jtsProjects.Tabs.Count > 1) and Assigned(CurProjectFrame)
+    and (CurProjectFrame.ProjectData.PhaseData.StageCount <= 1);
+end;
+
 end.

+ 187 - 105
Forms/ProjectPropertiesFrm.dfm

@@ -1,7 +1,6 @@
 object ProjectPropertiesForm: TProjectPropertiesForm
   Left = 663
   Top = 261
-  ActiveControl = leProjectName
   BorderIcons = [biSystemMenu]
   BorderStyle = bsSingle
   Caption = #39033#30446#23646#24615
@@ -120,8 +119,8 @@ object ProjectPropertiesForm: TProjectPropertiesForm
     Top = 63
     Width = 530
     Height = 255
-    ActivePage = jpsPropertiesBase
-    ActivePageIndex = 0
+    ActivePage = jpsPropertiesView
+    ActivePageIndex = 2
     Align = alTop
     Caption = 'jpsProperties'
     object jpsPropertiesBase: TJimPage
@@ -1247,120 +1246,166 @@ object ProjectPropertiesForm: TProjectPropertiesForm
         Left = 8
         Top = 24
         Width = 505
-        Height = 113
+        Height = 105
         BevelOuter = bvNone
         TabOrder = 1
-        object pnlAlias: TPanel
+        object pnlViewPart1: TPanel
           Left = 0
-          Top = 75
-          Width = 505
-          Height = 25
-          Align = alTop
+          Top = 0
+          Width = 249
+          Height = 105
+          Align = alLeft
           BevelOuter = bvNone
           TabOrder = 0
-          object cbShowAlias: TCheckBox
-            Left = 33
-            Top = 8
-            Width = 80
-            Height = 17
-            Hint = #25511#21046#21464#26356#21333#20215#12289#26412#26399#21333#20215#21464#26356#21015#26174#31034
-            Caption = #21035#21517
-            Ctl3D = False
-            Font.Charset = ANSI_CHARSET
-            Font.Color = clWindowText
-            Font.Height = -12
-            Font.Name = #23435#20307
-            Font.Style = []
-            ParentCtl3D = False
-            ParentFont = False
-            ParentShowHint = False
-            ShowHint = True
+          object pnlAlias: TPanel
+            Left = 0
+            Top = 25
+            Width = 249
+            Height = 25
+            Align = alTop
+            BevelOuter = bvNone
             TabOrder = 0
+            object cbShowAlias: TCheckBox
+              Left = 33
+              Top = 8
+              Width = 80
+              Height = 17
+              Hint = #25511#21046#21035#21517#21015#26174#31034
+              Caption = #21035#21517
+              Ctl3D = False
+              Font.Charset = ANSI_CHARSET
+              Font.Color = clWindowText
+              Font.Height = -12
+              Font.Name = #23435#20307
+              Font.Style = []
+              ParentCtl3D = False
+              ParentFont = False
+              ParentShowHint = False
+              ShowHint = True
+              TabOrder = 0
+            end
           end
-        end
-        object pnlPriceChange: TPanel
-          Left = 0
-          Top = 0
-          Width = 505
-          Height = 25
-          Align = alTop
-          BevelOuter = bvNone
-          TabOrder = 1
-          Visible = False
-          object cbShowPriceChange: TCheckBox
-            Left = 33
-            Top = 8
-            Width = 88
-            Height = 17
-            Hint = #25511#21046#21464#26356#21333#20215#12289#26412#26399#21333#20215#21464#26356#21015#26174#31034
-            Caption = #21333#20215#21464#26356
-            Ctl3D = False
-            Font.Charset = ANSI_CHARSET
-            Font.Color = clWindowText
-            Font.Height = -12
-            Font.Name = #23435#20307
-            Font.Style = []
-            ParentCtl3D = False
-            ParentFont = False
-            ParentShowHint = False
-            ShowHint = True
-            TabOrder = 0
+          object pnlBGL: TPanel
+            Left = 0
+            Top = 75
+            Width = 249
+            Height = 25
+            Align = alTop
+            BevelOuter = bvNone
+            TabOrder = 1
+            object cbShowBGLCode: TCheckBox
+              Left = 33
+              Top = 8
+              Width = 80
+              Height = 17
+              Hint = #25511#21046#21464#26356#20196#21015#26174#31034
+              Caption = #21464#26356#20196
+              Ctl3D = False
+              Font.Charset = ANSI_CHARSET
+              Font.Color = clWindowText
+              Font.Height = -12
+              Font.Name = #23435#20307
+              Font.Style = []
+              ParentCtl3D = False
+              ParentFont = False
+              ParentShowHint = False
+              ShowHint = True
+              TabOrder = 0
+            end
           end
-        end
-        object pnlBGL: TPanel
-          Left = 0
-          Top = 25
-          Width = 505
-          Height = 25
-          Align = alTop
-          BevelOuter = bvNone
-          TabOrder = 2
-          object cbShowBGLCode: TCheckBox
-            Left = 33
-            Top = 8
-            Width = 80
-            Height = 17
-            Hint = #25511#21046#21464#26356#21333#20215#12289#26412#26399#21333#20215#21464#26356#21015#26174#31034
-            Caption = #21464#26356#20196
-            Ctl3D = False
-            Font.Charset = ANSI_CHARSET
-            Font.Color = clWindowText
-            Font.Height = -12
-            Font.Name = #23435#20307
-            Font.Style = []
-            ParentCtl3D = False
-            ParentFont = False
-            ParentShowHint = False
-            ShowHint = True
-            TabOrder = 0
+          object pnlDesignQuantity: TPanel
+            Left = 0
+            Top = 50
+            Width = 249
+            Height = 25
+            Align = alTop
+            BevelOuter = bvNone
+            TabOrder = 2
+            object cbShowDesignQuantity: TCheckBox
+              Left = 33
+              Top = 8
+              Width = 80
+              Height = 17
+              Hint = #25511#21046#35774#35745#25968#37327#21015#26174#31034
+              Caption = #35774#35745#25968#37327
+              Ctl3D = False
+              Font.Charset = ANSI_CHARSET
+              Font.Color = clWindowText
+              Font.Height = -12
+              Font.Name = #23435#20307
+              Font.Style = []
+              ParentCtl3D = False
+              ParentFont = False
+              ParentShowHint = False
+              ShowHint = True
+              TabOrder = 0
+            end
+          end
+          object pnlPriceChange: TPanel
+            Left = 0
+            Top = 0
+            Width = 249
+            Height = 25
+            Align = alTop
+            BevelOuter = bvNone
+            TabOrder = 3
+            Visible = False
+            object cbShowPriceChange: TCheckBox
+              Left = 33
+              Top = 8
+              Width = 88
+              Height = 17
+              Hint = #25511#21046#21464#26356#21333#20215#12289#26412#26399#21333#20215#21464#26356#21015#26174#31034
+              Caption = #21333#20215#21464#26356
+              Ctl3D = False
+              Font.Charset = ANSI_CHARSET
+              Font.Color = clWindowText
+              Font.Height = -12
+              Font.Name = #23435#20307
+              Font.Style = []
+              ParentCtl3D = False
+              ParentFont = False
+              ParentShowHint = False
+              ShowHint = True
+              TabOrder = 0
+            end
           end
         end
-        object pnlDesignQuantity: TPanel
-          Left = 0
-          Top = 50
-          Width = 505
-          Height = 25
-          Align = alTop
+        object pnlViewPart2: TPanel
+          Left = 249
+          Top = 0
+          Width = 256
+          Height = 105
+          Align = alClient
           BevelOuter = bvNone
-          TabOrder = 3
-          object cbShowDesignQuantity: TCheckBox
-            Left = 33
-            Top = 8
-            Width = 80
-            Height = 17
-            Hint = #25511#21046#21464#26356#21333#20215#12289#26412#26399#21333#20215#21464#26356#21015#26174#31034
-            Caption = #35774#35745#25968#37327
-            Ctl3D = False
-            Font.Charset = ANSI_CHARSET
-            Font.Color = clWindowText
-            Font.Height = -12
-            Font.Name = #23435#20307
-            Font.Style = []
-            ParentCtl3D = False
-            ParentFont = False
-            ParentShowHint = False
-            ShowHint = True
+          TabOrder = 1
+          object pnlApprovalCode: TPanel
+            Left = 0
+            Top = 0
+            Width = 256
+            Height = 25
+            Align = alTop
+            BevelOuter = bvNone
             TabOrder = 0
+            object cbShowApprovalCode: TCheckBox
+              Left = 33
+              Top = 8
+              Width = 88
+              Height = 17
+              Hint = #25511#21046#25209#22797#32534#21495#21015#26174#31034
+              Caption = #25209#22797#32534#21495
+              Ctl3D = False
+              Font.Charset = ANSI_CHARSET
+              Font.Color = clWindowText
+              Font.Height = -12
+              Font.Name = #23435#20307
+              Font.Style = []
+              ParentCtl3D = False
+              ParentFont = False
+              ParentShowHint = False
+              ShowHint = True
+              TabOrder = 0
+            end
           end
         end
       end
@@ -1443,6 +1488,43 @@ object ProjectPropertiesForm: TProjectPropertiesForm
           TabOrder = 3
         end
       end
+      object pnlOverRange: TPanel
+        Left = 1
+        Top = 197
+        Width = 529
+        Height = 45
+        BevelOuter = bvNone
+        TabOrder = 6
+        object Label1: TLabel
+          Left = 7
+          Top = 5
+          Width = 48
+          Height = 12
+          Caption = #36229#35745#21151#33021
+          Font.Charset = ANSI_CHARSET
+          Font.Color = clBlue
+          Font.Height = -12
+          Font.Name = #23435#20307
+          Font.Style = []
+          ParentFont = False
+        end
+        object Panel2: TPanel
+          Left = 64
+          Top = 11
+          Width = 455
+          Height = 2
+          BevelOuter = bvLowered
+          TabOrder = 0
+        end
+        object cbShowOverRange: TCheckBox
+          Left = 40
+          Top = 26
+          Width = 121
+          Height = 17
+          Caption = #24213#33394#26631#32418#25552#31034
+          TabOrder = 1
+        end
+      end
     end
   end
   object xpm: TXPMenu

+ 12 - 0
Forms/ProjectPropertiesFrm.pas

@@ -132,6 +132,14 @@ type
     leCLegal_2: TLabeledEdit;
     leCDate_2: TLabeledEdit;
     lblConstructor_2: TLabel;
+    pnlOverRange: TPanel;
+    Label1: TLabel;
+    Panel2: TPanel;
+    cbShowOverRange: TCheckBox;
+    pnlViewPart1: TPanel;
+    pnlViewPart2: TPanel;
+    pnlApprovalCode: TPanel;
+    cbShowApprovalCode: TCheckBox;
     procedure btnOkClick(Sender: TObject);
     procedure leContractPriceClick(Sender: TObject);
     procedure msbBaseMouseWheel(Sender: TObject; Shift: TShiftState;
@@ -250,6 +258,8 @@ begin
   cbShowBGLCode.Checked := FProjProperties.ShowBGLCode;
   cbShowDesignQuantity.Checked := FProjProperties.ShowDesignQuantity;
   cbShowAlias.Checked := FProjProperties.ShowAlias;
+  cbShowOverRange.Checked := FProjProperties.ShowOverRange;
+  cbShowApprovalCode.Checked := FProjProperties.ShowApprovalCode;
 
   cbShowReportShading.Checked := FProjProperties.ShowReportShading;
   edtReportShading.Enabled := cbShowReportShading.Checked;
@@ -657,6 +667,8 @@ begin
   FProjProperties.ShowBGLCode := cbShowBGLCode.Checked;
   FProjProperties.ShowDesignQuantity := cbShowDesignQuantity.Checked;
   FProjProperties.ShowAlias := cbShowAlias.Checked;
+  FProjProperties.ShowOverRange := cbShowOverRange.Checked;
+  FProjProperties.ShowApprovalCode := cbShowApprovalCode.Checked;
   // ˢнçÃæÏÔʾ
   FProjectFrame.RefreshColumnDisplay;
 end;

+ 1 - 1
Forms/ReportsFrm.dfm

@@ -296,7 +296,7 @@ object ReportsForm: TReportsForm
     Font.Charset = DEFAULT_CHARSET
     Font.Color = clWindowText
     Font.Height = -12
-    Font.Name = #24494#36719#38597#40657
+    Font.Name = 'Microsoft YaHei UI'
     Font.Style = []
     Bars = <
       item

+ 3 - 1
Forms/ReportsFrm.pas

@@ -125,7 +125,7 @@ type
     function GetClassNode(ANode: TTemplateNode): TExTreeNode;
     function GetSubClassNode(AClassNode: TExTreeNode; ANode: TTemplateNode): TExTreeNode;
     procedure AddReportTemplate(ANode: TTemplateNode);
-	procedure LoadReportTemplets;
+  	procedure LoadReportTemplets;
 
     procedure SaveAuditOpinion(ATemplate: TTemplateNode);
     procedure SaveReportInteractData(ATemplate: TTemplateNode);
@@ -202,6 +202,8 @@ begin
   ReportsForm.InitReportSettings(ReportsForm.PreviewComXML);
   ReportsForm.InitFormView;
   try
+    if not _IsDebugView then
+      ReportsForm.extvReport.OnKeyDown := nil;
     ReportsForm.ShowModal;
   finally
     ReportsForm.Free;

+ 1 - 1
Forms/SignOnlineReportsFrm.pas

@@ -192,7 +192,7 @@ begin
   FSignPhase := ASignPhase;
 
   FProjectData := TProjectData.Create;
-  FProjectData.OpenForSignOnline(GetMyProjectsFilePath + AProjNode.Rec.ValueByName('FileName').AsString, ASignPhase);
+  FProjectData.OpenForSignOnline(AProjNode.Rec, ASignPhase);
   FReportDataPrepare := TReportPrepare.Create(FProjectData);
   FReportCon := TReportConnection.Create(FProjectData);
 

+ 3 - 0
Frames/BGLFme.dfm

@@ -336,6 +336,8 @@ object BGLFrame: TBGLFrame
       end>
     Grid = zgBGL
     ExtendRowCount = 1
+    Options = [aoAllowEdit, aoAllowDelete, aoAllowUpMove, aoAllowDownMove]
+    OnGridCellCanEdit = zaBGLGridCellCanEdit
     Left = 96
     Top = 88
   end
@@ -470,6 +472,7 @@ object BGLFrame: TBGLFrame
     Grid = zgBGBills
     ExtendRowCount = 1
     OnGridSetCellText = zaBGBillsGridSetCellText
+    OnGridCellCanEdit = zaBGBillsGridCellCanEdit
     Left = 96
     Top = 456
   end

+ 56 - 1
Frames/BGLFme.pas

@@ -57,6 +57,11 @@ type
     procedure zgBGLEditorLoadCell(Sender: TObject; ACoord: TPoint;
       AControl: TWinControl);
     procedure zgBGLCellTextChanged(Sender: TObject; Col, Row: Integer);
+    procedure zaBGLGridCellCanEdit(Sender: TObject; const ACoord: TPoint;
+      var Allow: Boolean);
+    procedure zaBGBillsGridCellCanEdit(Sender: TObject;
+      const ACoord: TPoint; var Allow: Boolean);
+    procedure zgBGLCurrentChanged;
   private
     FBGLData: TBGLData;
 
@@ -64,13 +69,15 @@ type
     procedure PasteBGLBlock;
   public
     constructor Create(AParent: TFrame; ABGLData: TBGLData);
+
+    procedure LoadBGLFromCloud;
   end;
 
 implementation
 
 uses
   UtilMethods, MergeTextFrm, ProjectData, MainFrm, mEncryptEditions,
-  BGLClipboard, ConditionalDefines, ZjCells;
+  BGLClipboard, ConditionalDefines, ZjCells, PHPWebDm;
 
 {$R *.dfm}
 
@@ -91,6 +98,15 @@ begin
   dbmDirection.DataSource := FBGLData.dsBGL;
   zaBGBills.DataSet := FBGLData.cdsBGBillsView;
   SetDxBtnAction(actnNew, tobtnNew);
+
+  if _IsCloud then
+  begin
+    zaBGL.Options := [aoAllowEdit, aoAllowDelete, aoAllowUpMove, aoAllowDownMove];
+    zaBGL.ExtendRowCount := 0;
+    FBGLData.AfterCurrentBGLChanged := zgBGLCurrentChanged;
+  end
+  else
+    zaBGL.Options := [aoAllowInsert, aoAllowEdit, aoAllowDelete, aoAutoInsert, aoAllowUpMove, aoAllowDownMove];
 end;
 
 procedure TBGLFrame.actnNewExecute(Sender: TObject);
@@ -248,4 +264,43 @@ begin
   end;
 end;
 
+procedure TBGLFrame.LoadBGLFromCloud;
+var
+  sgs: TStrings;
+  sUrl, sInfo: string;
+begin
+  Screen.Cursor := crHourGlass;
+  sgs := TStringList.Create;
+  try
+    sgs.Add(Format('filter=%s', [FBGLData.AllCloudBGLWebID]));
+    sUrl := PHPWeb.MeasureURL + Format('change/get/%d/list', [TProjectData(FBGLData.ProjectData).WebID]);
+    if PHPWeb.UrlGet(sUrl, sgs, sInfo) = 1 then
+      FBGLData.LoadCloudBGL(sInfo)
+    else if sInfo <> '' then
+      WarningMessage(sInfo);
+  finally
+    Screen.Cursor := crDefault;
+  end;
+end;
+
+procedure TBGLFrame.zaBGLGridCellCanEdit(Sender: TObject;
+  const ACoord: TPoint; var Allow: Boolean);
+begin
+  if _IsCloud and Allow then
+    Allow := FBGLData.GetBGLCanEdit(ACoord.Y - zgBGL.FixedRowCount);
+end;
+
+procedure TBGLFrame.zaBGBillsGridCellCanEdit(Sender: TObject;
+  const ACoord: TPoint; var Allow: Boolean);
+begin
+  if _IsCloud and Allow then
+    Allow := not FBGLData.cdsBGLViewIsCloud.AsBoolean;
+end;
+
+procedure TBGLFrame.zgBGLCurrentChanged;
+begin
+  dbmPos_Reason.ReadOnly := _IsCloud and FBGLData.cdsBGLViewIsCloud.AsBoolean;
+  dbmDirection.ReadOnly := dbmPos_Reason.ReadOnly;
+end;
+
 end.

+ 50 - 11
Frames/BillsCompileFme.dfm

@@ -53,7 +53,7 @@ object BillsCompileFrame: TBillsCompileFrame
       Height = 376
       Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection, goShowTreeLine]
       OptionsEx = []
-      ColCount = 23
+      ColCount = 25
       RowCount = 7
       FixedRowCount = 3
       ShowGridLine = False
@@ -174,6 +174,26 @@ object BillsCompileFrame: TBillsCompileFrame
   object stdBillsCompile: TsdGridTreeDBA
     Columns = <
       item
+        Title.Caption = #35745#37327#27719#24635
+        Title.CaptionAcrossCols = '1'
+        Title.CaptionAcrossRows = 3
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taCenter
+        EditType = sgeCheckBox
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'IsGatherZJJL'
+        Width = 35
+        ReadOnly = False
+      end
+      item
         Title.Caption = #39033#30446#33410#32534#21495
         Title.CaptionAcrossCols = '1'
         Title.CaptionAcrossRows = 3
@@ -544,6 +564,24 @@ object BillsCompileFrame: TBillsCompileFrame
         ReadOnly = False
       end
       item
+        Title.Caption = #25209#22797#32534#21495
+        Title.CaptionAcrossCols = '1'
+        Title.CaptionAcrossRows = 3
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'ApprovalCode'
+        ReadOnly = False
+      end
+      item
         Title.Caption = #22791#27880
         Title.CaptionAcrossCols = '1'
         Title.CaptionAcrossRows = 3
@@ -640,7 +678,7 @@ object BillsCompileFrame: TBillsCompileFrame
         ReadOnly = False
       end
       item
-        Title.Caption = 'ID'
+        Title.Caption = 'ChapterParentID'
         Title.CaptionAcrossCols = '1'
         Title.CaptionAcrossRows = 3
         Title.Font.Charset = GB2312_CHARSET
@@ -654,13 +692,13 @@ object BillsCompileFrame: TBillsCompileFrame
         Font.Height = -12
         Font.Name = #23435#20307
         Font.Style = []
-        FieldName = 'ID'
+        FieldName = 'ChapterParentID'
         Width = 50
         Visible = False
-        ReadOnly = True
+        ReadOnly = False
       end
       item
-        Title.Caption = 'ParentID'
+        Title.Caption = 'ID'
         Title.CaptionAcrossCols = '1'
         Title.CaptionAcrossRows = 3
         Title.Font.Charset = GB2312_CHARSET
@@ -674,13 +712,13 @@ object BillsCompileFrame: TBillsCompileFrame
         Font.Height = -12
         Font.Name = #23435#20307
         Font.Style = []
-        FieldName = 'ParentID'
+        FieldName = 'ID'
         Width = 50
         Visible = False
         ReadOnly = True
       end
       item
-        Title.Caption = 'NextSiblingID'
+        Title.Caption = 'ParentID'
         Title.CaptionAcrossCols = '1'
         Title.CaptionAcrossRows = 3
         Title.Font.Charset = GB2312_CHARSET
@@ -694,13 +732,13 @@ object BillsCompileFrame: TBillsCompileFrame
         Font.Height = -12
         Font.Name = #23435#20307
         Font.Style = []
-        FieldName = 'NextSiblingID'
+        FieldName = 'ParentID'
         Width = 50
         Visible = False
         ReadOnly = True
       end
       item
-        Title.Caption = 'ChapterParentID'
+        Title.Caption = 'NextSiblingID'
         Title.CaptionAcrossCols = '1'
         Title.CaptionAcrossRows = 3
         Title.Font.Charset = GB2312_CHARSET
@@ -714,14 +752,15 @@ object BillsCompileFrame: TBillsCompileFrame
         Font.Height = -12
         Font.Name = #23435#20307
         Font.Style = []
-        FieldName = 'ChapterParentID'
+        FieldName = 'NextSiblingID'
         Width = 50
         Visible = False
-        ReadOnly = False
+        ReadOnly = True
       end>
     Grid = zgBillsCompile
     ExtendRowCount = 3
     AutoExpand = False
+    TreeCellCol = 2
     KeyFieldName = 'ID'
     ParentFieldName = 'ParentID'
     NextSiblingFieldName = 'NextSiblingID'

+ 24 - 1
Frames/BillsCompileFme.pas

@@ -76,6 +76,7 @@ type
 
     FOnAfterSetBookmark: TBookmarkRefreshEvent;
     FShowAlias: Boolean;
+    FShowApprovalCode: Boolean;
 
     procedure CopyBillsBlock(ANode: TsdIDTreeNode; ABounds: TRect);
     procedure PasteBillsBlock(ANode: TsdIDTreeNode; ABounds: TRect);
@@ -90,11 +91,14 @@ type
     procedure ResetBaseDataReadOnly(AReadOnly: Boolean);
     procedure ResetAllowInsert(AAllow: Boolean);
 
+    procedure RefreshTreeRow(ARowIndex: Integer);
+
     function CheckExprsColumn: Boolean;
     function CheckMemoStrColumn: Boolean;
 
     procedure SetShowDesignQuantity(const Value: Boolean);
     procedure SetShowAlias(const Value: Boolean);
+    procedure SetShowApprovalCode(const Value: Boolean);
   public
     constructor Create(AParent: TFrame; ABillsCompileData: TBillsCompileData);
     destructor Destroy; override;
@@ -107,6 +111,7 @@ type
 
     property ShowDesignQuantity: Boolean read FShowDesginQuantity write SetShowDesignQuantity;
     Property ShowAlias: Boolean read FShowAlias write SetShowAlias;
+    property ShowApprovalCode: Boolean read FShowApprovalCode write SetShowApprovalCode;
 
     property OnAfterSetBookmark: TBookmarkRefreshEvent read FOnAfterSetBookmark write FOnAfterSetBookmark;
     property BillsCompileData: TBillsCompileData read FBillsCompileData;
@@ -116,7 +121,8 @@ implementation
 
 uses
   MainFrm, BatchInsertBillsFrm, ExportExcel, ProjectData, mEncryptEditions,
-  ExcelImport, DetailExcelImport, mDataRecord, ExcelImport_GclBills;
+  ExcelImport, DetailExcelImport, mDataRecord, ExcelImport_GclBills,
+  ConditionalDefines;
 
 {$R *.dfm}
 
@@ -228,8 +234,14 @@ begin
   FBillsCompileData := ABillsCompileData;
   stdBillsCompile.IDTree := FBillsCompileData.BillsCompileTree;
   with TProjectData(FBillsCompileData.ProjectData) do
+  begin
     stdBillsCompile.Column('LockedInfo').ReadOnly := ProjProperties.PhaseCount > 0;
+  end;
   zgBillsCompile.OnExpandMouseDown := ExpandMouseDown;
+  FBillsCompileData.RefreshRow := RefreshTreeRow;
+  
+  if not _IsDebugView then
+    zgBillsCompile.OnKeyDown := nil;
 end;
 
 destructor TBillsCompileFrame.Destroy;
@@ -713,4 +725,15 @@ begin
   Result := (iCol = stdBillsCompile.VisibleCol('MemoStr'));
 end;
 
+procedure TBillsCompileFrame.SetShowApprovalCode(const Value: Boolean);
+begin
+  FShowApprovalCode := Value;
+  stdBillsCompile.Column('ApprovalCode').Visible := FShowApprovalCode;
+end;
+
+procedure TBillsCompileFrame.RefreshTreeRow(ARowIndex: Integer);
+begin
+  zgBillsCompile.InvalidateRow(ARowIndex + zgBillsCompile.FixedRowCount);
+end;
+
 end.

+ 630 - 3
Frames/BillsGatherFme.dfm

@@ -20,9 +20,9 @@ object BillsGatherFrame: TBillsGatherFrame
   end
   object pnlBillsGather: TPanel
     Left = 0
-    Top = 0
+    Top = 20
     Width = 1477
-    Height = 378
+    Height = 358
     Align = alClient
     BevelOuter = bvNone
     TabOrder = 0
@@ -30,7 +30,7 @@ object BillsGatherFrame: TBillsGatherFrame
       Left = 0
       Top = 0
       Width = 1477
-      Height = 378
+      Height = 358
       Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection, goShowTreeLine]
       OptionsEx = []
       ColCount = 29
@@ -194,6 +194,633 @@ object BillsGatherFrame: TBillsGatherFrame
       end
     end
   end
+  object pnlTop: TPanel
+    Left = 0
+    Top = 0
+    Width = 1477
+    Height = 20
+    Align = alTop
+    BevelOuter = bvNone
+    TabOrder = 2
+    object btnUploadBillsList: TCslButton
+      Left = 0
+      Top = 1
+      Width = 111
+      Height = 19
+      Enabled = True
+      PicNormal.Data = {
+        07544269746D617026190000424D261900000000000036000000280000006F00
+        0000130000000100180000000000F0180000120B0000120B0000000000000000
+        0000D35203D25000D25000D25000D25000D25000D25000D25000D25000D25000
+        D25000D25000D25000D25000D25000D25000D25000D25000D25000D25000D250
+        00D25000D25000D25000D25000D25000D25000D25000D25000D25000D25000D2
+        5000D25000D25000D25000D25000D25000D25000D25000D25000D25000D25000
+        D25000D25000D25000D25000D25000D25000D25000D25000D25000D25000D250
+        00D25000D25000D25000D25000D25000D25000D25000D25000D25000D25000D2
+        5000D25000D25000D25000D25000D25000D25000D25000D25000D25000D25000
+        D25000D25000D25000D25000D25000D25000D25000D25000D25000D25000D250
+        00D25000D25000D25000D25000D25000D25000D25000D25000D25000D25000D2
+        5000D25000D25000D25000D25000D25000D25000D25000D25000D25000D25000
+        D25000D25000D25000D25000D35203000D00D25303D35300D35200D35200D352
+        00D35200D35200D35200D35200D35200D35200D35200D35200D35200D35200D3
+        5200D35200D35200D35200D35200D35200D35200D35200D35200D35200D35200
+        D35200D35200D35200D35200D35200D35200D35200D35200D35200D35200D352
+        00D35200D35200D35200D35200D35200D35200D35200D35200D35200D35200D3
+        5200D35200D35200D35200D35200D35200D35200D35200D35200D35200D35200
+        D35200D35200D35200D35200D35200D35200D35200D35200D35200D35200D352
+        00D35200D35200D35200D35200D35200D35200D35200D35200D35200D35200D3
+        5200D35200D35200D35200D35200D35200D35200D35200D35200D35200D35200
+        D35200D35200D35200D35200D35200D35200D35200D35200D35200D35200D352
+        00D35200D35200D35200D35200D35200D35200D35200D35200D35300D253034E
+        7939D15403D35600D35500D35500D35500D35500D35500D35500D35500D35500
+        D35500D35500D35500D35500D35500D35500D35500D35500D35500D35500D355
+        00D35500D35500D35500D35500D35500D35500D35500D35500D35500D35500D3
+        5500D35500D35500D35500D35500D35500D35500D35500D35500D35500D35500
+        D35500D35500D35500D35500D35500D35500D35500D35500D35500D35500D355
+        00D35500D35500D35500D35500D35500D35500D35500D35500D35500D35500D3
+        5500D35500D35500D35500D35500D35500D35500D35500D35500D35500D35500
+        D35500D35500D35500D35500D35500D35500D35500D35500D35500D35500D355
+        00D35500D35500D35500D35500D35500D35500D35500D35500D35500D35500D3
+        5500D35500D35500D35500D35500D35500D35500D35500D35500D35500D35500
+        D35500D35500D35500D35600D154038FDEA3D05603D35900D35800D35800D358
+        00DE8535DE8535DE8535DE8535DE8535DE8535DE8535DE8535DE8535DE8535DE
+        8535DE8535D35800D35800D35800D35800D35800FFFFFFD35800D35800D35800
+        D35800D35800D35800FFFFFFFFFFFFFFFFFFD35800D35800FFFFFFFFFFFFFFFF
+        FFD35800D35800D35800D35800D35800D35800D35800D35800D35800D35800D3
+        5800FFFFFFD35800D35800D35800D35800FFFFFFFFFFFFD35800D35800D35800
+        D35800D35800D35800D35800FFFFFFD35800D35800D35800D35800D35800D358
+        00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFD35800D35800D35800D35800D35800D35800D35800D35800D35800D35800
+        FFFFFFD35800D35800D35800D35800D35800D35800FFFFFFD35800D35800D358
+        00D35800FFFFFFFFFFFFD35800D35800D35800D35800D35800D35900D05603B9
+        7265CF5703D35E00D35D00D35D00D35D00E2AE83E2AE82E2AE82E2AE82E2AE82
+        E2AE82E2AE82E2AE82E2AE82E2AE82E2AE82E2AE82D35D00D35D00D35D00D35D
+        00D35D00FFFFFFD35D00D35D00D35D00D35D00D35D00D35D00984100984100FF
+        FFFFD35D00D35D00984100984100984100FFFFFFFFFFFFD35D00D35D00D35D00
+        D35D00D35D00D35D00FFFFFFD35D00D35D00FFFFFFD35D00D35D00D35D00D35D
+        00984100FFFFFFD35D00D35D00D35D00D35D00D35D00D35D00D35D00FFFFFFD3
+        5D00D35D00D35D00D35D00D35D00D35D00984100984100984100984100984100
+        FFFFFF984100984100984100984100984100D35D00D35D00FFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD35D00D35D00FFFFFFFFFFFFD3
+        5D00D35D00FFFFFFD35D00FFFFFFD35D00FFFFFF984100FFFFFFD35D00D35D00
+        D35D00D35D00D35D00D35E00CF570327352ECE5903D36200D36100D36100D361
+        00EED7C4EED7C4EED7C4EED7C4EED7C4EED7C4EED7C4EED7C4EED7C4EED7C4EE
+        D7C4EED7C4D36100D36100D36100D36100D36100FFFFFFD36100D36100D36100
+        D36100D36100D36100D36100D36100FFFFFFD36100D36100FFFFFFD36100D361
+        00984400FFFFFFFFFFFFFFFFFFD36100D36100D36100D36100984400FFFFFFD3
+        6100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD36100D36100D36100
+        D36100D36100D36100D36100FFFFFFD36100D36100D36100D36100D36100D361
+        00D36100D36100D36100D36100D36100FFFFFFD36100D36100D36100D36100D3
+        6100D36100D36100984400FFFFFF984400984400984400984400984400FFFFFF
+        984400D36100D36100984400984400FFFFFFD36100FFFFFFD36100FFFFFFD361
+        00FFFFFFD36100FFFFFFD36100D36100D36100D36100D36100D36200CE59032A
+        27F1CD5A03D26600D26500D26500D26500EAD6C4FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAD6C3D26500D26500D26500D265
+        00D26500FFFFFFD26500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD26500FF
+        FFFFD26500D26500984700FFFFFFD26500D26500FFFFFF984700984700FFFFFF
+        D26500D26500D26500D26500984700D26500FFFFFF9847009847009847009847
+        00984700FFFFFFD26500D26500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFD26500D26500FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD26500D26500D26500D26500984700FFFF
+        FFD26500D26500D26500FFFFFF984700D26500D26500D26500D26500FFFFFF98
+        4700D26500FFFFFFD26500FFFFFFD26500FFFFFFD26500FFFFFFD26500D26500
+        D26500D26500D26500D26600CD5A03AA6F6ACB5C03D26B00D26A00D26A00D26A
+        00BE8139FFFFFFFFFFFFFFFFFFE6D5C3CCA983CCA983E6D5C3FFFFFFFFFFFFFF
+        FFFFBE8139D26A00D26A00D26A00D26A00D26A00FFFFFFD26A00FFFFFF984B00
+        984B00984B00984B00FFFFFFD26A00FFFFFFD26A00D26A00D26A00984B00FFFF
+        FFD26A00FFFFFFD26A00D26A00984B00FFFFFFD26A00D26A00D26A00D26A00D2
+        6A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD26A00D26A00984B00
+        984B00984B00984B00984B00FFFFFF984B00984B00984B00984B00984B00D26A
+        00D26A00984B00984B00984B00984B00FFFFFF984B00984B00984B00984B00D2
+        6A00D26A00D26A00D26A00D26A00984B00FFFFFFD26A00D26A00984B00D26A00
+        D26A00D26A00D26A00FFFFFF984B00FFFFFFD26A00FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFD26A00D26A00D26A00D26A00D26A00D26B00CB5C037D
+        0C06CA5E03D26F00D26E00D26E00D26E00C56600E6D6C4FFFFFFFFFFFFD4AE84
+        E0BC94E0BC94D4AE84FFFFFFFFFFFFE6D6C3C56600D26E00D26E00D26E00D26E
+        00D26E00FFFFFFD26E00FFFFFFD26E00D26E00D26E00D26E00FFFFFFD26E00FF
+        FFFFD26E00D26E00D26E00D26E00984E00D26E00984E00D26E00D26E00D26E00
+        984E00D26E00D26E00D26E00FFFFFFD26E00FFFFFF984E00984E00984E00984E
+        00984E00FFFFFFD26E00D26E00D26E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFD26E00D26E00D26E00D26E00D26E00D26E00D26E00
+        FFFFFFD26E00D26E00D26E00FFFFFFD26E00D26E00D26E00D26E00D26E00D26E
+        00984E00FFFFFFD26E00D26E00D26E00D26E00D26E00D26E00FFFFFFD26E00FF
+        FFFFD26E00984E00984E00984E00FFFFFF984E00984E00984E00D26E00D26E00
+        D26E00D26E00D26E00D26F00CA5E03F1F5D7C95F03D27300D27200D27200D272
+        00D27200A75900985100985100B66100EDD9C4EDD9C4B66100985100985100A7
+        5900D27200D27200D27200D27200D27200D27200FFFFFFD27200FFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFD27200FFFFFFD27200FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD27200FFFFFF985100FF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD27200D27200
+        FFFFFF985100985100985100FFFFFF985100985100985100FFFFFFD27200D272
+        00D27200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+        7200D27200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFD27200FFFFFFD27200FFFFFFD27200FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFD27200D27200D27200D27200D27200D27300C95F03B5
+        A830C86103D27800D27700D27700D27700D27700D27700D27700D27700D27700
+        EAD9C4EAD9C4D27700D27700D27700D27700D27700D27700D27700D27700D277
+        00D27700FFFFFFD27700985400985400985400985400985400985400D27700FF
+        FFFFD27700985400985400FFFFFF985400985400FFFFFF985400985400985400
+        985400985400D27700985400D27700985400985400985400985400FFFFFF9854
+        00985400985400985400D27700D27700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFD27700D27700D27700985400FFFFFF985400985400
+        985400985400985400FFFFFF985400D27700D277009854009854009854009854
+        00985400985400985400985400985400985400985400D27700985400D2770098
+        5400D27700985400985400985400985400985400985400985400D27700D27700
+        D27700D27700D27700D27800C8610345BDFEC76303D27C00D27B00D27B00D27B
+        00D27B00D27B00D58300F1D7B3F4E0C3FAF6F1FAF6F1F4E0C3F1D7B3D58300D2
+        7B00D27B00D27B00D27B00D27B00D27B00D27B00FFFFFFD27B00FFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFD27B00FFFFFFD27B00D27B00D27B00FFFFFFD27B
+        00D27B00FFFFFFD27B00D27B00D27B00D27B00D27B00D27B00D27B00D27B00D2
+        7B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD27B00D27B00D27B00
+        FFFFFF985700985700985700FFFFFF985700985700985700FFFFFFD27B00D27B
+        00D27B00D27B00985700FFFFFFD27B00D27B00D27B00FFFFFF985700D27B00D2
+        7B00D27B00D27B00D27B00D27B00D27B00D27B00D27B00D27B00D27B00D27B00
+        D27B00D27B00D27B00FFFFFFFFFFFFFFFFFFD27B00FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFD27B00D27B00D27B00D27B00D27B00D27C00C763030A
+        06E9C66403D28100D28000D28000D28000D28000D28000CE7E00BC841AFAF6F0
+        FFFFFFFFFFFFFAF6F0BC841ACE7E00D28000D28000D28000D28000D28000D280
+        00D28000FFFFFFD28000985A00985A00985A00985A00985A00985A00D28000FF
+        FFFFD28000D28000D28000FFFFFFD28000D28000FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFD28000D28000D28000FFFFFFD28000985A00985A00985A00FFFFFF985A
+        00985A00985A00D28000D28000D28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFD28000D28000D28000D28000D28000985A00FFFFFF
+        D28000D28000985A00D28000D28000D28000D28000D28000D28000D28000D280
+        00D28000D28000D28000D28000D28000D28000D28000D28000985A00985A0098
+        5A00D28000FFFFFF985A00985A00FFFFFF985A00985A00FFFFFFD28000D28000
+        D28000D28000D28000D28100C664032D3999C56603D28300D28200D28200D282
+        00D28200D28200D28200C87B00AF801EF9F5F0F9F5F0AF801EC87B00D28200D2
+        8200D28200D28200D28200D28200D28200D28200FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD28200D28200D28200FFFFFFD282
+        00D28200FFFFFF985D00985D00985D00985D00D28200D28200FFFFFF985D00FF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD28200D28200
+        985D00985D00FFFFFF985D00985D00985D00FFFFFF985D00985D00D28200D282
+        00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFD28200D28200D28200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        D28200D28200D28200D28200FFFFFFD28200D28200FFFFFFD28200D28200FFFF
+        FFD28200D28200FFFFFFD28200D28200D28200D28200D28200D28300C56603A0
+        4672C46703D28700D28600D28600D28600D28600D28600D28600D28600C87F00
+        AF821DAF821DC87F00D28600D28600D28600D28600D28600D28600D28600D286
+        00D2860098600098600098600098600098600098600098600098600098600098
+        6000D28600D28600D28600986000D28600D28600FFFFFFD28600D28600D28600
+        D28600D28600D28600986000D28600986000986000986000986000FFFFFF9860
+        00986000986000986000D28600D28600D28600FFFFFF986000D28600D28600D2
+        8600986000FFFFFFD28600D28600D28600986000986000986000986000986000
+        986000986000986000986000986000986000D28600D28600D286009860009860
+        00986000986000986000986000986000D28600D28600D28600FFFFFF986000D2
+        8600D28600986000D28600D28600FFFFFFD28600D28600986000D28600D28600
+        D28600D28600D28600D28700C467031E6BD6C36903D28A00D28A00D28A00D28A
+        00D28A00D28A00D28A00D28A00D28A00C88300C88300D28A00D28A00D28A00D2
+        8A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00
+        D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A
+        00D28A00986300D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D2
+        8A00D28A00D28A00D28A00986300D28A00D28A00D28A00D28A00D28A00D28A00
+        D28A00986300D28A00D28A00D28A00D28A00D28A00986300D28A00D28A00D28A
+        00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D2
+        8A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00
+        D28A00D28A00D28A00986300D28A00D28A00D28A00D28A00D28A00D28A009863
+        00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00D28A00C369037B
+        DA6CC26A03D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00
+        D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D
+        00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D2
+        8D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00
+        D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D
+        00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D2
+        8D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00
+        D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D
+        00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D2
+        8D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00D28D00
+        D28D00D28D00D28D00D28D00C26A03217E8FC16B03DDAB26DDAC28DDAC28DDAC
+        28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DD
+        AC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28
+        DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC
+        28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DD
+        AC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28
+        DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC
+        28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DD
+        AC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28
+        DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC
+        28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAC28DDAB26C16B032A
+        AB5CC16C03C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00
+        C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A
+        00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C0
+        6A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00
+        C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A
+        00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C0
+        6A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00
+        C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A
+        00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C0
+        6A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00C06A00
+        C06A00C06A00C06A00C06A00C16C032B0074}
+      PicMouseOver.Data = {
+        07544269746D617026190000424D261900000000000036000000280000006F00
+        0000130000000100180000000000F0180000120B0000120B0000000000000000
+        0000A63E03A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00
+        A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C
+        00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A5
+        3C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00
+        A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C
+        00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A5
+        3C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00
+        A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C
+        00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A5
+        3C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00A53C00
+        A53C00A53C00A53C00A53C00A63E03000D00A74003D25000D34F00D34F00D34F
+        00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D3
+        4F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00
+        D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F
+        00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D3
+        4F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00
+        D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F
+        00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D3
+        4F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00
+        D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F
+        00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D34F00D25000A7400300
+        7400A84203D25100D35000D35000D35000D35000D35000D35000D35000D35000
+        D35000D35000D35000D35000D35000D35000D35000D35000D35000D35000D350
+        00D35000D35000D35000D35000D35000D35000D35000D35000D35000D35000D3
+        5000D35000D35000D35000D35000D35000D35000D35000D35000D35000D35000
+        D35000D35000D35000D35000D35000D35000D35000D35000D35000D35000D350
+        00D35000D35000D35000D35000D35000D35000D35000D35000D35000D35000D3
+        5000D35000D35000D35000D35000D35000D35000D35000D35000D35000D35000
+        D35000D35000D35000D35000D35000D35000D35000D35000D35000D35000D350
+        00D35000D35000D35000D35000D35000D35000D35000D35000D35000D35000D3
+        5000D35000D35000D35000D35000D35000D35000D35000D35000D35000D35000
+        D35000D35000D35000D25100A84203000000AA4403D25300D35200D35200D352
+        00DE8136DE8136DE8136DE8136DE8136DE8136DE8136DE8136DE8136DE8136DE
+        8136DE8136D35200D35200D35200D35200D35200FFFFFFD35200D35200D35200
+        D35200D35200D35200FFFFFFFFFFFFFFFFFFD35200D35200FFFFFFFFFFFFFFFF
+        FFD35200D35200D35200D35200D35200D35200D35200D35200D35200D35200D3
+        5200FFFFFFD35200D35200D35200D35200FFFFFFFFFFFFD35200D35200D35200
+        D35200D35200D35200D35200FFFFFFD35200D35200D35200D35200D35200D352
+        00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFD35200D35200D35200D35200D35200D35200D35200D35200D35200D35200
+        FFFFFFD35200D35200D35200D35200D35200D35200FFFFFFD35200D35200D352
+        00D35200FFFFFFFFFFFFD35200D35200D35200D35200D35200D25300AA440300
+        0000AA4703D25400D35300D35300D35300E2AA84E2A983E2A983E2A983E2A983
+        E2A983E2A983E2A983E2A983E2A983E2A983E2A983D35300D35300D35300D353
+        00D35300FFFFFFD35300D35300D35300D35300D35300D35300983A00983A00FF
+        FFFFD35300D35300983A00983A00983A00FFFFFFFFFFFFD35300D35300D35300
+        D35300D35300D35300FFFFFFD35300D35300FFFFFFD35300D35300D35300D353
+        00983A00FFFFFFD35300D35300D35300D35300D35300D35300D35300FFFFFFD3
+        5300D35300D35300D35300D35300D35300983A00983A00983A00983A00983A00
+        FFFFFF983A00983A00983A00983A00983A00D35300D35300FFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD35300D35300FFFFFFFFFFFFD3
+        5300D35300FFFFFFD35300FFFFFFD35300FFFFFF983A00FFFFFFD35300D35300
+        D35300D35300D35300D25400AA4703000000AC4903D35600D35500D35500D355
+        00EED5C4EED5C4EED5C4EED5C4EED5C4EED5C4EED5C4EED5C4EED5C4EED5C4EE
+        D5C4EED5C4D35500D35500D35500D35500D35500FFFFFFD35500D35500D35500
+        D35500D35500D35500D35500D35500FFFFFFD35500D35500FFFFFFD35500D355
+        00983C00FFFFFFFFFFFFFFFFFFD35500D35500D35500D35500983C00FFFFFFD3
+        5500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD35500D35500D35500
+        D35500D35500D35500D35500FFFFFFD35500D35500D35500D35500D35500D355
+        00D35500D35500D35500D35500D35500FFFFFFD35500D35500D35500D35500D3
+        5500D35500D35500983C00FFFFFF983C00983C00983C00983C00983C00FFFFFF
+        983C00D35500D35500983C00983C00FFFFFFD35500FFFFFFD35500FFFFFFD355
+        00FFFFFFD35500FFFFFFD35500D35500D35500D35500D35500D35600AC490301
+        0000AE4B03D35800D35700D35700D35700EAD4C4FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAD3C3D35700D35700D35700D357
+        00D35700FFFFFFD35700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD35700FF
+        FFFFD35700D35700983D00FFFFFFD35700D35700FFFFFF983D00983D00FFFFFF
+        D35700D35700D35700D35700983D00D35700FFFFFF983D00983D00983D00983D
+        00983D00FFFFFFD35700D35700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFD35700D35700FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD35700D35700D35700D35700983D00FFFF
+        FFD35700D35700D35700FFFFFF983D00D35700D35700D35700D35700FFFFFF98
+        3D00D35700FFFFFFD35700FFFFFFD35700FFFFFFD35700FFFFFFD35700D35700
+        D35700D35700D35700D35800AE4B03000000AF4D03D35900D35800D35800D358
+        00BE783BFFFFFFFFFFFFFFFFFFE6D2C4CCA484CCA484E6D2C4FFFFFFFFFFFFFF
+        FFFFBE783BD35800D35800D35800D35800D35800FFFFFFD35800FFFFFF983E00
+        983E00983E00983E00FFFFFFD35800FFFFFFD35800D35800D35800983E00FFFF
+        FFD35800FFFFFFD35800D35800983E00FFFFFFD35800D35800D35800D35800D3
+        5800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD35800D35800983E00
+        983E00983E00983E00983E00FFFFFF983E00983E00983E00983E00983E00D358
+        00D35800983E00983E00983E00983E00FFFFFF983E00983E00983E00983E00D3
+        5800D35800D35800D35800D35800983E00FFFFFFD35800D35800983E00D35800
+        D35800D35800D35800FFFFFF983E00FFFFFFD35800FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFD35800D35800D35800D35800D35800D35900AF4D0300
+        0000B15003D35C00D35B00D35B00D35B00C55400E6D3C5FFFFFFFFFFFFD5A785
+        E0B695E0B695D5A785FFFFFFFFFFFFE6D2C4C55400D35B00D35B00D35B00D35B
+        00D35B00FFFFFFD35B00FFFFFFD35B00D35B00D35B00D35B00FFFFFFD35B00FF
+        FFFFD35B00D35B00D35B00D35B00984000D35B00984000D35B00D35B00D35B00
+        984000D35B00D35B00D35B00FFFFFFD35B00FFFFFF9840009840009840009840
+        00984000FFFFFFD35B00D35B00D35B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFD35B00D35B00D35B00D35B00D35B00D35B00D35B00
+        FFFFFFD35B00D35B00D35B00FFFFFFD35B00D35B00D35B00D35B00D35B00D35B
+        00984000FFFFFFD35B00D35B00D35B00D35B00D35B00D35B00FFFFFFD35B00FF
+        FFFFD35B00984000984000984000FFFFFF984000984000984000D35B00D35B00
+        D35B00D35B00D35B00D35C00B15003000000B35203D35E00D35D00D35D00D35D
+        00D35D00A74800984100984100B64E00EDD6C4EDD6C4B64E00984100984100A7
+        4800D35D00D35D00D35D00D35D00D35D00D35D00FFFFFFD35D00FFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFD35D00FFFFFFD35D00FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD35D00FFFFFF984100FF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD35D00D35D00
+        FFFFFF984100984100984100FFFFFF984100984100984100FFFFFFD35D00D35D
+        00D35D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+        5D00D35D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFD35D00FFFFFFD35D00FFFFFFD35D00FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFD35D00D35D00D35D00D35D00D35D00D35E00B35203FF
+        FFFFB55603D36000D35F00D35F00D35F00D35F00D35F00D35F00D35F00D35F00
+        EAD5C4EAD5C4D35F00D35F00D35F00D35F00D35F00D35F00D35F00D35F00D35F
+        00D35F00FFFFFFD35F00984200984200984200984200984200984200D35F00FF
+        FFFFD35F00984200984200FFFFFF984200984200FFFFFF984200984200984200
+        984200984200D35F00984200D35F00984200984200984200984200FFFFFF9842
+        00984200984200984200D35F00D35F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFD35F00D35F00D35F00984200FFFFFF984200984200
+        984200984200984200FFFFFF984200D35F00D35F009842009842009842009842
+        00984200984200984200984200984200984200984200D35F00984200D35F0098
+        4200D35F00984200984200984200984200984200984200984200D35F00D35F00
+        D35F00D35F00D35F00D36000B55603000000B65803D36200D36100D36100D361
+        00D36100D36100D56C00F1D0B4F4D9C4FAF5F1FAF5F1F4D9C4F1D0B4D56C00D3
+        6100D36100D36100D36100D36100D36100D36100FFFFFFD36100FFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFD36100FFFFFFD36100D36100D36100FFFFFFD361
+        00D36100FFFFFFD36100D36100D36100D36100D36100D36100D36100D36100D3
+        6100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD36100D36100D36100
+        FFFFFF984400984400984400FFFFFF984400984400984400FFFFFFD36100D361
+        00D36100D36100984400FFFFFFD36100D36100D36100FFFFFF984400D36100D3
+        6100D36100D36100D36100D36100D36100D36100D36100D36100D36100D36100
+        D36100D36100D36100FFFFFFFFFFFFFFFFFFD36100FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFD36100D36100D36100D36100D36100D36200B6580300
+        0000B85A03D36300D36200D36200D36200D36200D36200CF6000BC7321FAF4F0
+        FFFFFFFFFFFFFAF4F0BC7321CF6000D36200D36200D36200D36200D36200D362
+        00D36200FFFFFFD36200984400984400984400984400984400984400D36200FF
+        FFFFD36200D36200D36200FFFFFFD36200D36200FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFD36200D36200D36200FFFFFFD36200984400984400984400FFFFFF9844
+        00984400984400D36200D36200D36200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFD36200D36200D36200D36200D36200984400FFFFFF
+        D36200D36200984400D36200D36200D36200D36200D36200D36200D36200D362
+        00D36200D36200D36200D36200D36200D36200D36200D3620098440098440098
+        4400D36200FFFFFF984400984400FFFFFF984400984400FFFFFFD36200D36200
+        D36200D36200D36200D36300B85A03000000B95C03D26500D26400D26400D264
+        00D26400D26400D26400C85E00B06E24F9F4F0F9F4F0B06E24C85E00D26400D2
+        6400D26400D26400D26400D26400D26400D26400FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD26400D26400D26400FFFFFFD264
+        00D26400FFFFFF984600984600984600984600D26400D26400FFFFFF984600FF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD26400D26400
+        984600984600FFFFFF984600984600984600FFFFFF984600984600D26400D264
+        00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFD26400D26400D26400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        D26400D26400D26400D26400FFFFFFD26400D26400FFFFFFD26400D26400FFFF
+        FFD26400D26400FFFFFFD26400D26400D26400D26400D26400D26500B95C0300
+        0000BA5E03D26700D26600D26600D26600D26600D26600D26600D26600C86000
+        B06F24B06F24C86000D26600D26600D26600D26600D26600D26600D26600D266
+        00D2660098470098470098470098470098470098470098470098470098470098
+        4700D26600D26600D26600984700D26600D26600FFFFFFD26600D26600D26600
+        D26600D26600D26600984700D26600984700984700984700984700FFFFFF9847
+        00984700984700984700D26600D26600D26600FFFFFF984700D26600D26600D2
+        6600984700FFFFFFD26600D26600D26600984700984700984700984700984700
+        984700984700984700984700984700984700D26600D26600D266009847009847
+        00984700984700984700984700984700D26600D26600D26600FFFFFF984700D2
+        6600D26600984700D26600D26600FFFFFFD26600D26600984700D26600D26600
+        D26600D26600D26600D26700BA5E03FFFFFFBC6003D26800D26700D26700D267
+        00D26700D26700D26700D26700D26700C86100C86100D26700D26700D26700D2
+        6700D26700D26700D26700D26700D26700D26700D26700D26700D26700D26700
+        D26700D26700D26700D26700D26700D26700D26700D26700D26700D26700D267
+        00D26700984900D26700D26700D26700D26700D26700D26700D26700D26700D2
+        6700D26700D26700D26700984900D26700D26700D26700D26700D26700D26700
+        D26700984900D26700D26700D26700D26700D26700984900D26700D26700D267
+        00D26700D26700D26700D26700D26700D26700D26700D26700D26700D26700D2
+        6700D26700D26700D26700D26700D26700D26700D26700D26700D26700D26700
+        D26700D26700D26700984900D26700D26700D26700D26700D26700D267009849
+        00D26700D26700D26700D26700D26700D26700D26700D26700D26800BC600300
+        0000BD6203D26900D26800D26800D26800D26800D26800D26800D26800D26800
+        D26800D26800D26800D26800D26800D26800D26800D26800D26800D26800D268
+        00D26800D26800D26800D26800D26800D26800D26800D26800D26800D26800D2
+        6800D26800D26800D26800D26800D26800D26800D26800D26800D26800D26800
+        D26800D26800D26800D26800D26800D26800D26800D26800D26800D26800D268
+        00D26800D26800D26800D26800D26800D26800D26800D26800D26800D26800D2
+        6800D26800D26800D26800D26800D26800D26800D26800D26800D26800D26800
+        D26800D26800D26800D26800D26800D26800D26800D26800D26800D26800D268
+        00D26800D26800D26800D26800D26800D26800D26800D26800D26800D26800D2
+        6800D26800D26800D26800D26800D26800D26800D26800D26800D26800D26800
+        D26800D26800D26800D26900BD6203000000BE6403DE8F31DE9032DE9032DE90
+        32DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE
+        9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032
+        DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE90
+        32DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE
+        9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032
+        DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE90
+        32DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE
+        9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032
+        DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE90
+        32DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE9032DE8F31BE640300
+        0000BF6503BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300
+        BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE63
+        00BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE
+        6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300
+        BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE63
+        00BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE
+        6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300
+        BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE63
+        00BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE
+        6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300BE6300
+        BE6300BE6300BE6300BE6300BF6503000000}
+      PicMouseDown.Data = {
+        07544269746D617026190000424D261900000000000036000000280000006F00
+        0000130000000100180000000000F0180000120B0000120B0000000000000000
+        0000A63D03A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00
+        A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B
+        00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A5
+        3B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00
+        A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B
+        00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A5
+        3B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00
+        A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B
+        00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A5
+        3B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00A53B00
+        A53B00A53B00A53B00A53B00A63D03000D00A73D03BF4500C64700C94A00CD4B
+        00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE
+        4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00
+        CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B
+        00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE
+        4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00
+        CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B
+        00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE
+        4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00
+        CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B
+        00CE4B00CE4B00CE4B00CE4B00CE4B00CD4B00C94A00C64700BF4500A73D034E
+        7939A83D03C24600C84900CD4B00D04C00D14C00D14C00D14C00D14C00D14C00
+        D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C
+        00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D1
+        4C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00
+        D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C
+        00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D1
+        4C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00
+        D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C
+        00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D1
+        4C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C00
+        D04C00CD4B00C84900C24600A83D038FDEA3AA3E03C34600C94A00CD4B00D14C
+        00DE7D37DE7D37DE7D37DE7D37DE7D37DE7D37DE7D37DE7D37DE7D37DE7D37DE
+        7D37DE7D37D34D00D34D00D34D00D34D00D34D00FFFFFFD34D00D34D00D34D00
+        D34D00D34D00D34D00FFFFFFFFFFFFFFFFFFD34D00D34D00FFFFFFFFFFFFFFFF
+        FFD34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00D3
+        4D00FFFFFFD34D00D34D00D34D00D34D00FFFFFFFFFFFFD34D00D34D00D34D00
+        D34D00D34D00D34D00D34D00FFFFFFD34D00D34D00D34D00D34D00D34D00D34D
+        00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFD34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00
+        FFFFFFD34D00D34D00D34D00D34D00D34D00D34D00FFFFFFD34D00D34D00D34D
+        00D34D00FFFFFFFFFFFFD34D00D34D00D14C00CD4B00C94A00C34600AA3E03B9
+        7265AB3E03C34600C94A00CD4B00D14C00E2A884E2A883E2A883E2A883E2A883
+        E2A883E2A883E2A883E2A883E2A883E2A883E2A883D34D00D34D00D34D00D34D
+        00D34D00FFFFFFD34D00D34D00D34D00D34D00D34D00D34D00983500983500FF
+        FFFFD34D00D34D00983500983500983500FFFFFFFFFFFFD34D00D34D00D34D00
+        D34D00D34D00D34D00FFFFFFD34D00D34D00FFFFFFD34D00D34D00D34D00D34D
+        00983500FFFFFFD34D00D34D00D34D00D34D00D34D00D34D00D34D00FFFFFFD3
+        4D00D34D00D34D00D34D00D34D00D34D00983500983500983500983500983500
+        FFFFFF983500983500983500983500983500D34D00D34D00FFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD34D00D34D00FFFFFFFFFFFFD3
+        4D00D34D00FFFFFFD34D00FFFFFFD34D00FFFFFF983500FFFFFFD34D00D34D00
+        D14C00CD4B00C94A00C34600AB3E0327352EAC3F03C34600C94A00CD4B00D14C
+        00EED3C4EED3C4EED3C4EED3C4EED3C4EED3C4EED3C4EED3C4EED3C4EED3C4EE
+        D3C4EED3C4D34D00D34D00D34D00D34D00D34D00FFFFFFD34D00D34D00D34D00
+        D34D00D34D00D34D00D34D00D34D00FFFFFFD34D00D34D00FFFFFFD34D00D34D
+        00983500FFFFFFFFFFFFFFFFFFD34D00D34D00D34D00D34D00983500FFFFFFD3
+        4D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD34D00D34D00D34D00
+        D34D00D34D00D34D00D34D00FFFFFFD34D00D34D00D34D00D34D00D34D00D34D
+        00D34D00D34D00D34D00D34D00D34D00FFFFFFD34D00D34D00D34D00D34D00D3
+        4D00D34D00D34D00983500FFFFFF983500983500983500983500983500FFFFFF
+        983500D34D00D34D00983500983500FFFFFFD34D00FFFFFFD34D00FFFFFFD34D
+        00FFFFFFD34D00FFFFFFD34D00D34D00D14C00CD4B00C94A00C34600AC3F032A
+        27F1AE4003C34600C94A00CD4B00D14C00EAD2C5FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAD1C4D34D00D34D00D34D00D34D
+        00D34D00FFFFFFD34D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD34D00FF
+        FFFFD34D00D34D00983500FFFFFFD34D00D34D00FFFFFF983500983500FFFFFF
+        D34D00D34D00D34D00D34D00983500D34D00FFFFFF9835009835009835009835
+        00983500FFFFFFD34D00D34D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFD34D00D34D00FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD34D00D34D00D34D00D34D00983500FFFF
+        FFD34D00D34D00D34D00FFFFFF983500D34D00D34D00D34D00D34D00FFFFFF98
+        3500D34D00FFFFFFD34D00FFFFFFD34D00FFFFFFD34D00FFFFFFD34D00D34D00
+        D14C00CD4B00C94A00C34600AE4003AA6F6AAF4003C34600C94A00CD4B00D14C
+        00BE723CFFFFFFFFFFFFFFFFFFE6D0C4CCA085CCA085E6D0C4FFFFFFFFFFFFFF
+        FFFFBE723CD34D00D34D00D34D00D34D00D34D00FFFFFFD34D00FFFFFF983500
+        983500983500983500FFFFFFD34D00FFFFFFD34D00D34D00D34D00983500FFFF
+        FFD34D00FFFFFFD34D00D34D00983500FFFFFFD34D00D34D00D34D00D34D00D3
+        4D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD34D00D34D00983500
+        983500983500983500983500FFFFFF983500983500983500983500983500D34D
+        00D34D00983500983500983500983500FFFFFF983500983500983500983500D3
+        4D00D34D00D34D00D34D00D34D00983500FFFFFFD34D00D34D00983500D34D00
+        D34D00D34D00D34D00FFFFFF983500FFFFFFD34D00FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFD34D00D34D00D14C00CD4B00C94A00C34600AF40037D
+        0C06B14103C34600C94A00CD4B00D14C00C54700E6D1C5FFFFFFFFFFFFD5A385
+        E0B195E0B195D5A385FFFFFFFFFFFFE6D0C4C54700D34D00D34D00D34D00D34D
+        00D34D00FFFFFFD34D00FFFFFFD34D00D34D00D34D00D34D00FFFFFFD34D00FF
+        FFFFD34D00D34D00D34D00D34D00983500D34D00983500D34D00D34D00D34D00
+        983500D34D00D34D00D34D00FFFFFFD34D00FFFFFF9835009835009835009835
+        00983500FFFFFFD34D00D34D00D34D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFD34D00D34D00D34D00D34D00D34D00D34D00D34D00
+        FFFFFFD34D00D34D00D34D00FFFFFFD34D00D34D00D34D00D34D00D34D00D34D
+        00983500FFFFFFD34D00D34D00D34D00D34D00D34D00D34D00FFFFFFD34D00FF
+        FFFFD34D00983500983500983500FFFFFF983500983500983500D34D00D34D00
+        D14C00CD4B00C94A00C34600B14103F1F5D7B34103C34600C94A00CD4B00D14C
+        00D34D00A83C00983500983500B64200EDD3C4EDD3C4B64200983500983500A8
+        3C00D34D00D34D00D34D00D34D00D34D00D34D00FFFFFFD34D00FFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFD34D00FFFFFFD34D00FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD34D00FFFFFF983500FF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD34D00D34D00
+        FFFFFF983500983500983500FFFFFF983500983500983500FFFFFFD34D00D34D
+        00D34D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+        4D00D34D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFD34D00FFFFFFD34D00FFFFFFD34D00FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFD34D00D34D00D14C00CD4B00C94A00C34600B34103B5
+        A830B54303C34600C94A00CD4B00D14C00D34D00D34D00D34D00D34D00D34D00
+        EAD2C5EAD2C5D34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D
+        00D34D00FFFFFFD34D00983500983500983500983500983500983500D34D00FF
+        FFFFD34D00983500983500FFFFFF983500983500FFFFFF983500983500983500
+        983500983500D34D00983500D34D00983500983500983500983500FFFFFF9835
+        00983500983500983500D34D00D34D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFD34D00D34D00D34D00983500FFFFFF983500983500
+        983500983500983500FFFFFF983500D34D00D34D009835009835009835009835
+        00983500983500983500983500983500983500983500D34D00983500D34D0098
+        3500D34D00983500983500983500983500983500983500983500D34D00D34D00
+        D14C00CD4B00C94A00C34600B5430345BDFEB64303C34600C94A00CD4B00D14C
+        00D34D00D34D00D55A00F1CBB4F4D6C4FAF4F1FAF4F1F4D6C4F1CBB4D55A00D3
+        4D00D34D00D34D00D34D00D34D00D34D00D34D00FFFFFFD34D00FFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFD34D00FFFFFFD34D00D34D00D34D00FFFFFFD34D
+        00D34D00FFFFFFD34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00D3
+        4D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD34D00D34D00D34D00
+        FFFFFF983500983500983500FFFFFF983500983500983500FFFFFFD34D00D34D
+        00D34D00D34D00983500FFFFFFD34D00D34D00D34D00FFFFFF983500D34D00D3
+        4D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00D34D00
+        D34D00D34D00D34D00FFFFFFFFFFFFFFFFFFD34D00FFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFD34D00D34D00D14C00CD4B00C94A00C34600B643030A
+        06E9B84403C24600C84900CD4B00D04C00D14C00D14C00CD4B00BA6426FAF4F0
+        FFFFFFFFFFFFFAF4F0BA6426CD4B00D14C00D14C00D14C00D14C00D14C00D14C
+        00D14C00FFFFFFD14C00973500973500973500973500973500973500D14C00FF
+        FFFFD14C00D14C00D14C00FFFFFFD14C00D14C00FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFD14C00D14C00D14C00FFFFFFD14C00973500973500973500FFFFFF9735
+        00973500973500D14C00D14C00D14C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFD14C00D14C00D14C00D14C00D14C00973500FFFFFF
+        D14C00D14C00973500D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C
+        00D14C00D14C00D14C00D14C00D14C00D14C00D14C00D14C0097350097350097
+        3500D14C00FFFFFF973500973500FFFFFF973500973500FFFFFFD14C00D14C00
+        D04C00CD4B00C84900C24600B844032D3999BA4503BF4500C64700C94A00CD4B
+        00CE4B00CE4B00CE4B00C44600AD5F28F9F4F0F9F4F0AD5F28C44600CE4B00CE
+        4B00CE4B00CE4B00CE4B00CE4B00CE4B00CE4B00FFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE4B00CE4B00CE4B00FFFFFFCE4B
+        00CE4B00FFFFFF953400953400953400953400CE4B00CE4B00FFFFFF953400FF
+        FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE4B00CE4B00
+        953400953400FFFFFF953400953400953400FFFFFF953400953400CE4B00CE4B
+        00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        FFFFCE4B00CE4B00CE4B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        CE4B00CE4B00CE4B00CE4B00FFFFFFCE4B00CE4B00FFFFFFCE4B00CE4B00FFFF
+        FFCE4B00CE4B00FFFFFFCE4B00CE4B00CD4B00C94A00C64700BF4500BA4503A0
+        4672BB4503BC4400C14600C64700C84900C94A00C94A00C94A00C94A00BF4500
+        AA5F29AA5F29BF4500C94A00C94A00C94A00C94A00C94A00C94A00C94A00C94A
+        00C94A0091330091330091330091330091330091330091330091330091330091
+        3300C94A00C94A00C94A00913300C94A00C94A00FFFFFFC94A00C94A00C94A00
+        C94A00C94A00C94A00913300C94A00913300913300913300913300FFFFFF9133
+        00913300913300913300C94A00C94A00C94A00FFFFFF913300C94A00C94A00C9
+        4A00913300FFFFFFC94A00C94A00C94A00913300913300913300913300913300
+        913300913300913300913300913300913300C94A00C94A00C94A009133009133
+        00913300913300913300913300913300C94A00C94A00C94A00FFFFFF913300C9
+        4A00C94A00913300C94A00C94A00FFFFFFC94A00C94A00913300C94A00C94A00
+        C84900C64700C14600BC4400BB45031E6BD6BD4603B74200BC4400BF4500C246
+        00C34600C34600C34600C34600C34600BA4300BA4300C34600C34600C34600C3
+        4600C34600C34600C34600C34600C34600C34600C34600C34600C34600C34600
+        C34600C34600C34600C34600C34600C34600C34600C34600C34600C34600C346
+        00C346008D3000C34600C34600C34600C34600C34600C34600C34600C34600C3
+        4600C34600C34600C346008D3000C34600C34600C34600C34600C34600C34600
+        C346008D3000C34600C34600C34600C34600C346008D3000C34600C34600C346
+        00C34600C34600C34600C34600C34600C34600C34600C34600C34600C34600C3
+        4600C34600C34600C34600C34600C34600C34600C34600C34600C34600C34600
+        C34600C34600C346008D3000C34600C34600C34600C34600C34600C346008D30
+        00C34600C34600C34600C34600C34600C24600BF4500BC4400B74200BD46037B
+        DA6CBD4603B13F00B54100B84200BB4300BB4300BB4300BB4300BB4300BB4300
+        BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB43
+        00BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB
+        4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300
+        BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB43
+        00BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB
+        4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300
+        BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB43
+        00BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB
+        4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300BB4300
+        BB4300B84200B54100B13F00BD4603217E8FBE4603AA3D00AD3E00AF3E00B03F
+        00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B1
+        3F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00
+        B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F
+        00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B1
+        3F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00
+        B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F
+        00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B1
+        3F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00
+        B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F00B13F
+        00B13F00B13F00B13F00B13F00B13F00B03F00AF3E00AD3E00AA3D00BE46032A
+        AB5CBF4703BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500
+        BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE45
+        00BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE
+        4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500
+        BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE45
+        00BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE
+        4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500
+        BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE45
+        00BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE
+        4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500BE4500
+        BE4500BE4500BE4500BE4500BF47032B0074}
+      PaintMode = pmNormal
+      OnClick = btnUploadBillsListClick
+    end
+  end
   object xpm: TXPMenu
     DimLevel = 30
     GrayLevel = 10

+ 33 - 4
Frames/BillsGatherFme.pas

@@ -6,7 +6,7 @@ uses
   BillsGatherDm, Globals, sdDB,
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
   Dialogs, ZJGrid, ExtCtrls, ZjGridDBA, ZjGridTreeDBA, ComCtrls, ToolWin,
-  XPMenu, sdGridDBA, JimPages, dxBar, ActnList;
+  XPMenu, sdGridDBA, JimPages, dxBar, ActnList, CslButton;
 
 type
   TLocateBillsEvent = procedure (AID: Integer) of object;
@@ -37,6 +37,8 @@ type
     alBillsGather: TActionList;
     actnLocateMeasureBills: TAction;
     actnLocateCompileBills: TAction;
+    pnlTop: TPanel;
+    btnUploadBillsList: TCslButton;
     procedure zgGclBillsCellGetColor(Sender: TObject; ACoord: TPoint;
       var AColor: TColor);
     procedure tobtnDetailGclClick(Sender: TObject);
@@ -47,6 +49,7 @@ type
       Shift: TShiftState; X, Y: Integer);
     procedure actnLocateCompileBillsExecute(Sender: TObject);
     procedure actnLocateCompileBillsUpdate(Sender: TObject);
+    procedure btnUploadBillsListClick(Sender: TObject);
   private
     FBillsGatherData: TBillsGatherData;
     FShowPhaseData: Boolean;
@@ -74,7 +77,7 @@ type
 implementation
 
 uses
-  ProjectData, UtilMethods, CalcDecimal, MainFrm;
+  ProjectData, UtilMethods, CalcDecimal, MainFrm, PHPWebDm, ConditionalDefines;
 
 {$R *.dfm}
 
@@ -89,6 +92,7 @@ begin
   saDetailGcl.DataView := FBillsGatherData.sdvDetailGclBills;
   saDetailDeal.DataView := FBillsGatherData.sdvDetailDealBills;
   saDetailBGL.DataView := FBillsGatherData.sdvDetailBGLBills;
+  pnlTop.Visible := _IsCloud;
 end;
 
 destructor TBillsGatherFrame.Destroy;
@@ -180,7 +184,7 @@ procedure TBillsGatherFrame.zgGclBillsCellGetColor(Sender: TObject;
 var
   bSimilarBills: Boolean;
 begin
-  if (ACoord.Y >= zgGclBills.FixedRowCount) then
+  if (ACoord.Y >= zgGclBills.FixedRowCount) and (ACoord.Y < zgGclBills.FixedRowCount + saGclBills.DataView.RecordCount) then
   begin
     if ACoord.Y = zgGclBills.FixedRowCount then
       bSimilarBills := CheckSimilarBills(ACoord.Y, ACoord.Y + 1)
@@ -193,7 +197,7 @@ begin
       AColor := $00646AFE;}
      if bSimilarBills then
        AColor := $0000FFFF; // 黄色
-     if CheckOverRange(ACoord.Y - zgGclBills.FixedRowCount) then
+     if TProjectData(FBillsGatherData.ProjectData).ProjProperties.ShowOverRange and CheckOverRange(ACoord.Y - zgGclBills.FixedRowCount) then
        AColor := $00505AFF; // 红色
   end;
 end;
@@ -241,5 +245,30 @@ begin
   TAction(Sender).Enabled := Assigned(saDetailGcl.DataView.Current) and Assigned(FOnLocateCompileBills);
 end;
 
+procedure TBillsGatherFrame.btnUploadBillsListClick(Sender: TObject);
+var
+  sgsParam: TStrings;
+  sResult: string;
+begin
+  if saGclBills.DataView.RecordCount = 0 then
+  begin
+    WarningMessage('请先建立台账,再同步清单至云端。');
+    Exit;
+  end;
+
+  sgsParam := TStringList.Create;
+  try
+    sgsParam.Add(Format('pmid=%d', [TProjectData(FBillsGatherData.ProjectData).WebID]));
+    //sgsParam.Add(Format('pmid=%d', [1595]));
+    sgsParam.Add(Format('listjson=%s', [FBillsGatherData.GetAllBillsJson]));
+    if PHPWeb.UrlGet(PHPWeb.MeasureURL + 'change/list/create', sgsParam, sResult) = 1 then
+      TipMessage('上传成功。')
+    else
+      WarningMessage(Format('上传数据失败:', [sResult]));
+  finally
+    sgsParam.Free;
+  end;
+end;
+
 end.
 

+ 41 - 2
Frames/BillsMeasureFme.dfm

@@ -53,7 +53,7 @@ object BillsMeasureFrame: TBillsMeasureFrame
       Height = 269
       Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection, goShowTreeLine]
       OptionsEx = []
-      ColCount = 35
+      ColCount = 37
       RowCount = 6
       FixedRowCount = 2
       ShowGridLine = False
@@ -130,6 +130,26 @@ object BillsMeasureFrame: TBillsMeasureFrame
   object stdBillsMeasure: TsdGridTreeDBA
     Columns = <
       item
+        Title.Caption = #35745#37327#27719#24635
+        Title.CaptionAcrossCols = '1'
+        Title.CaptionAcrossRows = 2
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        EditType = sgeCheckBox
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'IsGatherZJJL'
+        Width = 35
+        ReadOnly = True
+      end
+      item
         Title.Caption = #39033#30446#33410#32534#21495
         Title.CaptionAcrossCols = '1'
         Title.CaptionAcrossRows = 2
@@ -924,6 +944,24 @@ object BillsMeasureFrame: TBillsMeasureFrame
         ReadOnly = False
       end
       item
+        Title.Caption = #25209#22797#32534#21495
+        Title.CaptionAcrossCols = '1'
+        Title.CaptionAcrossRows = 2
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'ApprovalCode'
+        ReadOnly = False
+      end
+      item
         Title.Caption = #32047#35745#23436#25104#29575'(%)'
         Title.CaptionAcrossCols = '1'
         Title.CaptionAcrossRows = 2
@@ -1020,6 +1058,7 @@ object BillsMeasureFrame: TBillsMeasureFrame
     Grid = zgBillsMeasure
     ExtendRowCount = 3
     AutoExpand = False
+    TreeCellCol = 2
     KeyFieldName = 'ID'
     ParentFieldName = 'ParentID'
     NextSiblingFieldName = 'NextSiblingID'
@@ -1093,8 +1132,8 @@ object BillsMeasureFrame: TBillsMeasureFrame
     object actnCalculateAll: TAction
       Caption = #20840#37096#35745#31639
       ImageIndex = 15
-      Visible = False
       OnExecute = actnCalculateAllExecute
+      OnUpdate = actnCalculateAllUpdate
     end
     object actnExportGridToExcel: TAction
       Caption = #23548#20986#34920#26684#25968#25454

+ 33 - 2
Frames/BillsMeasureFme.pas

@@ -60,6 +60,7 @@ type
     procedure actnCancelHiddenColExecute(Sender: TObject);
     procedure actnLocateZJJLExecute(Sender: TObject);
     procedure actnLocateZJJLUpdate(Sender: TObject);
+    procedure actnCalculateAllUpdate(Sender: TObject);
   private
     FBillsMeasureData: TBillsMeasureData;
     FShowPriceChange: Boolean;
@@ -69,6 +70,8 @@ type
     FShowPMField: Boolean; // For Inner Test
     FOnAfterSetBookmark: TBookmarkRefreshEvent;
     FShowAlias: Boolean;
+    FShowApprovalCode: Boolean;
+    FShowIsGather: Boolean;
 
     FColVisibleManager: TBM_ColVisibleManager;
     FOnLocateZJJL: TLocateZJJLEvent;
@@ -98,6 +101,8 @@ type
     procedure SetShowBGLCode(const Value: Boolean);
     procedure SetShowDesignQuantity(const Value: Boolean);
     procedure SetShowAlias(const Value: Boolean);
+    procedure SetShowApprovalCode(const Value: Boolean);
+    procedure SetShowIsGather(const Value: Boolean);
   public
     constructor Create(AProjectFrame: TFrame; ABillsMeasureData: TBillsMeasureData);
     destructor Destroy; override;
@@ -112,6 +117,8 @@ type
     property ShowBGLCode: Boolean read FShowBGLCode write SetShowBGLCode;
     property ShowDesignQuantity: Boolean read FShowDesignQuantity write SetShowDesignQuantity;
     property ShowAlias: Boolean read FShowAlias write SetShowAlias;
+    property ShowApprovalCode: Boolean read FShowApprovalCode write SetShowApprovalCode;
+    property ShowIsGather: Boolean read FShowIsGather write SetShowIsGather;
 
     property OnAfterSetBookmark: TBookmarkRefreshEvent read FOnAfterSetBookmark write FOnAfterSetBookmark;
     property OnLocateZJJL: TLocateZJJLEvent read FOnLocateZJJL write FOnLocateZJJL;
@@ -136,7 +143,9 @@ begin
   stdBillsMeasure.IDTree := FBillsMeasureData.BillsMeasureTree;
   zgBillsMeasure.OnExpandMouseDown := ExpandMouseDown;
 
-  FColVisibleManager := TBM_ColVisibleManager.Create(stdBillsMeasure.Columns);
+  FColVisibleManager := TBM_ColVisibleManager.Create(stdBillsMeasure);
+  if not _IsDebugView then
+    zgBillsMeasure.OnKeyDown := nil;
 end;
 
 destructor TBillsMeasureFrame.Destroy;
@@ -243,7 +252,7 @@ begin
       AColor := $00A7FDFD;
   end;
   // 叶子节点,累计合同计量超过0号台账,整行数据的底色变为暗红提示用户
-  if not stnNode.HasChildren then
+  if TProjectData(FBillsMeasureData.ProjectData).ProjProperties.ShowOverRange and not stnNode.HasChildren then
   begin
     with stnNode.Rec do
     begin
@@ -442,6 +451,10 @@ begin
   if (ssCtrl in Shift) and (ssShift in Shift) and (ssAlt in Shift)
       and (Key in [67, 99]) then // 'c', 'C'
     actnCalculateAll.Execute;
+
+  if (ssCtrl in Shift) and (ssShift in Shift) and (ssAlt in Shift)
+      and (Key in [66, 98]) then
+    ShowIsGather := not ShowIsGather;
 end;
 
 procedure TBillsMeasureFrame.actnSetStageBookmarkExecute(Sender: TObject);
@@ -779,4 +792,22 @@ begin
   TAction(Sender).Enabled := TProjectData(FBillsMeasureData.ProjectData).PhaseData.Active;
 end;
 
+procedure TBillsMeasureFrame.SetShowApprovalCode(const Value: Boolean);
+begin
+  FShowApprovalCode := Value;
+  FColVisibleManager.ShowApprovalCode(FShowApprovalCode);
+end;
+
+procedure TBillsMeasureFrame.SetShowIsGather(const Value: Boolean);
+begin
+  FShowIsGather := Value;
+  FColVisibleManager.ShowIsGather(FShowIsGather);
+end;
+
+procedure TBillsMeasureFrame.actnCalculateAllUpdate(Sender: TObject);
+begin
+  with TProjectData(FBillsMeasureData.ProjectData) do
+  TAction(Sender).Enabled := PhaseData.Active and not PhaseData.StageDataReadOnly;
+end;
+
 end.

+ 3 - 1
Frames/OtherMeasureFme.pas

@@ -40,7 +40,7 @@ type
 implementation
 
 uses
-  OtherMeasurePhaseDm, sdDB;
+  OtherMeasurePhaseDm, sdDB, ConditionalDefines;
 
 {$R *.dfm}
 
@@ -50,6 +50,8 @@ begin
   FProjectData := AProjectData;
   saPhase.DataView := FProjectData.OtherMeasurePhaseData.sdvPhase;
   saOnce.DataView := FProjectData.OtherMeasureOnceData.sdvOnce;
+  if not _IsDebugView then
+    zgPhase.OnKeyDown := nil;
 end;
 
 destructor TOtherMeasureFrame.Destroy;

+ 54 - 3
Frames/ProjectFme.pas

@@ -184,6 +184,8 @@ type
     function CheckFileAndCloudChekerList: Boolean;
 
     procedure LocateMeasureBills(AID: Integer);
+    procedure LocateCompileBills(AID: Integer);
+    procedure LocateZJJL(ABillsID: Integer);
 
     property ProjectData: TProjectData read FProjectData;
 
@@ -210,8 +212,8 @@ uses
   PhaseData, BGLDm, MainFrm, ZhAPI, SearchDm, PHPWebDm, ActiveX,
   ConstUnit, MD5Unit, sdIDTree, sdDB, mProgressFrm, ConditionalDefines,
   ProjectCommands, ProjectProperty, CheckerMemoFrm, BillsMeasureDm,
-  ProgressHintFrm, mProgressProFrm, ReportManagerFrm,
-  ScFileArchiverConsts;
+  ProgressHintFrm, mProgressProFrm, ReportManagerFrm, BillsCompileDm,
+  ScFileArchiverConsts, Math, ZJJLDm;
 
 {$R *.dfm}
 
@@ -308,6 +310,8 @@ begin
       jpsAssistant.ActivePageIndex := Tag;
       sbtnExpend.Tag := Tag;
       ControlAssistantButtonsDown(Tag);
+      if _IsCloud and (Tag = tobtnBGL.Tag) then
+        BGLFrame.LoadBGLFromCloud;
       jpsMain.ActivePage.Tag := Tag;
     end;
     SetAssistantViewVisible(Down);
@@ -329,7 +333,12 @@ begin
 end;
 
 procedure TProjectFrame.jcbPhaseChanged(Sender: TObject);
+var
+  cr: TCursor;
 begin
+  cr := Screen.Cursor;
+  Screen.Cursor := crHourGlass;
+  
   if ProjectData.PhaseIndex = jcbPhase.ItemIndex + 1 then Exit;
 
   FProjectData.PhaseIndex := jcbPhase.ItemIndex + 1;
@@ -351,6 +360,9 @@ begin
     ButtonControl_UpToWeb;
     UpFileManageView.RefreshViews;
   end;
+  jcbPhase.Invalidate;
+
+  Screen.Cursor := cr;
 end;
 
 function TProjectFrame.CreateNewPhase: Boolean;
@@ -688,16 +700,20 @@ begin
   FBillsCompileFrame := TBillsCompileFrame.Create(Self, FProjectData.BillsCompileData);
   FBillsCompileFrame.ShowDesignQuantity := FProjectData.ProjProperties.ShowDesignQuantity;
   FBillsCompileFrame.ShowAlias := FProjectData.ProjProperties.ShowAlias;
+  FBillsCompileFrame.ShowApprovalCode := FProjectData.ProjProperties.ShowApprovalCode;
   FBillsCompileFrame.OnAfterSetBookmark := ExpandBookmarkFrame;
   AlignControl(FBillsCompileFrame, jpsMainBillsCompile, alClient);
   UpdateSysProgress(65, '正在解析数据');
 
   FBillsMeasureFrame := TBillsMeasureFrame.Create(Self, FProjectData.BillsMeasureData);
   FBillsMeasureFrame.OnAfterSetBookmark := ExpandBookmarkFrame;
+  FBillsMeasureFrame.OnLocateZJJL := LocateZJJL;
   FBillsMeasureFrame.ShowPriceChange := FProjectData.ProjProperties.ShowPriceChange;
   FBillsMeasureFrame.ShowBGLCode := FProjectData.ProjProperties.ShowBGLCode;
   FBillsMeasureFrame.ShowDesignQuantity := FProjectData.ProjProperties.ShowDesignQuantity;
   FBillsMeasureFrame.ShowAlias := FProjectData.ProjProperties.ShowAlias;
+  FBillsMeasureFrame.ShowApprovalCode := FProjectData.ProjProperties.ShowApprovalCode; 
+  FBillsMeasureFrame.ShowIsGather := True;
   AlignControl(FBillsMeasureFrame, jpsMainBillsMeasure, alClient);
 end;
 
@@ -714,6 +730,7 @@ begin
   FBillsGatherFrame.ShowPriceChange := FProjectData.ProjProperties.ShowPriceChange;
   FBillsGatherFrame.ShowPhaseData := FProjectData.ProjProperties.PhaseCount > 0;
   FBillsGatherFrame.OnLocateMeasureBills := LocateMeasureBills;
+  FBillsGatherFrame.OnLocateCompileBills := LocateCompileBills;
 end;
 
 procedure TProjectFrame.dxpmExpandBillsPopup(Sender: TObject);
@@ -1464,11 +1481,14 @@ procedure TProjectFrame.RefreshColumnDisplay;
 begin
   BillsCompileFrame.ShowDesignQuantity := FProjectData.ProjProperties.ShowDesignQuantity;
   BillsCompileFrame.ShowAlias := FProjectData.ProjProperties.ShowAlias;
+  BillsCompileFrame.ShowApprovalCode := FProjectData.ProjProperties.ShowApprovalCode;
   BillsMeasureFrame.ShowPriceChange := FProjectData.ProjProperties.ShowPriceChange;
   BillsMeasureFrame.ShowBGLCode := FProjectData.ProjProperties.ShowBGLCode;
   BillsMeasureFrame.ShowDesignQuantity := FProjectData.ProjProperties.ShowDesignQuantity;
   BillsMeasureFrame.ShowAlias := FProjectData.ProjProperties.ShowAlias;
+  BillsMeasureFrame.ShowApprovalCode := FProjectData.ProjProperties.ShowApprovalCode;
   BillsGatherFrame.ShowPriceChange := FProjectData.ProjProperties.ShowPriceChange;
+  BillsGatherFrame.zgGclBills.Invalidate; 
 end;
 
 procedure TProjectFrame.RefreshProjectState;
@@ -1497,7 +1517,10 @@ end;
 
 function TProjectFrame.CheckCanReport: Boolean;
 begin
-  Result := QuestMessageYesNo('请确定已生成中间计量数据?');
+  if not _IsCloud or ProjectData.CurUserIsAuthor then
+    Result := QuestMessageYesNo('请检查中间计量数据是否生成。')
+  else
+    Result := QuestMessageYesNo('如修改过本期计量数据,请先点击【否】完善【中间计量】窗口数据。');
   // 使用控件点击进行定位,重新定义方法太复杂
   if not Result then
   begin
@@ -1508,6 +1531,7 @@ begin
     tobtnZJJL.Down := True;
     tobtnZJJL.Click;
   end;
+  FZJJLFrame.GenerateZJJL;
 end;
 
 procedure TProjectFrame.actnAllPegExecute(Sender: TObject);
@@ -1658,4 +1682,31 @@ begin
     jpsMain.ActivePage.Tag := -1;
 end;
 
+procedure TProjectFrame.LocateZJJL(ABillsID: Integer);
+var
+  Rec: TsdDataRecord;
+begin
+  if not tobtnZJJL.Down then
+  begin
+    tobtnZJJL.Down := True;
+    tobtnZJJL.Click;
+  end;
+  Rec := FProjectData.PhaseData.ZJJLData.FindZJJLRecord(ABillsID);
+  FProjectData.PhaseData.ZJJLData.sdvZJJL.LocateInControl(Rec);
+end;
+
+procedure TProjectFrame.LocateCompileBills(AID: Integer);
+var
+  vNode: TsdIDTreeNode;
+begin
+  dxsbViewControl.SelectedItem := dxsbViewControl.Groups[0].Items[xbiBillsCompile.Tag];
+  ChangeView(xbiBillsCompile.Tag);
+  with FProjectData.BillsCompileData do
+  begin
+    vNode := BillsCompileTree.FindNode(AID);
+    if Assigned(vNode) then
+      sdvBillsCompile.LocateInControl(vNode.Rec);
+  end;
+end;
+
 end.

+ 9 - 1
Frames/ZJJLFme.dfm

@@ -104,7 +104,6 @@ object ZJJLFrame: TZJJLFrame
       Selection.TransparentColor = False
       FrozenCol = 0
       FrozenRow = 0
-      OnCurrentChanged = zgZJJLCurrentChanged
       OnMouseDown = zgZJJLMouseDown
       Align = alClient
     end
@@ -233,6 +232,11 @@ object ZJJLFrame: TZJJLFrame
       ImageIndex = 32
       OnExecute = actnGenerateGclZJJLExecute
     end
+    object actnGenerateGclGatherZJJL: TAction
+      Caption = #35745#37327#27719#24635#27169#24335
+      ImageIndex = 32
+      OnExecute = actnGenerateGclGatherZJJLExecute
+    end
   end
   object dxpmZJJL: TdxBarPopupMenu
     BarManager = MainForm.dxBarManager
@@ -261,6 +265,10 @@ object ZJJLFrame: TZJJLFrame
       item
         Item = MainForm.dxbtnGclZJJL
         Visible = True
+      end
+      item
+        Item = MainForm.dxbtnGclGatherZJJL
+        Visible = True
       end>
     UseOwnFont = False
     OnPopup = dxpmAutoGeneratePopup

+ 52 - 13
Frames/ZJJLFme.pas

@@ -9,12 +9,12 @@ uses
   ToolWin, ActnList, ZjGridDBA, ZJGrid, dxBar, sdGridDBA, sdDB;
 
 type
-  TRowIndex = (riBGLCode, riPegName, riBeginPeg, riEndPeg, riFBFXName, riUnitName, riDrawingCode,
+  TRowIndex = (riCurGatherMeasure, riBGLCode, riPegName, riBeginPeg, riEndPeg, riFBFXName, riUnitName, riDrawingCode,
     riFormulaMemoTitle, riFormulaMemoValue, riRelaFileTitle, riRelaFileValue);
 const
-  RowFields: array [TRowIndex] of string = ('BGLCode', 'PegName', 'BeginPeg', 'EndPeg', 'FBFXName', 'UnitName', 'DrawingCode',
+  RowFields: array [TRowIndex] of string = ('', 'BGLCode', 'PegName', 'BeginPeg', 'EndPeg', 'FBFXName', 'UnitName', 'DrawingCode',
     '', 'FormulaMemo', '', 'RelaFile');
-  RowFormats: array [TRowIndex] of string = ('变更令号:', '部位:', '起始桩号:', '终止桩号:', '分部分项工程:', '计量单元:', '图号:',
+  RowFormats: array [TRowIndex] of string = ('本期计量%s:%s', '变更令号:', '部位:', '起始桩号:', '终止桩号:', '分部分项工程:', '计量单元:', '图号:',
     '计算式说明:', '', '计算草图几何尺寸:', '');
 type
   TZJJLFrame = class(TFrame)
@@ -42,6 +42,7 @@ type
     actnGenerateGclZJJL: TAction;
     saZJJL: TsdGridDBA;
     zgDetailInfo: TZJGrid;
+    actnGenerateGclGatherZJJL: TAction;
     procedure actnGenerateExecute(Sender: TObject);
     procedure lePreTextExit(Sender: TObject);
     procedure zgZJJLMouseDown(Sender: TObject; Button: TMouseButton;
@@ -55,18 +56,18 @@ type
     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);
+    procedure actnGenerateGclGatherZJJLExecute(Sender: TObject);
   private
     FZJJLData: TZJJLData;
     FDataReadOnly: Boolean;
     procedure SetDataReadOnly(const Value: Boolean);
 
     procedure RefreshTitle;
-    procedure GenerateZJJL;
+    procedure RefreshDetailGrid;
 
     procedure InitDetailGrid;
   public
@@ -74,6 +75,7 @@ type
     destructor Destroy; override;
 
     procedure ResetFrameLink(AZJJLData: TZJJLData);
+    procedure GenerateZJJL;
 
     property DataReadOnly: Boolean read FDataReadOnly write SetDataReadOnly;
   end;
@@ -91,6 +93,7 @@ uses
 constructor TZJJLFrame.Create(AParent: TFrame; AZJJLData: TZJJLData);
 begin
   inherited Create(AParent);
+  zgDetailInfo.RowCount := Integer(riRelaFileValue) + 1;
   ResetFrameLink(AZJJLData);
   if TPhaseData(FZJJLData.PhaseData).Active then
   begin
@@ -98,6 +101,7 @@ begin
       lePreText.Text := ZJJLPreText;
   end;
   RefreshTitle;
+  FZJJLData.RefreshDetailGrid := RefreshDetailGrid;
 end;
 
 destructor TZJJLFrame.Destroy;
@@ -112,6 +116,7 @@ begin
   InitDetailGrid;
   if (saZJJL.DataView.RecordCount > 0) then
     saZJJL.DataView.LocateInControl(saZJJL.DataView.Records[0]);
+  FZJJLData.RefreshDetailGrid := RefreshDetailGrid;
   zgDetailInfo.Invalidate;
 end;
 
@@ -186,6 +191,7 @@ begin
   case iType of
     0: labTitle.Caption := '中间计量(0号台账)';
     1: labTitle.Caption := '中间计量(总量控制)';
+    2: labTitle.Caption := '中间计量(计量汇总)';
   end;
 end;
 
@@ -193,6 +199,7 @@ procedure TZJJLFrame.dxpmAutoGeneratePopup(Sender: TObject);
 begin
   SetDxBtnAction(actnGenerateFxZJJL, MainForm.dxbtnFxZJJL);
   SetDxBtnAction(actnGenerateGclZJJL, MainForm.dxbtnGclZJJL);
+  SetDxBtnAction(actnGenerateGclGatherZJJL, MainForm.dxbtnGclGatherZJJL);
 end;
 
 procedure TZJJLFrame.actnGenerateFxZJJLExecute(Sender: TObject);
@@ -215,6 +222,7 @@ begin
   case iType of
     0: FZJJLData.GenerateAll;
     1: FZJJLData.GenerateAllByB_Code;
+    2: FZJJLData.GenerateAllByB_CodeGather;
   end;
   RefreshTitle;
   if (saZJJL.DataView.RecordCount > 0) then
@@ -259,8 +267,31 @@ procedure TZJJLFrame.zgDetailInfoGetCellText(Sender: TObject;
       Result := GetDefaultValue(Rec, RowFields[ARow]);
   end;
 
+  function GetFloatStr(ANum: Double): string;
+  begin
+    if ANum = 0 then
+      Result := ''
+    else
+      Result := FloatToStr(ANum);
+  end;
+
+  function GetCurGatherMeasure: string;
+  var
+    Rec: TsdDataRecord;
+  begin
+    Rec := saZJJL.DataView.Current;
+    if not Assigned(Rec) then
+      Result := Format(RowFormats[riCurGatherMeasure], ['', ''])
+    else if Rec.ValueByName('Type').AsInteger = Integer(ztFx) then
+      Result := Format(RowFormats[riCurGatherMeasure], ['金额', GetFloatStr(FZJJLData.GetZJJLCalcData(Rec, 'GatherTotalPrice'))])
+    else
+      Result := Format(RowFormats[riCurGatherMeasure], ['数量', GetFloatStr(FZJJLData.GetZJJLCalcData(Rec, 'GatherQuantity'))]);
+  end;
+
 begin
-  if (ACoord.Y >= 0) and (ACoord.Y <= 10) then
+  if (ACoord.Y = Integer(riCurGatherMeasure)) then
+    Value := GetCurGatherMeasure
+  else if (ACoord.Y > Integer(riCurGatherMeasure)) and (ACoord.Y <= Integer(riRelaFileValue)) then
     Value := GetText(TRowIndex(ACoord.Y));
 end;
 
@@ -273,16 +304,10 @@ begin
     zgDetailInfo[0, iRowIndex].Align := gaTopLeft;
   zgDetailInfo.RowHeights[Integer(riFormulaMemoValue)] := 57;
   zgDetailInfo.Cells[0, Integer(riFormulaMemoValue)].Align := gaTopLeft;
-  zgDetailInfo.RowHeights[Integer(riRelaFileValue)] := 57;              
+  zgDetailInfo.RowHeights[Integer(riRelaFileValue)] := 57;
   zgDetailInfo.Cells[0, Integer(riRelaFileValue)].Align := gaTopLeft;
 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
@@ -309,4 +334,18 @@ begin
   Allow := (not FDataReadOnly) and (sFieldName <> '') and Assigned(saZJJL.DataView.Current);
 end;
 
+procedure TZJJLFrame.actnGenerateGclGatherZJJLExecute(Sender: TObject);
+begin
+  with TPhaseData(FZJJLData.PhaseData).PhaseProperty do
+  begin
+    ZJJLType := Integer(ztGclGather);
+    GenerateZJJL;
+  end;
+end;
+
+procedure TZJJLFrame.RefreshDetailGrid;
+begin
+  zgDetailInfo.Invalidate;
+end;
+
 end.

+ 276 - 0
SubTenderGather/stgExcelExport.pas

@@ -0,0 +1,276 @@
+unit stgExcelExport;
+
+interface
+
+uses
+  Classes, OExport, OExport_Vcl, OExport_VclForms, stgGatherDm, sdDB,
+  stgGatherCacheData, stgGatherUtils, sdIDTree, Graphics;
+
+type
+  TstgExcelExport = class
+  private
+    FTempFile: string;
+    FGatherData: TstgGatherData;
+    FOExport: TOExport;
+    FOExportor: TOCustomExporter;
+  protected
+    function AddHeadCell(ARow: TExportRow; const AHead: string; AWidth: Integer): TExportCellString;
+
+    function GetExportor(const AFileType: string): TOCustomExporter;
+
+    procedure SaveFile(const AFileName: string);
+
+    procedure BeforeExport;
+    procedure AfterExport;
+  public
+    constructor Create(AGatherData: TstgGatherData);
+
+    property GatherData: TstgGatherData read FGatherData;
+    property OExport: TOExport read FOExport;
+  end;
+
+  TstgErrorExcelExport = class(TstgExcelExport)
+  private
+    procedure InitSheet(ASheet: TExportWorkSheet);
+    procedure ExportSubTenderToSheet(ATenderID: Integer; ASheet: TExportWorkSheet);
+  public
+    procedure ExportSubTender(ARec: TsdDataRecord; const AFileName: string);
+    procedure ExportAll(const AFileName: string);
+  end;
+
+  TstgGatherExcelExport = class(TstgExcelExport)
+  private
+    procedure InitSheet(ASheet: TExportWorkSheet);
+    procedure ExportTreeNodeToSheet(ANode: TsdIDTreeNode; ASheet: TExportWorkSheet);
+    procedure ExportGatherToSheet(ASheet: TExportWorkSheet);
+  public
+    procedure ExportGather(const AFileName: string);
+  end;
+
+implementation
+
+uses SysUtils, UtilMethods, ZhAPI;
+
+{ TstgErrorExcelExport }
+
+procedure TstgErrorExcelExport.ExportAll(const AFileName: string);
+var
+  i: Integer;
+  vRec: TsdDataRecord;
+begin
+  BeforeExport;
+  try
+    GetExportor(ExtractFileExt(AFileName));
+    for i := 0 to FGatherData.sddSubTenders.RecordCount - 1 do
+    begin
+      vRec := FGatherData.sddSubTenders.Records[i];
+      ExportSubTenderToSheet(vRec.ValueByName('ID').AsInteger, FOExport.AddWorkSheet(vRec.ValueByName('Name').AsString));
+    end;
+    SaveFile(AFileName);
+  finally
+    AfterExport;
+  end;
+end;
+
+procedure TstgErrorExcelExport.ExportSubTender(ARec: TsdDataRecord;
+  const AFileName: string);
+begin
+  BeforeExport;
+  try
+    GetExportor(ExtractFileExt(AFileName));
+    ExportSubTenderToSheet(ARec.ValueByName('ID').AsInteger, FOExport.AddWorkSheet(ARec.ValueByName('Name').AsString));
+    SaveFile(AFileName);
+  finally
+    AfterExport;
+  end;
+end;
+
+procedure TstgErrorExcelExport.ExportSubTenderToSheet(ATenderID: Integer;
+  ASheet: TExportWorkSheet);
+
+  procedure ExportErrorRecord(ARec: TsdDataRecord);
+  var
+    vRow: TExportRow;
+    vCell: TExportCell;
+  begin
+    vRow := ASheet.AddRow;
+    vCell := vRow.AddCellString(ARec.ValueByName('RelaCode').AsString);
+    vCell := vRow.AddCellString(ARec.ValueByName('RelaSerialNo').AsString);
+    vCell.SetAlignment(cahCenter);
+    vCell := vRow.AddCellString(ARec.ValueByName('DetailCode').AsString);
+    vCell := vRow.AddCellString(ARec.ValueByName('DetailSerialNo').AsString);
+    vCell.SetAlignment(cahCenter);
+    vCell := vRow.AddCellString(GetErrorTypeText(ARec.ValueByName('ErrorType').AsInteger));
+  end;
+
+var
+  vIdx: TsdIndex;
+  i, iBegin, iEnd: Integer;
+  vRec: TsdDataRecord;
+begin
+  InitSheet(ASheet);
+  vIdx := GatherData.sddErrorDetail.FindIndex('idxTenderID');
+  iBegin := vIdx.FindKeyIndex(ATenderID);
+  iEnd := vIdx.FindKeyLastIndex(ATenderID);
+  if iBegin = -1 then Exit;
+  for i := iBegin to iEnd do
+    ExportErrorRecord(vIdx.Records[i]);
+end;
+
+procedure TstgErrorExcelExport.InitSheet(ASheet: TExportWorkSheet);
+var
+  vRow: TExportRow;
+  vCell: TExportCellString;
+begin
+  vRow := ASheet.AddRow;
+  vCell := AddHeadCell(vRow, '出错源', 120);
+  vCell.ColSpan := 2;
+  vCell := AddHeadCell(vRow, '可计量清单', 80);
+  vCell.ColSpan := 2;
+  vCell := AddHeadCell(vRow, '错误原因', 200);
+  vCell.RowSpan := 2;
+
+  vRow := ASheet.Rows.Items[vRow.RowIndex + 1];
+  vCell := AddHeadCell(vRow, '编号', 120);
+  vCell := AddHeadCell(vRow, '行号', 50);
+  vCell := AddHeadCell(vRow, '编号', 80);
+  vCell := AddHeadCell(vRow, '行号', 50);
+end;
+
+{ TstgExcelExport }
+
+function TstgExcelExport.AddHeadCell(ARow: TExportRow; const AHead: string;
+  AWidth: Integer): TExportCellString;
+begin
+  Result := ARow.AddCellString(AHead);
+  Result.SetAlignment(cahCenter);
+  Result.SetVAlignment(cavCenter);
+  Result.Font.Name := '黑体';
+  Result.Font.Size := 10;
+  Result.Width := AWidth;
+end;
+
+procedure TstgExcelExport.AfterExport;
+begin
+  FOExport.Free;
+  if Assigned(FOExportor) then
+    FOExportor.Free;
+  if FileExists(FTempFile) then
+    DeleteFile(FTempFile);
+end;
+
+procedure TstgExcelExport.BeforeExport;
+begin
+  FOExport := TOExport.Create;
+  FOExport.UseProgress := False;
+  FTempFile := GetTempFileName;
+end;
+
+constructor TstgExcelExport.Create(AGatherData: TstgGatherData);
+begin
+  FGatherData := AGatherData;
+end;
+
+function TstgExcelExport.GetExportor(
+  const AFileType: string): TOCustomExporter;
+begin
+  if SameText(AFileType, '.xls') then
+    FOExportor := TOCustomExporterXLS.Create
+  else //if SameText(AFileType, '.xlsx') then
+    FOExportor := TOCustomExporterXLSX.Create;
+end;
+
+procedure TstgExcelExport.SaveFile(const AFileName: string);
+begin
+  FOExport.SaveToFile(FTempFile, FOExportor);
+  if not FileExists(AFileName) or QuestMessage('存在同名文件,是否替换?') then
+    CopyFileOrFolder(FTempFile, AFileName);
+end;
+
+{ TstgGatherExcelExport }
+
+procedure TstgGatherExcelExport.ExportGather(const AFileName: string);
+begin
+  BeforeExport;
+  try
+    GetExportor(ExtractFileExt(AFileName));
+    ExportGatherToSheet(OExport.AddWorkSheet('分包数据汇总'));
+    SaveFile(AFileName);
+  finally
+    AfterExport;
+  end;
+end;
+
+procedure TstgGatherExcelExport.ExportGatherToSheet(
+  ASheet: TExportWorkSheet);
+var
+  vTree: TsdIDTree;
+begin
+  InitSheet(ASheet);
+  vTree := TsdIDTree.Create;
+  try
+    vTree.KeyFieldName := 'ID';
+    vTree.ParentFieldName := 'ParentID';
+    vTree.NextSiblingFieldName := 'NextSiblingID';
+    vTree.DataView := GatherData.sdvGatherTree;
+    ExportTreeNodeToSheet(vTree.FirstNode, ASheet);
+  finally
+    vTree.Free;
+  end;
+end;
+
+procedure TstgGatherExcelExport.ExportTreeNodeToSheet(ANode: TsdIDTreeNode;
+  ASheet: TExportWorkSheet);
+
+  procedure AddCellString(ARow: TExportRow; const AStr: string; AColor: TColor);
+  var
+    vCell: TExportCellString;
+  begin
+    vCell := ARow.AddCellString(AStr);
+    vCell.Font.Color := AColor;
+  end;
+
+  procedure AddCellNumber(ARow: TExportRow; const ANum: Double; AColor: TColor);
+  var
+    vCell: TExportCellNumber;
+  begin
+    vCell := ARow.AddCellNumber(ANum);
+    vCell.Font.Color := AColor;
+    vCell.EmptyIfZero := True;
+  end;
+
+var
+  vColor: TColor;
+  vRow: TExportRow;
+  vCell: TExportCellNumber;
+begin
+  if not Assigned(ANode) then Exit;
+  if ANode.Rec.ValueByName('IsSubTender').AsBoolean then
+    vColor := $00D5D5D5
+  else
+    vColor := clWindowText;
+  vRow := ASheet.AddRow;
+  AddCellString(vRow, ANode.Rec.ValueByName('Code').AsString, vColor);
+  AddCellString(vRow, ANode.Rec.ValueByName('B_Code').AsString, vColor);
+  AddCellString(vRow, ANode.Rec.ValueByName('Name').AsString, vColor);
+  AddCellString(vRow, ANode.Rec.ValueByName('Units').AsString, vColor);
+  AddCellNumber(vRow, ANode.Rec.ValueByName('DealQuantity').AsFloat, vColor);
+  AddCellNumber(vRow, ANode.Rec.ValueByName('QcQuantity').AsFloat, vColor);
+  ExportTreeNodeToSheet(ANode.FirstChild, ASheet);
+  ExportTreeNodeToSheet(ANode.NextSibling, ASheet);
+end;
+
+procedure TstgGatherExcelExport.InitSheet(ASheet: TExportWorkSheet);
+var
+  vRow: TExportRow;
+begin
+  vRow := ASheet.AddRow;
+  AddHeadCell(vRow, '项目节编号', 180);
+  AddHeadCell(vRow, '清单编号', 80);
+  AddHeadCell(vRow, '名称', 240);
+  AddHeadCell(vRow, '单位', 50);
+  AddHeadCell(vRow, '合同计量', 100);
+  AddHeadCell(vRow, '数量变更计量', 100);
+end;
+
+end.

+ 429 - 0
SubTenderGather/stgGather.pas

@@ -0,0 +1,429 @@
+unit stgGather;
+
+interface
+
+uses
+  Classes, stgGatherCacheData, ProjectData, BillsTree, sdIDTree;
+
+type
+  TProgramHintEvent = procedure (const ATenderName: string) of Object;
+
+  TstgSumBaseFileLoader = class
+  private
+    FTree: TstgGatherTree;
+    FSumBaseFile: string;
+    FTempFolder: string;
+    FFileName: string;
+    FProjectData: TProjectData;
+
+    procedure LoadFileName;
+    function LoadTreeNodeData(ANode: TBillsIDTreeNode; AParent: TstgGatherTreeNode): TstgGatherTreeNode;
+    procedure LoadSumBaseTreeNode(ANode: TsdIDTreeNode; AParent: TstgGatherTreeNode);
+  public
+    constructor Create(ATree: TstgGatherTree; const ASumBaseFile: string);
+    destructor Destroy; override;
+
+    procedure LoadData;
+  end;
+
+  TstgSubTenderFileGather = class
+  private
+    FCacheData: TstgGatherCacheData;
+    FProjectData: TProjectData;
+    FCurSubTenderID: Integer;
+    FLoadHint: TProgramHintEvent;
+    procedure GatherDetailData(AGatherNode: TstgGatherTreeNode; ASourceNode: TMeasureBillsIDTreeNode);
+    function GatherSubTenderTreeNodeData(ANode: TsdIDTreeNode; AParent: TstgGatherTreeNode): TstgGatherTreeNode;
+    procedure GatherSubTenderTreeNode(ANode: TsdIDTreeNode; AParent: TstgGatherTreeNode);
+    procedure GatherSubTender(ASubTenderID: Integer);
+  public
+    procedure GatherTo(AGatherCacheData: TstgGatherCacheData; ASubTenders: TList);
+
+    property LoadHint: TProgramHintEvent read FLoadHint write FLoadHint;
+  end;
+
+  TstgErrorChecker = class
+  private
+    FCacheData: TstgGatherCacheData;
+
+    procedure NewError(ANode: TstgGatherTreeNode; AType: Integer);
+
+    function SafeCheckParent(ANode, ACheckParent: TstgGatherTreeNode): TstgGatherTreeNode;
+
+    // ACheckParent的子项(总包中存在),存在与ANode同编号节点
+    function HasSameCodeLevelChild(ANode: TstgGatherTreeNode;
+      ACheckParent: tstgGatherTreeNode = nil): Boolean;
+    // ACheckParent的子项(总包中存在),存在与ANode同编号、名称、单位,但不同层次节点
+    function HasSameChildWithDiffLevel(ANode: TstgGatherTreeNode;
+      ACheckParent: TstgGatherTreeNode = nil): Boolean;
+    // ACheckParent的子项(总包中存在)(含子项的子项),存在与ANode同编号节点
+    // 子项(含子项的子项),存在与CheckParent的子项(总包中存在)同编号节点
+
+    function HasShortRelaCodeChild(ANode: TstgGatherTreeNode): Boolean;
+    function HasLongRelaCodeChild(ANode:TstgGatherTreeNode): Boolean;
+    function HasXmjChildWithSameCodeChild(ANode: TstgGatherTreeNode): Boolean;
+
+    procedure AddXmjError(ANode: TstgGatherTreeNode);
+    procedure AddGclError(ANode: TstgGatherTreeNode);
+
+    procedure AddError(ANode: TstgGatherTreeNode);
+  public
+    procedure Check(AGatherCacheData: TstgGatherCacheData);
+  end;
+
+implementation
+
+uses Math, Globals, mDataRecord, UtilMethods, SysUtils, XMLDoc, XMLIntf,
+  CacheTree;
+
+{ TstgSumBaseFileLoader }
+
+constructor TstgSumBaseFileLoader.Create(ATree: TstgGatherTree;
+  const ASumBaseFile: string);
+begin
+  FTree := ATree;
+  FSumBaseFile := ASumBaseFile;
+  FTempFolder := GenerateTempFolder(GetTempFilePath);
+  FProjectData := TProjectData.Create;
+end;
+
+destructor TstgSumBaseFileLoader.Destroy;
+begin
+  if FileExists(FTempFolder) then
+    DeleteFolder(FTempFolder);
+  if Assigned(FProjectData) then
+    FProjectData.Free;
+  inherited;
+end;
+
+procedure TstgSumBaseFileLoader.LoadData;
+begin
+  UnZipFile(FSumBaseFile, FTempFolder);
+  LoadFileName;
+  FProjectData.OpenForSumUpBase(FTempFolder + '\' + FFileName);
+  LoadSumBaseTreeNode(FProjectData.BillsCompileData.BillsCompileTree.FirstNode, nil);
+  FTree.MarkLeafXmj;
+end;
+
+procedure TstgSumBaseFileLoader.LoadFileName;
+var
+  FXmlDocument: IXMLDocument;
+  RootXmlNode, InfoXmlNode: IXMLNode;
+  ChildNodes: IXMLNodeList;
+begin
+  FXmlDocument := TXMLDocument.Create(nil) as IXMLDocument;
+  try
+    FXmlDocument.LoadFromFile(FTempFolder + '\Info.xml');
+    FXmlDocument.Options := [doNodeAutoCreate,doNodeAutoIndent,doAutoPrefix,doNamespaceDecl];
+    RootXmlNode := FXmlDocument.DocumentElement;
+
+    ChildNodes := RootXmlNode.ChildNodes;
+    InfoXmlNode := ChildNodes.FindNode('ProjectInfo');
+
+    FFileName := InfoXmlNode.Attributes['FileName'];
+  finally
+    FXmlDocument := nil;
+  end;
+end;
+
+procedure TstgSumBaseFileLoader.LoadSumBaseTreeNode(ANode: TsdIDTreeNode; AParent: TstgGatherTreeNode);
+var
+  vCurGatherNode: TstgGatherTreeNode;
+begin
+  if not Assigned(ANode) then Exit;
+  vCurGatherNode := LoadTreeNodeData(TBillsIDTreeNode(ANode), AParent);
+  LoadSumBaseTreeNode(ANode.FirstChild, vCurGatherNode);
+  LoadSumBaseTreeNode(ANode.NextSibling, AParent);
+end;
+
+function TstgSumBaseFileLoader.LoadTreeNodeData(ANode: TBillsIDTreeNode;
+  AParent: TstgGatherTreeNode): TstgGatherTreeNode;
+begin
+  Result := FTree.AddSumBaseNode(AParent, ANode.ID);
+  Result.Code := ANode.Rec.Code.AsString;
+  Result.B_Code := ANode.Rec.B_Code.AsString;
+  Result.Name := ANode.Rec.Name.AsString;
+  Result.Units := ANode.Rec.Units.AsString;
+  Result.IsLeaf := not ANode.HasChildren;
+end;
+
+{ TstgSubTenderFileGather }
+
+procedure TstgSubTenderFileGather.GatherDetailData(
+  AGatherNode: TstgGatherTreeNode; ASourceNode: TMeasureBillsIDTreeNode);
+var
+  vSubTender: TstgSubTenderStageData;
+begin
+  //if Assigned(ASourceNode.StageRec) and
+  //   ((ASourceNode.StageRec.GatherQuantity.AsFloat <> 0) or (ASourceNode.StageRec.GatherTotalPrice.AsFloat <> 0)) then
+  
+  //if not ASourceNode.HasChildren then
+  if (AGatherNode.IsSubTender) or (not ASourceNode.HasChildren) then
+  begin
+    vSubTender := AGatherNode.SafeSubTender(FCurSubTenderID);
+    vSubTender.AddDetail(ASourceNode);
+  end;
+end;
+
+procedure TstgSubTenderFileGather.GatherSubTender(ASubTenderID: Integer);
+var
+  vNode: TsdIDTreeNode;
+begin
+  FCurSubTenderID := ASubTenderID;
+  vNode := ProjectManager.ProjectsTree.FindNode(ASubTenderID);
+  if vNode.Rec.ValueByName('Type').AsInteger = 1 then
+  begin;
+    FLoadHint(vNode.Rec.ValueByName('Name').AsString);
+    FProjectData := OpenProjectManager.FindProjectData(ASubTenderID);
+    try
+      if not Assigned(FProjectData) then
+      begin
+        FProjectData := TProjectData.Create;
+        FProjectData.OpenForSumUpGather(GetMyProjectsFilePath + vNode.Rec.ValueByName('FileName').AsString);
+      end;
+      FCacheData.AddSubTender(vNode.Rec);
+      GatherSubTenderTreeNode(FProjectData.BillsMeasureData.BillsMeasureTree.FirstNode, nil);
+    finally
+      if not Assigned(OpenProjectManager.FindProjectData(ASubTenderID)) then
+        FProjectData.Free;
+    end;
+  end;
+end;
+
+procedure TstgSubTenderFileGather.GatherSubTenderTreeNode(
+  ANode: TsdIDTreeNode; AParent: TstgGatherTreeNode);
+var
+  vCur: TstgGatherTreeNode;
+begin
+  if not Assigned(ANode) then Exit;
+  vCur := GatherSubTenderTreeNodeData(ANode, AParent);
+  GatherSubTenderTreeNode(ANode.FirstChild, vCur);
+  GatherSubTenderTreeNode(ANode.NextSibling, AParent);
+end;
+
+function TstgSubTenderFileGather.GatherSubTenderTreeNodeData(
+  ANode: TsdIDTreeNode; AParent: TstgGatherTreeNode): TstgGatherTreeNode;
+var
+  vNode: TMeasureBillsIDTreeNode;
+  vNext: TstgGatherTreeNode;
+begin
+  vNode := TMeasureBillsIDTreeNode(ANode);
+  if ANode.ID < 100 then
+    Result := FCacheData.GatherTree.FindNode(ANode.ID)
+  else
+    Result := FCacheData.GatherTree.FindNode(AParent, vNode);
+
+  if not Assigned(Result) then
+  begin
+    vNext := FCacheData.GatherTree.FindNextSibling(AParent, vNode.Rec.Code.AsString, vNode.Rec.B_Code.AsString);
+    if not Assigned(AParent) or (not (AParent.IsSumBase and AParent.IsLeafXmj)) or (vNode.Rec.B_Code.AsString <> '') {or (not ANode.HasChildren)} then
+    begin
+      if ANode.ID < 100 then
+        Result := FCacheData.GatherTree.AddSubTenderNode(AParent, vNext, ANode.ID)
+      else
+        Result := FCacheData.GatherTree.AddSubTenderNode(AParent, vNext);
+      Result.Code := Trim(vNode.Rec.Code.AsString);
+      Result.B_Code := Trim(vNode.Rec.B_Code.AsString);
+      Result.Name := Trim(vNode.Rec.Name.AsString);
+      Result.Units := Trim(vNode.Rec.Units.AsString);
+      Result.IsLeaf := not vNode.HasChildren;
+    end
+    else
+      Result := AParent;
+  end;
+
+  if Assigned(Result) then
+    GatherDetailData(Result, vNode)
+  else
+    Result := AParent;
+end;
+
+procedure TstgSubTenderFileGather.GatherTo(AGatherCacheData: TstgGatherCacheData;
+  ASubTenders: TList);
+var
+  i, iSubTenderID: Integer;
+begin
+  FCacheData := AGatherCacheData;
+  for i := 0 to ASubTenders.Count - 1 do
+    GatherSubTender(Integer(ASubTenders.Items[i]));
+  FCacheData.GatherTree.CalculateAll;
+end;
+
+{ TstgErrorChecker }
+
+procedure TstgErrorChecker.AddError(ANode: TstgGatherTreeNode);
+begin
+  if ANode.IsGclBills then
+    AddGclError(ANode)
+  else
+    AddXmjError(ANode);
+end;
+
+procedure TstgErrorChecker.AddGclError(ANode: TstgGatherTreeNode);
+begin
+  if HasXmjChildWithSameCodeChild(ANode) then
+    NewError(ANode, iErrorXmjLess)
+  else if HasLongRelaCodeChild(ANode) then
+    NewError(ANode, iErrorGclMore)
+  else if HasShortRelaCodeChild(ANode) then
+    NewError(ANode, iErrorGclLess)
+  else if HasSameChildWithDiffLevel(ANode) then
+    NewError(ANode, iErrorGclMore)
+  else if HasSameCodeLevelChild(ANode) then
+    NewError(ANode, iErrorGclDiff)
+  else
+    NewError(ANode, iErrorGclAdd);
+end;
+
+procedure TstgErrorChecker.AddXmjError(ANode: TstgGatherTreeNode);
+begin
+  if HasSameCodeLevelChild(ANode) then
+    NewError(ANode, iErrorXmjDiff)
+  else
+    NewError(ANode, iErrorXmjAdd);
+end;
+
+procedure TstgErrorChecker.Check(AGatherCacheData: TstgGatherCacheData);
+var
+  i: Integer;
+  vNode, vParent: TstgGatherTreeNode;
+begin
+  FCacheData := AGatherCacheData;
+  for i := 0 to FCacheData.GatherTree.CacheNodes.Count - 1 do
+  begin
+    vNode := TstgGatherTreeNode(FCacheData.GatherTree.CacheNodes[i]);
+    vParent := TstgGatherTreeNode(vNode.Parent);
+    if vNode.IsSubTender and (not Assigned(vParent) or not vParent.IsSubTender) then
+      AddError(vNode);
+  end;
+end;
+
+function TstgErrorChecker.HasLongRelaCodeChild(
+  ANode: TstgGatherTreeNode): Boolean;
+var
+  vParent, vChild: TstgGatherTreeNode;
+  i: Integer;
+begin
+  Result := False;
+  vParent := SafeCheckParent(ANode, nil);
+  for i := 0 to vParent.Children.Count - 1 do
+  begin
+    vChild := TstgGatherTreeNode(vParent.Children.Items[i]);
+    if (Pos(ANode.B_Code + '-', vChild.B_Code) = 1) and (vChild.IsSumBase) then
+    begin
+      Result := True;
+      Break;
+    end;
+  end;
+end;
+
+function TstgErrorChecker.HasSameChildWithDiffLevel(ANode,
+  ACheckParent: TstgGatherTreeNode): Boolean;
+var
+  vParent, vChild: TstgGatherTreeNode;
+  i: Integer;
+begin
+  Result := False;
+  vParent := SafeCheckParent(ANode, ACheckParent);
+  for i := 0 to vParent.Children.Count - 1 do
+  begin
+    vChild := TstgGatherTreeNode(vParent.Children.Items[i]);
+    if vChild.IsSumBase and (vChild.Code = ANode.Code) and
+       (vChild.B_Code = ANode.B_Code) and (vChild.Name = ANode.Name) and
+       (vChild.Units = ANode.Units) and (vChild.IsLeaf = vChild.IsLeaf) then
+    begin
+      Result := True;
+      Break;
+    end;
+  end;
+end;
+
+function TstgErrorChecker.HasSameCodeLevelChild(ANode,
+  ACheckParent: tstgGatherTreeNode): Boolean;
+var
+  vParent, vChild: TstgGatherTreeNode;
+  i: Integer;
+begin
+  Result := False;
+  vParent := SafeCheckParent(ANode, ACheckParent);
+  for i := 0 to vParent.Children.Count - 1 do
+  begin
+    vChild := TstgGatherTreeNode(vParent.Children.Items[i]);
+    if vChild.IsSumBase and (vChild.Code = ANode.Code) and (vChild.B_Code = ANode.B_Code) and (vChild.IsLeaf = vChild.IsLeaf) then
+    begin
+      Result := True;
+      Break;
+    end;
+  end;
+end;
+
+function TstgErrorChecker.HasShortRelaCodeChild(
+  ANode: TstgGatherTreeNode): Boolean;
+var
+  vParent, vChild: TstgGatherTreeNode;
+  i: Integer;
+begin
+  Result := False;
+  vParent := SafeCheckParent(ANode, nil);
+  for i := 0 to vParent.Children.Count - 1 do
+  begin
+    vChild := TstgGatherTreeNode(vParent.Children.Items[i]);
+    if (Pos(vChild.B_Code + '-', ANode.B_Code) = 1) and (vChild.IsSumBase) then
+    begin
+      Result := True;
+      Break;
+    end;
+  end;
+end;
+
+function TstgErrorChecker.HasXmjChildWithSameCodeChild(
+  ANode: TstgGatherTreeNode): Boolean;
+var
+  vParent, vChild: TstgGatherTreeNode;
+  i: Integer;
+begin
+  Result := False;
+  vParent := SafeCheckParent(ANode, nil);
+  for i := 0 to vParent.Children.Count - 1 do
+  begin
+    vChild := TstgGatherTreeNode(vParent.Children.Items[i]);
+    if not vChild.IsGclBills and ANode.IsGclBills and vChild.IsSumBase then
+    begin
+      Result := True;
+      Break;
+    end;
+  end;
+end;
+
+procedure TstgErrorChecker.NewError(ANode: TstgGatherTreeNode;
+  AType: Integer);
+
+  procedure RecursiveNewError(AParent: TstgGatherTreeNode);
+  var
+    i: Integer;
+  begin
+    if AParent.Children.Count > 0 then
+    begin
+      for i := 0 to AParent.Children.Count - 1 do
+        RecursiveNewError(TstgGatherTreeNode(AParent.Children.Items[i]));
+    end
+    else
+      FCacheData.AddError(ANode, AParent, AType);
+  end;
+
+begin
+  RecursiveNewError(ANode);
+end;
+
+function TstgErrorChecker.SafeCheckParent(ANode,
+  ACheckParent: TstgGatherTreeNode): TstgGatherTreeNode;
+begin
+  if Assigned(ACheckParent) then
+    Result := ACheckParent
+  else if Assigned(ANode.Parent) then
+    Result := TstgGatherTreeNode(ANode.Parent)
+  else
+    Result := TstgGatherTreeNode(FCacheData.GatherTree.Root);
+end;
+
+end.

+ 738 - 0
SubTenderGather/stgGatherCacheData.pas

@@ -0,0 +1,738 @@
+unit stgGatherCacheData;
+
+interface
+
+uses
+  CacheTree, SysUtils, BillsTree, Classes, sdDB, mDataRecord;
+
+const
+  // 新增项目节
+  iErrorXmjAdd = 1;
+  sErrorXmjAdd = '新增';
+  // 存在同号项目节,但名称、单价不同
+  iErrorXmjDiff = 2;    
+  sErrorXmjDiff = '存在同号不同名(单位)';
+  // 项目节层次少于总包
+  iErrorXmjLess = 3;
+  sErrorXmjLess = '父项项目节,层次少于总包';
+
+  // 新增工程量清单
+  iErrorGclAdd = 11;
+  sErrorGclAdd = '新增';
+  // 存在同名工程量清单,但名称、单价不同
+  iErrorGclDiff = 12;   
+  sErrorGclDiff = '存在同号不同名(单位)';
+  // 工程量清单层次多于总包
+  iErrorGclMore = 13;
+  sErrorGclMore = '工程量清单,层次多于总包';
+  // 工程量清单层次少于总包
+  iErrorGclLess = 14;
+  sErrorGclLess = '工程量清单,层次少于总包';
+
+type
+  TstgStageData = class
+  private
+    FDealQuantity: Double;
+    FDealTotalPrice: Double;
+    FQcQuantity: Double;
+    FQcTotalPrice: Double;
+    FQcBGLCode: string;
+    FQcBGLNum: string;
+
+    procedure AddBGLCodeAndNum(ACode, ANum: string);
+  public
+    procedure ClearData;
+    procedure AddStageData(AStageData: TstgStageData);
+    procedure AssignedData(AStageRecord: TStageRecord);
+
+    property DealQuantity: Double read FDealQuantity;
+    property DealTotalPrice: Double read FDealTotalPrice;
+    property QcQuantity: Double read FQcQuantity;
+    property QcTotalPrice: Double read FQcTotalPrice;
+    property QcBGLCode: string read FQcBGLCode;
+    property QcBGLNum: string read FQcBGLNum;
+  end;
+
+  TstgSubTenderDetailData = class
+  private
+    FSerialNo: Integer;
+    FLeafXmjCode: string;
+    FDetailStage: TstgStageData;
+  public
+    constructor Create(ANode: TMeasureBillsIDTreeNode);
+    destructor Destroy; override;
+
+    property SerialNo: Integer read FSerialNo;
+    property LeafXmjCode: string read FLeafXmjCode;
+    property DetailStage: TstgStageData read FDetailStage;
+  end;
+
+  TstgSubTenderStageData = class
+  private
+    FSubTenderID: Integer;
+    FGather: TstgStageData;
+    FDetails: TList;
+    function GetDetail(AIndex: Integer): TstgSubTenderDetailData;
+    function GetDetailCount: Integer;
+  public
+    constructor Create(ASubTenderID: Integer);
+    destructor Destroy; override;
+
+    function AddDetail(ANode: TMeasureBillsIDTreeNode): TstgSubTenderDetailData;
+
+    procedure CalculateGather;
+
+    property SubTenderID: Integer read FSubTenderID;
+    property Gather: TstgStageData read FGather;
+    property DetailCount: Integer read GetDetailCount;
+    property Detail[AIndex: Integer]: TstgSubTenderDetailData read GetDetail;
+  end;
+
+  TstgGatherTreeNode = class(TCacheNode)
+  private
+    FCode: string;
+    FB_Code: string;
+    FName: string;
+    FUnits: string;
+
+    FIsSumBase: Boolean;
+    FIsLeafXmj: Boolean;
+    FIsLeaf: Boolean;
+    FIsSubTender: Boolean;
+
+    FGather: TstgStageData;
+    FSubTenders: TList;
+    function GetIsGclBills: Boolean;
+    function GetSubTender(AIndex: Integer): TstgSubTenderStageData;
+    function GetSubTenderCount: Integer;
+  public
+    constructor Create(ATree: TCacheTree; AID: Integer); override;
+    destructor Destroy; override;
+
+    function FindSubTender(ASubTenderID: Integer): TstgSubTenderStageData;
+    function SafeSubTender(ASubTenderID: Integer): TstgSubTenderStageData;
+
+    procedure CalculateGather;
+
+    property Code: string read FCode write FCode;
+    property B_Code: string read FB_Code write FB_Code;
+    property Name: string read FName write FName;
+    property Units: string read FUnits write FUnits;
+
+    property IsSumBase: Boolean read FIsSumBase write FIsSumBase;
+    property IsLeafXmj: Boolean read FIsLeafXmj write FIsLeafXmj;
+    property IsLeaf: Boolean read FIsLeaf write FIsLeaf;
+    property IsSubTender: Boolean read FIsSubTender write FIsSubTender;
+
+    property IsGclBills: Boolean read GetIsGclBills;
+
+    property SubTenderCount: Integer read GetSubTenderCount;
+    property SubTender[AIndex: Integer]: TstgSubTenderStageData read GetSubTender;
+
+    property Gather: TstgStageData read FGather;
+  end;
+
+  TstgGatherTree = class(TCacheTree)
+  private
+    FFixedNodes: TCacheNodeList;
+    // -1的情况下默认自动赋值一个新的ID
+    function GetNewNode(AID: Integer = -1): TstgGatherTreeNode; overload;
+
+    function CheckLeafXmj(ANode: TstgGatherTreeNode): Boolean;
+  public
+    constructor Create; override;
+    destructor Destroy; override;
+
+    function FindNextSibling(AParent: TCacheNode; ACode, AB_Code: string): TstgGatherTreeNode;
+    function FindNode(AParent: TCacheNode; AInfo: TBillsIDTreeNode): TstgGatherTreeNode; overload;
+    function FindNode(AID: Integer): TstgGatherTreeNode; overload;
+
+    function AddFixedNode(AParent: TCacheNode; ANextSibling:
+      TCacheNode = nil; AFixedID: Integer = -1): TstgGatherTreeNode;
+    function AddNode(AParent: TCacheNode; ANextSibling:
+      TCacheNode = nil; ASumBaseID: Integer = -1): TstgGatherTreeNode;
+
+    function AddSumBaseNode(AParent: TCacheNode; ASumBaseID: Integer): TstgGatherTreeNode;
+    function AddSubTenderNode(AParent: TCacheNode; ANextSibling: TCacheNode; AFixedID: Integer = -1): TstgGatherTreeNode;
+
+    // Only for Debugging lot of Data
+    procedure SaveTreeToFile(const AFileName: string);
+
+    procedure MarkLeafXmj;
+    procedure CalculateAll;
+  end;
+
+  TstgGatherSubTender = class
+  private
+    FID: Integer;
+    FRec: TsdDataRecord;
+  public
+    constructor Create(ARec: TsdDataRecord);
+
+    property ID: Integer read FID;
+    property Rec: TsdDataRecord read FRec;
+  end;
+
+  TstgErrorInfo = class
+  private
+    FRelaNode: TstgGatherTreeNode;
+    FErrorType: Integer;
+
+    FDetails: TList;
+    function GetDetail(AIndex: Integer): TstgGatherTreeNode;
+    function GetDetailCount: Integer;
+  public
+    constructor Create(ARelaNode: TstgGatherTreeNode);
+    destructor Destroy; override;
+
+    procedure AddErrorDetail(ARelaDetailNode: TstgGatherTreeNode);
+
+    property RelaNode: TstgGatherTreeNode read FRelaNode;
+    property ErrorType: Integer read FErrorType write FErrorType;
+
+    property DetailCount: Integer read GetDetailCount;
+    property Detail[AIndex: Integer]: TstgGatherTreeNode read GetDetail;
+  end;
+
+  TstgGatherCacheData = class
+  private
+    FGatherTree: TstgGatherTree;
+    FSubTenders: TList;
+    FErrors: TList;
+
+    function FindError(ANode: TstgGatherTreeNode): TstgErrorInfo;
+    function NewError(ANode: TstgGatherTreeNode; AErrorType: Integer): TstgErrorInfo;
+
+    function GetSubTenderCount: Integer;
+    function GetSubTender(AIndex: Integer): TstgGatherSubTender;
+    function GetErrorCount: Integer;
+    function GetError(AIndex: Integer): TstgErrorInfo;
+  public
+    constructor Create;
+    destructor Destroy; override;
+
+    function FindSubTender(AID: Integer): TstgGatherSubTender;
+    function AddSubTender(ARec: TsdDataRecord): TstgGatherSubTender;
+
+    procedure AddError(ANode, ALeafErrorNode: TstgGatherTreeNode; AErrorType: Integer);
+
+    property SubTenderCount: Integer read GetSubTenderCount;
+    property SubTender[AIndex: Integer]: TstgGatherSubTender read GetSubTender;
+
+    property ErrorCount: Integer read GetErrorCount;
+    property Error[AIndex: Integer]: TstgErrorInfo read GetError;
+
+    property GatherTree: TstgGatherTree read FGatherTree;
+  end;
+
+implementation
+
+uses
+  ZhAPI, UtilMethods, Math;
+
+{ TstgGatherTreeNode }
+
+procedure TstgGatherTreeNode.CalculateGather;
+var
+  i: Integer;
+  vSubTender: TstgSubTenderDetailData;
+begin
+  FGather.ClearData;
+  for i := 0 to FSubTenders.Count - 1 do
+  begin
+    SubTender[i].CalculateGather;
+    FGather.AddStageData(SubTender[i].Gather);
+  end;
+end;
+
+constructor TstgGatherTreeNode.Create(ATree: TCacheTree; AID: Integer);
+begin
+  inherited Create(ATree, AID);
+  FSubTenders := TList.Create;
+  FGather := TstgStageData.Create;
+end;
+
+destructor TstgGatherTreeNode.Destroy;
+begin
+  FGather.Free;
+  ClearObjects(FSubTenders);
+  FSubTenders.Free;
+  inherited;
+end;
+
+function TstgGatherTreeNode.FindSubTender(
+  ASubTenderID: Integer): TstgSubTenderStageData;
+var
+  i: Integer;
+begin
+  Result := nil;
+  for i := 0 to FSubTenders.Count - 1 do
+  begin
+    if ASubTenderID = SubTender[i].SubTenderID then
+    begin
+      Result := SubTender[i];
+      Break;
+    end;
+  end;
+end;
+
+function TstgGatherTreeNode.GetIsGclBills: Boolean;
+begin
+  Result := FB_Code <> '';
+end;
+
+function TstgGatherTreeNode.GetSubTender(
+  AIndex: Integer): TstgSubTenderStageData;
+begin
+  Result := TstgSubTenderStageData(FSubTenders.Items[AIndex]);
+end;
+
+function TstgGatherTreeNode.GetSubTenderCount: Integer;
+begin
+  Result := FSubTenders.Count;
+end;
+
+function TstgGatherTreeNode.SafeSubTender(
+  ASubTenderID: Integer): TstgSubTenderStageData;
+begin
+  Result := FindSubTender(ASubTenderID);
+  if not Assigned(Result) then
+  begin
+    Result := TstgSubTenderStageData.Create(ASubTenderID);
+    FSubTenders.Add(Result);
+  end;
+end;
+
+{ TstgGatherTree }
+
+function TstgGatherTree.AddFixedNode(AParent, ANextSibling: TCacheNode;
+  AFixedID: Integer): TstgGatherTreeNode;
+begin
+  Result := GetNewNode(AFixedID);
+  if Assigned(ANextSibling) then
+    ANextSibling.InsertPreSibling(Result)
+  else if Assigned(AParent) then
+    AParent.InsertChild(Result)
+  else
+    Root.InsertChild(Result);
+  FFixedNodes.Add(Result);
+end;
+
+function TstgGatherTree.AddNode(AParent, ANextSibling: TCacheNode;
+  ASumBaseID: Integer): TstgGatherTreeNode;
+begin
+  Result := GetNewNode(ASumBaseID);
+  if Assigned(ANextSibling) then
+    ANextSibling.InsertPreSibling(Result)
+  else if Assigned(AParent) then
+    AParent.InsertChild(Result)
+  else
+    Root.InsertChild(Result);
+end;
+
+function TstgGatherTree.AddSubTenderNode(AParent, ANextSibling: TCacheNode;
+  AFixedID: Integer): TstgGatherTreeNode;
+begin
+  Result := GetNewNode(AFixedID);
+  Result.IsSubTender := True;
+
+  if Assigned(ANextSibling) then
+    ANextSibling.InsertPreSibling(Result)
+  else if Assigned(AParent) then
+    AParent.InsertChild(Result)
+  else
+    Root.InsertChild(Result);
+end;
+
+function TstgGatherTree.AddSumBaseNode(AParent: TCacheNode;
+  ASumBaseID: Integer): TstgGatherTreeNode;
+begin
+  Result := GetNewNode(ASumBaseID);
+  Result.IsSumBase := True;
+
+  if Assigned(AParent) then
+    AParent.InsertChild(Result)
+  else
+    Root.InsertChild(Result);
+end;
+
+procedure TstgGatherTree.CalculateAll;
+var
+  i: Integer;
+begin
+  for i := 0 to CacheNodes.Count - 1 do
+    TstgGatherTreeNode(CacheNodes[i]).CalculateGather;
+end;
+
+function TstgGatherTree.CheckLeafXmj(ANode: TstgGatherTreeNode): Boolean;
+var
+  iChild: Integer;
+  vChild: TstgGatherTreeNode;
+begin
+  Result := True;
+  for iChild := 0 to ANode.Children.Count - 1 do
+  begin
+    vChild := TstgGatherTreeNode(ANode.Children.Items[iChild]);
+    if vChild.FB_Code = '' then
+    begin
+      Result := False;
+      Break;
+    end;
+  end;
+end;
+
+constructor TstgGatherTree.Create;
+begin
+  inherited;
+  FFixedNodes := TCacheNodeList.Create;
+  NewNodeID := 100;
+end;
+
+destructor TstgGatherTree.Destroy;
+begin
+  FFixedNodes.Free;
+  inherited;
+end;
+
+function TstgGatherTree.FindNextSibling(AParent: TCacheNode;
+  ACode, AB_Code: string): TstgGatherTreeNode;
+var
+  vChild: TstgGatherTreeNode;
+begin
+  Result := nil;
+  if Assigned(AParent) then
+    vChild := TstgGatherTreeNode(AParent.FirstChild)
+  else
+    vChild := TstgGatherTreeNode(Root.FirstChild);
+  while not Assigned(Result) and Assigned(vChild) do
+  begin
+    if (CompareCode(ACode, vChild.Code) < 0) or (CompareCode(AB_Code, vChild.B_Code) < 0) then
+      Result := vChild;
+    vChild := TstgGatherTreeNode(vChild.NextSibling);
+  end;
+end;
+
+function TstgGatherTree.FindNode(AID: Integer): TstgGatherTreeNode;
+var
+  i: Integer;
+  Node: TCacheNode;
+begin
+  Result := nil;
+  for i := 0 to FFixedNodes.Count - 1 do
+  begin
+    Node := FFixedNodes.Items[i];
+    if Node.ID = AID then
+    begin
+      Result := TstgGatherTreeNode(Node);
+      Break;
+    end;
+  end;
+end;
+
+function TstgGatherTree.FindNode(AParent: TCacheNode;
+  AInfo: TBillsIDTreeNode): TstgGatherTreeNode;
+var
+  vNode: TstgGatherTreeNode;
+begin
+  Result := nil;
+  if Assigned(AParent) then
+    vNode := TstgGatherTreeNode(AParent.FirstChild)
+  else
+    vNode := TstgGatherTreeNode(Root.FirstChild);
+
+  while Assigned(vNode) and not Assigned(Result) do
+  begin
+    if SameText(vNode.Code, Trim(AInfo.Rec.Code.AsString)) and SameText(vNode.B_Code, Trim(AInfo.Rec.B_Code.AsString))
+        and SameText(vNode.Name, Trim(AInfo.Rec.Name.AsString)) and SameText(vNode.Units, Trim(AInfo.Rec.Units.AsString))
+        and ((vNode.B_Code = '') or (vNode.IsLeaf = not AInfo.HasChildren)) then
+      Result := vNode;
+    vNode := TstgGatherTreeNode(vNode.NextSibling);
+  end;
+end;
+
+function TstgGatherTree.GetNewNode(AID: Integer): TstgGatherTreeNode;
+begin
+  if AID = -1 then
+    Result := TstgGatherTreeNode.Create(Self, GetNewNodeID)
+  else
+    Result := TstgGatherTreeNode.Create(Self, AID);
+  NewNodeID := Max(NewNodeID, AID + 1);
+  CacheNodes.Add(Result);
+  if AID < 100 then
+    FFixedNodes.Add(Result);
+end;
+
+procedure TstgGatherTree.MarkLeafXmj;
+var
+  i: Integer;
+  vNode: TstgGatherTreeNode;
+begin
+  for i := 0 to CacheNodes.Count - 1 do
+  begin
+    vNode := TstgGatherTreeNode(CacheNodes.Items[i]);
+    vNode.IsLeafXmj := CheckLeafXmj(vNode);
+  end;
+end;
+
+procedure TstgGatherTree.SaveTreeToFile(const AFileName: string);
+var
+  sgs: TStringList;
+  I: Integer;
+  Node: TstgGatherTreeNode;
+begin
+  sgs := TStringList.Create;
+  try
+    for I := 0 to CacheNodes.Count - 1 do
+    begin
+      Node := TstgGatherTreeNode(CacheNodes.Items[I]);
+      sgs.Add(Format('ID: %3d; ParentID: %3d; NextID: %3d; Code: %s; B_Code: %s; Name: %s;',
+        [Node.ID, Node.ParentID, Node.NextSiblingID, Node.Code, Node.B_Code, Node.Name]));
+    end;
+    sgs.SaveToFile(AFileName);
+  finally
+    sgs.Free;
+  end;
+end;
+
+{ TstgGatherCacheData }
+
+procedure TstgGatherCacheData.AddError(ANode,
+  ALeafErrorNode: TstgGatherTreeNode; AErrorType: Integer);
+var
+  vError: TstgErrorInfo;
+begin
+  vError := FindError(ANode);
+  if not Assigned(vError) then
+    vError := NewError(ANode, AErrorType);
+  vError.AddErrorDetail(ALeafErrorNode);
+end;
+
+function TstgGatherCacheData.AddSubTender(
+  ARec: TsdDataRecord): TstgGatherSubTender;
+begin
+  Result := FindSubTender(ARec.ValueByName('ID').AsInteger);
+  if not Assigned(Result) then
+  begin
+    Result := TstgGatherSubTender.Create(ARec);
+    FSubTenders.Add(Result);
+  end;
+end;
+
+constructor TstgGatherCacheData.Create;
+begin
+  FGatherTree := TstgGatherTree.Create;
+  FSubTenders := TList.Create;
+  FErrors := TList.Create;
+end;
+
+destructor TstgGatherCacheData.Destroy;
+begin
+  ClearObjects(FErrors);
+  FErrors.Free;
+  ClearObjects(FSubTenders);
+  FSubTenders.Free;
+  FGatherTree.Free;
+  inherited;
+end;
+
+function TstgGatherCacheData.FindError(
+  ANode: TstgGatherTreeNode): TstgErrorInfo;
+var
+  i: Integer;
+begin
+  Result := nil;
+  for i := 0 to ErrorCount - 1 do
+  begin
+    if Error[i].RelaNode = ANode then
+    begin
+      Result := Error[i];
+      Break;
+    end;
+  end;
+end;
+
+function TstgGatherCacheData.FindSubTender(
+  AID: Integer): TstgGatherSubTender;
+var
+  i: Integer;
+begin
+  Result := nil;
+  for i := 0 to SubTenderCount - 1 do
+  begin
+    if SubTender[i].ID = AID then
+    begin
+      Result := SubTender[i];
+      Break;
+    end;
+  end;
+end;
+
+function TstgGatherCacheData.GetError(AIndex: Integer): TstgErrorInfo;
+begin
+  Result := TstgErrorInfo(FErrors.Items[AIndex]);
+end;
+
+function TstgGatherCacheData.GetErrorCount: Integer;
+begin
+  Result := FErrors.Count;
+end;
+
+function TstgGatherCacheData.GetSubTender(AIndex: Integer): TstgGatherSubTender;
+begin
+  Result := TstgGatherSubTender(FSubTenders.Items[AIndex]);
+end;
+
+function TstgGatherCacheData.GetSubTenderCount: Integer;
+begin
+  Result := FSubTenders.Count;
+end;
+
+function TstgGatherCacheData.NewError(
+  ANode: TstgGatherTreeNode; AErrorType: Integer): TstgErrorInfo;
+begin
+  Result := TstgErrorInfo.Create(ANode);
+  Result.ErrorType := AErrorType;
+  FErrors.Add(Result);
+end;
+
+{ TstgGatherSubTender }
+
+constructor TstgGatherSubTender.Create(ARec: TsdDataRecord);
+begin
+  FID := ARec.ValueByName('ID').AsInteger;
+  FRec := ARec;
+end;
+
+{ TstgStageData }
+
+procedure TstgStageData.AddBGLCodeAndNum(ACode, ANum: string);
+var
+  sCode, sNum: string;
+begin
+  sCode := FQcBGLCode;
+  sNum := FQcBGLNum;
+  MergeRelaBGLAndNum(sCode, sNum, ACode, ANum);
+  FQcBGLCode := sCode;
+  FQcBGLNum := sNum;
+end;
+
+procedure TstgStageData.AddStageData(AStageData: TstgStageData);
+begin
+  FDealQuantity := FDealQuantity + AStageData.DealQuantity;
+  FDealTotalPrice := FDealTotalPrice + AStageData.DealTotalPrice;
+  FQcQuantity := FQcQuantity + AStageData.QcQuantity;
+  FQcTotalPrice := FQcTotalPrice + AStageData.QcTotalPrice;
+  AddBGLCodeAndNum(AStageData.QcBGLCode, AStageData.QcBGLNum);
+end;
+
+procedure TstgStageData.AssignedData(AStageRecord: TStageRecord);
+begin
+  FDealQuantity := AStageRecord.DealQuantity.AsFloat;
+  FDealTotalPrice := AStageRecord.DealTotalPrice.AsFloat;
+  FQcQuantity := AStageRecord.QcQuantity.AsFloat;
+  FQcTotalPrice := AStageRecord.QcTotalPrice.AsFloat;
+  FQcBGLCode := AStageRecord.QcBGLCode.AsString;
+  FQcBGLNum := AStageRecord.QcBGLNum.AsString;
+end;
+
+procedure TstgStageData.ClearData;
+begin
+  FDealQuantity := 0;
+  FDealTotalPrice := 0;
+  FQcQuantity := 0;
+  FQcTotalPrice := 0;
+  FQcBGLCode := '';
+  FQcBGLNum := '';
+end;
+
+{ TstgSubTenderStageData }
+
+function TstgSubTenderStageData.AddDetail(
+  ANode: TMeasureBillsIDTreeNode): TstgSubTenderDetailData;
+begin
+  Result := TstgSubTenderDetailData.Create(ANode);
+  FDetails.Add(Result);
+end;
+
+procedure TstgSubTenderStageData.CalculateGather;
+var
+  i: Integer;
+begin
+  FGather.ClearData;
+  for i := 0 to DetailCount - 1 do
+    FGather.AddStageData(Detail[i].DetailStage);
+end;
+
+constructor TstgSubTenderStageData.Create(ASubTenderID: Integer);
+begin
+  FSubTenderID := ASubTenderID;
+  FGather := TstgStageData.Create;
+  FDetails := TList.Create;
+end;
+
+destructor TstgSubTenderStageData.Destroy;
+begin
+  ClearObjects(FDetails);
+  FDetails.Free;
+  FGather.Free;
+  inherited;
+end;
+
+function TstgSubTenderStageData.GetDetail(
+  AIndex: Integer): TstgSubTenderDetailData;
+begin
+  Result := TstgSubTenderDetailData(FDetails.Items[AIndex]);
+end;
+
+function TstgSubTenderStageData.GetDetailCount: Integer;
+begin
+  Result := FDetails.Count;
+end;
+
+{ TstgSubTenderDetailData }
+
+constructor TstgSubTenderDetailData.Create(ANode: TMeasureBillsIDTreeNode);
+begin
+  FSerialNo := ANode.MajorIndex + 1;
+  FDetailStage := TstgStageData.Create;
+  if Assigned(ANode.StageRec) then
+    FDetailStage.AssignedData(ANode.StageRec);
+end;
+
+destructor TstgSubTenderDetailData.Destroy;
+begin
+  FDetailStage.Free;
+  inherited;
+end;
+
+{ TstgErrorInfo }
+
+procedure TstgErrorInfo.AddErrorDetail(
+  ARelaDetailNode: TstgGatherTreeNode);
+begin
+  FDetails.Add(ARelaDetailNode);
+end;
+
+constructor TstgErrorInfo.Create(ARelaNode: TstgGatherTreeNode);
+begin
+  FRelaNode := ARelaNode;
+  FDetails := TList.Create;
+end;
+
+destructor TstgErrorInfo.Destroy;
+begin
+  FDetails.Free;
+  inherited;
+end;
+
+function TstgErrorInfo.GetDetail(AIndex: Integer): TstgGatherTreeNode;
+begin
+  Result :=  TstgGatherTreeNode(FDetails.Items[AIndex]);
+end;
+
+function TstgErrorInfo.GetDetailCount: Integer;
+begin
+  Result := FDetails.Count;
+end;
+
+end.

+ 137 - 0
SubTenderGather/stgGatherControl.pas

@@ -0,0 +1,137 @@
+unit stgGatherControl;
+
+interface
+
+uses
+  Classes, stgGatherCacheData, stgGatherDm, stgResultFrm,
+  stgGather;
+
+type
+  TstgGatherControl = class
+  private
+    FProjects: TList;
+    FSumBaseFile: string;
+
+    FGatherCacheData: tstgGatherCacheData;
+    FGatherData: TstgGatherData;
+    FResultForm: TstgResultForm;
+
+    FHintPosition: Integer;
+
+    procedure LoadHint(const ATenderName: string);
+
+    procedure LoadSumBaseFile;
+    procedure GatherSubTenderFiles;
+    procedure CheckErrorData;
+    procedure SaveGatherResult;
+    procedure ShowGatherResult;
+  public
+    constructor Create;
+    destructor Destroy; override;
+
+    procedure Gather;
+
+    property Projects: TList read FProjects;
+    property SumBaseFile: string read FSumBaseFile write FSumBaseFile;
+  end;
+
+implementation
+
+uses
+  ProgressHintFrm, SysUtils;
+
+{ TstgGatherControl }
+
+procedure TstgGatherControl.CheckErrorData;
+var
+  vChecker: TstgErrorChecker;
+begin
+  vChecker := TstgErrorChecker.Create;
+  try
+    vChecker.Check(FGatherCacheData);
+  finally
+    vChecker.Free;
+  end;
+end;
+
+constructor TstgGatherControl.Create;
+begin
+  FProjects := TList.Create;
+  FGatherCacheData := TstgGatherCacheData.Create;
+  FGatherData := TstgGatherData.Create(nil);
+end;
+
+destructor TstgGatherControl.Destroy;
+begin
+  FGatherData.Free;
+  FGatherCacheData.Free;
+  FProjects.Free;
+  inherited;
+end;
+
+procedure TstgGatherControl.Gather;
+begin
+  FHintPosition := 0;
+  ShowProgressHint('正在导入总包基准文件数据...', FProjects.Count + 2);
+  LoadSumBaseFile;
+  GatherSubTenderFiles;
+  UpdateProgressHint('正在检查汇总结果...');
+  UpdateProgressPosition(FProjects.Count + 1);
+  CheckErrorData;
+  UpdateProgressPosition(FProjects.Count + 2);
+  SaveGatherResult;
+  CloseProgressHint;
+  ShowGatherResult;
+end;
+
+procedure TstgGatherControl.GatherSubTenderFiles;
+var
+  vGather: TstgSubTenderFileGather;
+begin
+  vGather := TstgSubTenderFileGather.Create;
+  try
+    vGather.LoadHint := LoadHint;
+    vGather.GatherTo(FGatherCacheData, FProjects);
+  finally
+    vGather.Free;
+  end;
+end;
+
+procedure TstgGatherControl.LoadHint(const ATenderName: string);
+begin
+  Inc(FHintPosition);
+  UpdateProgressHint(Format('正在汇总分包标段"%s"...', [ATenderName]));
+  UpdateProgressPosition(FHintPosition);
+end;
+
+procedure TstgGatherControl.LoadSumBaseFile;
+var
+  vLoader: TstgSumBaseFileLoader;
+begin
+  vLoader := TstgSumBaseFileLoader.Create(FGatherCacheData.GatherTree, FSumBaseFile);
+  try
+    vLoader.LoadData;
+  finally
+    vLoader.Free;
+  end;
+end;
+
+procedure TstgGatherControl.SaveGatherResult;
+begin
+  FGatherData.LoadGatherData(FGatherCacheData);
+end;
+
+procedure TstgGatherControl.ShowGatherResult; 
+var
+  Form: TstgResultForm;
+begin
+  Form := TstgResultForm.Create(nil);
+  try
+    Form.SetGatherData(FGatherData);
+    Form.ShowModal;
+  finally
+    Form.Free;
+  end;
+end;
+
+end.

+ 304 - 0
SubTenderGather/stgGatherDm.dfm

@@ -0,0 +1,304 @@
+object stgGatherData: TstgGatherData
+  OldCreateOrder = False
+  Left = 37
+  Top = 195
+  Height = 253
+  Width = 482
+  object smpGatherTree: TsdMemoryProvider
+    Left = 40
+    Top = 24
+  end
+  object sddGatherTree: TsdDataSet
+    Active = True
+    Provider = smpGatherTree
+    Left = 40
+    Top = 87
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D650809507265636973696F6E02000453697A6502000001044E616D
+      650608506172656E744944094669656C644E616D650608506172656E74494408
+      44617461547970650203084461746153697A6502040549734B6579080F4E6565
+      6450726F636573734E616D650809507265636973696F6E02000453697A650200
+      0001044E616D65060D4E6578745369626C696E674944094669656C644E616D65
+      060D4E6578745369626C696E6749440844617461547970650203084461746153
+      697A6502040549734B6579080F4E65656450726F636573734E616D6508095072
+      65636973696F6E02000453697A6502000001044E616D650604436F6465094669
+      656C644E616D650604436F64650844617461547970650218084461746153697A
+      6502320549734B6579080F4E65656450726F636573734E616D65080950726563
+      6973696F6E02000453697A6502000001044E616D650606425F436F6465094669
+      656C644E616D650606425F436F64650844617461547970650218084461746153
+      697A6502320549734B6579080F4E65656450726F636573734E616D6508095072
+      65636973696F6E02000453697A6502000001044E616D6506044E616D65094669
+      656C644E616D6506044E616D650844617461547970650218084461746153697A
+      6503FF000549734B6579080F4E65656450726F636573734E616D650809507265
+      636973696F6E02000453697A6502000001044E616D650605556E697473094669
+      656C644E616D650605556E697473084461746154797065021808446174615369
+      7A6502140549734B6579080F4E65656450726F636573734E616D650809507265
+      636973696F6E02000453697A6502000001044E616D65060C4465616C5175616E
+      74697479094669656C644E616D65060C4465616C5175616E7469747908446174
+      61547970650206084461746153697A6502080549734B6579080F4E6565645072
+      6F636573734E616D650809507265636973696F6E02000453697A650200000104
+      4E616D65060A51635175616E74697479094669656C644E616D65060A51635175
+      616E746974790844617461547970650206084461746153697A6502080549734B
+      6579080F4E65656450726F636573734E616D650809507265636973696F6E0200
+      0453697A6502000001044E616D65060B497353756254656E646572094669656C
+      644E616D65060B497353756254656E6465720844617461547970650205084461
+      746153697A6502010549734B6579080F4E65656450726F636573734E616D6508
+      09507265636973696F6E02000453697A6502000001044E616D65060E4465616C
+      546F74616C5072696365094669656C644E616D65060E4465616C546F74616C50
+      726963650844617461547970650206084461746153697A6502080549734B6579
+      080F4E65656450726F636573734E616D650809507265636973696F6E02000453
+      697A6502000001044E616D65060C5163546F74616C5072696365094669656C64
+      4E616D65060C5163546F74616C50726963650844617461547970650206084461
+      746153697A6502080549734B6579080F4E65656450726F636573734E616D6508
+      09507265636973696F6E02000453697A6502000001044E616D65060951634247
+      4C436F6465094669656C644E616D650609516342474C436F6465084461746154
+      7970650218084461746153697A6503FF000549734B6579080F4E65656450726F
+      636573734E616D650809507265636973696F6E02000453697A6502000001044E
+      616D650608516342474C4E756D094669656C644E616D650608516342474C4E75
+      6D0844617461547970650218084461746153697A6503FF000549734B6579080F
+      4E65656450726F636573734E616D650809507265636973696F6E02000453697A
+      6502000001044E616D650609497353756D42617365094669656C644E616D6506
+      09497353756D426173650844617461547970650205084461746153697A650201
+      0549734B6579080F4E65656450726F636573734E616D65080950726563697369
+      6F6E02000453697A6502000001044E616D65060649734C656166094669656C64
+      4E616D65060649734C6561660844617461547970650205084461746153697A65
+      02010549734B6579080F4E65656450726F636573734E616D6508095072656369
+      73696F6E02000453697A6502000000}
+  end
+  object sdvGatherTree: TsdDataView
+    Active = False
+    DataSet = sddGatherTree
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'ID'
+      end
+      item
+        FieldName = 'ParentID'
+      end
+      item
+        FieldName = 'NextSiblingID'
+      end
+      item
+        FieldName = 'Code'
+      end
+      item
+        FieldName = 'B_Code'
+      end
+      item
+        FieldName = 'Name'
+      end
+      item
+        FieldName = 'Units'
+      end
+      item
+        FieldName = 'DealQuantity'
+      end
+      item
+        FieldName = 'QcQuantity'
+      end>
+    OnCurrentChanged = sdvGatherTreeCurrentChanged
+    OnGetText = sdvGatherTreeGetText
+    Left = 40
+    Top = 152
+  end
+  object smpSubTenders: TsdMemoryProvider
+    Left = 136
+    Top = 24
+  end
+  object sddSubTenders: TsdDataSet
+    Active = True
+    Provider = smpSubTenders
+    Left = 136
+    Top = 88
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D650809507265636973696F6E02000453697A6502000001044E616D
+      6506044E616D65094669656C644E616D6506044E616D65084461746154797065
+      0218084461746153697A6503FF000549734B6579080F4E65656450726F636573
+      734E616D650809507265636973696F6E02000453697A6502000000}
+  end
+  object sdvSubTenders: TsdDataView
+    Active = True
+    DataSet = sddSubTenders
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'ID'
+      end
+      item
+        FieldName = 'Name'
+      end
+      item
+        FieldName = 'ErrorCount'
+      end>
+    OnCurrentChanged = sdvSubTendersCurrentChanged
+    Left = 136
+    Top = 152
+  end
+  object smpBillsDetail: TsdMemoryProvider
+    Left = 248
+    Top = 24
+  end
+  object sddBillsDetail: TsdDataSet
+    Active = True
+    Provider = smpBillsDetail
+    Left = 248
+    Top = 88
+    FieldListData = {
+      0101044E616D65060742696C6C734944094669656C644E616D65060742696C6C
+      7349440844617461547970650203084461746153697A6502040549734B657908
+      0F4E65656450726F636573734E616D650809507265636973696F6E0200045369
+      7A6502000001044E616D65060854656E6465724944094669656C644E616D6506
+      0854656E64657249440844617461547970650203084461746153697A65020405
+      49734B6579080F4E65656450726F636573734E616D650809507265636973696F
+      6E02000453697A6502000001044E616D65060A54656E6465724E616D65094669
+      656C644E616D65060A54656E6465724E616D6508446174615479706502180844
+      61746153697A6503FF000549734B6579080F4E65656450726F636573734E616D
+      650809507265636973696F6E02000453697A6502000001044E616D6506085365
+      7269616C4E6F094669656C644E616D65060853657269616C4E6F084461746154
+      7970650203084461746153697A6502040549734B6579080F4E65656450726F63
+      6573734E616D650809507265636973696F6E02000453697A6502000001044E61
+      6D65060C4465616C5175616E74697479094669656C644E616D65060C4465616C
+      5175616E746974790844617461547970650206084461746153697A6502080549
+      734B6579080F4E65656450726F636573734E616D650809507265636973696F6E
+      02000453697A6502000001044E616D65060E4465616C546F74616C5072696365
+      094669656C644E616D65060E4465616C546F74616C5072696365084461746154
+      7970650206084461746153697A6502080549734B6579080F4E65656450726F63
+      6573734E616D650809507265636973696F6E02000453697A6502000001044E61
+      6D65060A51635175616E74697479094669656C644E616D65060A51635175616E
+      746974790844617461547970650206084461746153697A6502080549734B6579
+      080F4E65656450726F636573734E616D650809507265636973696F6E02000453
+      697A6502000001044E616D65060C5163546F74616C5072696365094669656C64
+      4E616D65060C5163546F74616C50726963650844617461547970650206084461
+      746153697A6502080549734B6579080F4E65656450726F636573734E616D6508
+      09507265636973696F6E02000453697A6502000001044E616D65060951634247
+      4C436F6465094669656C644E616D650609516342474C436F6465084461746154
+      7970650218084461746153697A6503FF000549734B6579080F4E65656450726F
+      636573734E616D650809507265636973696F6E02000453697A6502000001044E
+      616D650608516342474C4E756D094669656C644E616D650608516342474C4E75
+      6D0844617461547970650218084461746153697A6503FF000549734B6579080F
+      4E65656450726F636573734E616D650809507265636973696F6E02000453697A
+      6502000000}
+  end
+  object sdvBillsDetail: TsdDataView
+    Active = False
+    DataSet = sddBillsDetail
+    Filtered = True
+    Columns = <
+      item
+        FieldName = 'BillsID'
+      end
+      item
+        FieldName = 'TenderID'
+      end
+      item
+        FieldName = 'TenderName'
+      end
+      item
+        FieldName = 'SerialNo'
+      end
+      item
+        FieldName = 'DealQuantity'
+      end
+      item
+        FieldName = 'DealTotalPrice'
+      end
+      item
+        FieldName = 'QcQuantity'
+      end
+      item
+        FieldName = 'QcTotalPrice'
+      end
+      item
+        FieldName = 'QcBGLCode'
+      end
+      item
+        FieldName = 'QcBGLNum'
+      end
+      item
+      end>
+    OnFilterRecord = sdvBillsDetailFilterRecord
+    OnGetText = sdvBillsDetailGetText
+    Left = 248
+    Top = 152
+  end
+  object sdmErrorDetail: TsdMemoryProvider
+    Left = 352
+    Top = 24
+  end
+  object sddErrorDetail: TsdDataSet
+    Active = True
+    Provider = sdmErrorDetail
+    Left = 352
+    Top = 88
+    FieldListData = {
+      0101044E616D65060854656E6465724944094669656C644E616D65060854656E
+      64657249440844617461547970650203084461746153697A6502040549734B65
+      79080F4E65656450726F636573734E616D650809507265636973696F6E020004
+      53697A6502000001044E616D65060A54656E6465724E616D65094669656C644E
+      616D65060A54656E6465724E616D650844617461547970650218084461746153
+      697A6503FF000549734B6579080F4E65656450726F636573734E616D65080950
+      7265636973696F6E02000453697A6502000001044E616D65060852656C61436F
+      6465094669656C644E616D65060852656C61436F646508446174615479706502
+      18084461746153697A6502320549734B6579080F4E65656450726F636573734E
+      616D650809507265636973696F6E02000453697A6502000001044E616D65060C
+      52656C6153657269616C4E6F094669656C644E616D65060C52656C6153657269
+      616C4E6F0844617461547970650203084461746153697A6502040549734B6579
+      080F4E65656450726F636573734E616D650809507265636973696F6E02000453
+      697A6502000001044E616D65060A44657461696C436F6465094669656C644E61
+      6D65060A44657461696C436F6465084461746154797065021808446174615369
+      7A6502320549734B6579080F4E65656450726F636573734E616D650809507265
+      636973696F6E02000453697A6502000001044E616D65060E44657461696C5365
+      7269616C4E6F094669656C644E616D65060E44657461696C53657269616C4E6F
+      0844617461547970650203084461746153697A6502040549734B6579080F4E65
+      656450726F636573734E616D650809507265636973696F6E02000453697A6502
+      000001044E616D6506094572726F7254797065094669656C644E616D65060945
+      72726F72547970650844617461547970650203084461746153697A6502040549
+      734B6579080F4E65656450726F636573734E616D650809507265636973696F6E
+      02000453697A6502000000}
+    IndexListData = {
+      01044E616D65060B69647854656E64657249440A4669656C644E616D65730608
+      54656E64657249440000}
+  end
+  object sdvErrorDetail: TsdDataView
+    Active = False
+    DataSet = sddErrorDetail
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'TenderID'
+      end
+      item
+        FieldName = 'TenderName'
+      end
+      item
+        FieldName = 'RelaID'
+      end
+      item
+        FieldName = 'RelaCode'
+      end
+      item
+        FieldName = 'RelaSerialNo'
+      end
+      item
+        FieldName = 'DetailID'
+      end
+      item
+        FieldName = 'DetailCode'
+      end
+      item
+        FieldName = 'DetailSerialNo'
+      end
+      item
+        FieldName = 'ErrorType'
+      end>
+    OnFilterRecord = sdvErrorDetailFilterRecord
+    OnGetText = sdvErrorDetailGetText
+    Left = 352
+    Top = 152
+  end
+end

+ 281 - 0
SubTenderGather/stgGatherDm.pas

@@ -0,0 +1,281 @@
+unit stgGatherDm;
+// ½á¹ûչʾ£¬ÄÚ´æ±í
+
+interface
+
+uses
+  SysUtils, Classes, stgGatherCacheData, sdDB, sdProvider, stgGatherUtils;
+
+type
+  TstgGatherData = class(TDataModule)
+    smpGatherTree: TsdMemoryProvider;
+    sddGatherTree: TsdDataSet;
+    sdvGatherTree: TsdDataView;
+    smpSubTenders: TsdMemoryProvider;
+    sddSubTenders: TsdDataSet;
+    sdvSubTenders: TsdDataView;
+    smpBillsDetail: TsdMemoryProvider;
+    sddBillsDetail: TsdDataSet;
+    sdvBillsDetail: TsdDataView;
+    sdmErrorDetail: TsdMemoryProvider;
+    sddErrorDetail: TsdDataSet;
+    sdvErrorDetail: TsdDataView;
+    procedure sdvBillsDetailGetText(var Text: String;
+      ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+      DisplayText: Boolean);
+    procedure sdvBillsDetailFilterRecord(ARecord: TsdDataRecord;
+      var Allow: Boolean);
+    procedure sdvGatherTreeCurrentChanged(ARecord: TsdDataRecord);
+    procedure sdvGatherTreeGetText(var Text: String;
+      ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+      DisplayText: Boolean);
+    procedure sdvErrorDetailFilterRecord(ARecord: TsdDataRecord;
+      var Allow: Boolean);
+    procedure sdvSubTendersCurrentChanged(ARecord: TsdDataRecord);
+    procedure sdvErrorDetailGetText(var Text: String;
+      ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+      DisplayText: Boolean);
+  private
+    procedure LoadSubTenders(ACacheData: TstgGatherCacheData);
+
+    procedure LoadGatherTreeNodeDetail(ANode: TstgGatherTreeNode);
+    procedure LoadGatherTreeNode(ANode: TstgGatherTreeNode);
+    procedure LoadGatherTree(ACacheData: TstgGatherCacheData);
+
+    procedure LoadError(AError: TstgErrorInfo);
+    procedure LoadErrors(ACacheData: TstgGatherCacheData);
+  public
+    procedure LoadGatherData(ACacheData: TstgGatherCacheData);
+  end;
+
+implementation
+
+uses
+  Variants, DB, ConditionalDefines;
+
+{$R *.dfm}
+
+{ TstgGatherData }
+
+procedure TstgGatherData.LoadGatherData(ACacheData: TstgGatherCacheData);
+begin
+  LoadSubTenders(ACacheData);
+  LoadGatherTree(ACacheData);
+  LoadErrors(ACacheData);
+
+  sdvGatherTree.Active := True;
+  sdvBillsDetail.Active := True;
+  sdvBillsDetail.RefreshFilter;
+
+  sdvSubTenders.Active := True;
+  sdvErrorDetail.Active := True;
+  sdvErrorDetail.RefreshFilter;
+end;
+
+procedure TstgGatherData.LoadGatherTree(ACacheData: TstgGatherCacheData);
+var
+  i: Integer;
+  vNode:TstgGatherTreeNode;
+begin
+  if _IsDebugView then
+    ACacheData.GatherTree.SaveTreeToFile('E:\stgGatherTree.txt');
+  for i := 0 to ACacheData.GatherTree.CacheNodes.Count - 1 do
+  begin
+    vNode := TstgGatherTreeNode(ACacheData.GatherTree.CacheNodes.Items[i]);
+    LoadGatherTreeNode(vNode);
+  end;
+end;
+
+procedure TstgGatherData.LoadGatherTreeNode(ANode: TstgGatherTreeNode);
+var
+  Rec: TsdDataRecord;
+begin
+  Rec := sddGatherTree.Add;
+  Rec.ValueByName('ID').AsInteger := ANode.ID;
+  Rec.ValueByName('ParentID').AsInteger := ANode.ParentID;
+  Rec.ValueByName('NextSiblingID').AsInteger := ANode.NextSiblingID;
+  Rec.ValueByName('Code').AsString := ANode.Code;
+  Rec.ValueByName('B_Code').AsString := ANode.B_Code;
+  Rec.ValueByName('Name').AsString := ANode.Name;
+  Rec.ValueByName('Units').AsString := ANode.Units;
+  Rec.ValueByName('IsSubTender').AsBoolean := ANode.IsSubTender;
+  Rec.ValueByName('IsSumBase').AsBoolean := ANode.IsSumBase;
+  Rec.ValueByName('IsLeaf').AsBoolean := ANode.IsLeaf;
+
+  Rec.ValueByName('DealQuantity').AsFloat := ANode.Gather.DealQuantity;
+  Rec.ValueByName('DealTotalPrice').AsFloat := ANode.Gather.DealTotalPrice;
+  Rec.ValueByName('QcQuantity').AsFloat := ANode.Gather.QcQuantity;
+  Rec.ValueByName('QcTotalPrice').AsFloat := ANode.Gather.QcTotalPrice;
+  Rec.ValueByName('QcBGLCode').AsString := ANode.Gather.QcBGLCode;
+  Rec.ValueByName('QcBGLNum').AsString := ANode.Gather.QcBGLNum;
+  if ANode.Children.Count = 0 then
+    LoadGatherTreeNodeDetail(ANode);
+end;
+
+procedure TstgGatherData.LoadGatherTreeNodeDetail(
+  ANode: TstgGatherTreeNode);
+var
+  iSub, iDetail: Integer;
+  vSub: TstgSubTenderStageData;
+  vDetail: TstgSubTenderDetailData;
+  Rec: TsdDataRecord;
+  sSubTenderName: string;
+begin
+  for iSub := 0 to ANode.SubTenderCount - 1 do
+  begin
+    vSub := ANode.SubTender[iSub];
+    for iDetail := 0 to vSub.DetailCount - 1 do
+    begin
+      vDetail := vSub.Detail[iDetail];
+      Rec := sddBillsDetail.Add;
+      Rec.ValueByName('BillsID').AsInteger := ANode.ID;
+      Rec.ValueByName('TenderID').AsInteger := vSub.SubTenderID;
+      Rec.ValueByName('TenderName').AsString := '';
+      Rec.ValueByName('SerialNo').AsInteger := vDetail.SerialNo;
+      Rec.ValueByName('DealQuantity').AsFloat := vDetail.DetailStage.DealQuantity;
+      Rec.ValueByName('DealTotalPrice').AsFloat := vDetail.DetailStage.DealTotalPrice;
+      Rec.ValueByName('QcQuantity').AsFloat := vDetail.DetailStage.QcQuantity;
+      Rec.ValueByName('QcTotalPrice').AsFloat := vDetail.DetailStage.QcTotalPrice;
+      Rec.ValueByName('QcBGLCode').AsString := vDetail.DetailStage.QcBGLCode;
+      Rec.ValueByName('QcBGLNum').AsString := vDetail.DetailStage.QcBGLNum;
+    end;
+  end;
+end;
+
+procedure TstgGatherData.LoadSubTenders(ACacheData: TstgGatherCacheData);
+var
+  i: Integer;
+  vSubTender: TstgGatherSubTender;
+  Rec: TsdDataRecord;
+begin
+  for i := 0 to ACacheData.SubTenderCount - 1 do
+  begin
+    vSubTender := ACacheData.SubTender[i];
+    Rec := sddSubTenders.Add;
+    Rec.ValueByName('ID').AsInteger := vSubTender.ID;
+    Rec.ValueByName('Name').AsString := vSubTender.Rec.ValueByName('Name').AsString;
+  end;
+end;
+
+procedure TstgGatherData.sdvBillsDetailGetText(var Text: String;
+  ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+  DisplayText: Boolean);
+
+  function GetTenderName(ATenderID: Integer): string;
+  begin
+    Result := VarToStrDef(sddSubTenders.Lookup('ID', ATenderID, 'Name'), '');
+  end;
+
+begin
+  if DisplayText and (AColumn.FieldName = 'TenderName') then
+    Text := GetTenderName(ARecord.ValueByName('TenderID').asInteger);
+end;
+
+procedure TstgGatherData.sdvBillsDetailFilterRecord(ARecord: TsdDataRecord;
+  var Allow: Boolean);
+begin
+  if Assigned(sdvGatherTree.Current) then
+    Allow := ARecord.ValueByName('BillsID').AsInteger = sdvGatherTree.Current.ValueByName('ID').AsInteger
+  else
+    Allow := False;
+end;
+
+procedure TstgGatherData.sdvGatherTreeCurrentChanged(
+  ARecord: TsdDataRecord);
+begin
+  sdvBillsDetail.RefreshFilter;
+end;
+
+procedure TstgGatherData.sdvGatherTreeGetText(var Text: String;
+  ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+  DisplayText: Boolean);
+begin
+  if (AValue.DataType = ftFloat) and (AValue.AsFloat = 0) then
+  begin
+    Text := '';
+  end;
+end;
+
+procedure TstgGatherData.LoadErrors(ACacheData: TstgGatherCacheData);
+var
+  i: Integer;
+begin
+  for i := 0 to ACacheData.ErrorCount - 1 do
+    LoadError(ACacheData.Error[i]);
+end;
+
+procedure TstgGatherData.sdvErrorDetailFilterRecord(ARecord: TsdDataRecord;
+  var Allow: Boolean);
+begin
+  if Assigned(sdvSubTenders.Current) then
+    Allow := ARecord.ValueByName('TenderID').AsInteger = sdvSubTenders.Current.ValueByName('ID').AsInteger
+  else
+    Allow := False;
+end;
+
+procedure TstgGatherData.LoadError(AError: TstgErrorInfo);
+
+  function GetSubTenderSerialNo(ANode: TstgGatherTreeNode; ATenderID: Integer): Integer;
+  var
+    vSource: TstgSubTenderStageData;
+  begin
+    vSource := ANode.FindSubTender(ATenderID);
+    if Assigned(vSource) then
+      Result := vSource.Detail[0].SerialNo;
+  end;
+
+var
+  i, j, k: Integer;
+  vRelaDetail: TstgGatherTreeNode;
+  vRelaDetailStage: TstgSubTenderStageData;
+  Rec: TsdDataRecord;
+begin
+  for i := 0 to AError.DetailCount - 1 do
+  begin
+    vRelaDetail := AError.Detail[i];
+    for j := 0 to vRelaDetail.SubTenderCount - 1 do
+    begin
+      vRelaDetailStage := vRelaDetail.SubTender[j];
+      for k := 0 to vRelaDetailStage.DetailCount - 1 do
+      begin
+        Rec := sddErrorDetail.Add;
+        Rec.ValueByName('TenderID').AsInteger := vRelaDetail.SubTender[j].SubTenderID;
+        Rec.ValueByName('RelaCode').AsString := AError.RelaNode.Code + AError.RelaNode.B_Code;
+        if AError.RelaNode.IsLeaf then
+          Rec.ValueByName('RelaSerialNo').AsInteger := vRelaDetailStage.Detail[k].SerialNo
+        else
+          Rec.ValueByName('RelaSerialNo').AsInteger := GetSubTenderSerialNo(AError.RelaNode, vRelaDetailStage.SubTenderID);
+        Rec.ValueByName('DetailCode').AsString := vRelaDetail.Code + vRelaDetail.B_Code;
+        Rec.ValueByName('DetailSerialNo').AsInteger := vRelaDetailStage.Detail[k].SerialNo;
+        Rec.ValueByName('ErrorType').AsInteger := AError.ErrorType;
+      end;
+    end;
+  end;
+end;
+
+procedure TstgGatherData.sdvSubTendersCurrentChanged(
+  ARecord: TsdDataRecord);
+begin
+  sdvErrorDetail.RefreshFilter;
+end;
+
+procedure TstgGatherData.sdvErrorDetailGetText(var Text: String;
+  ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+  DisplayText: Boolean);
+
+  function GetTenderName(ATenderID: Integer): string;
+  begin
+    Result := VarToStrDef(sddSubTenders.Lookup('ID', ATenderID, 'Name'), '');
+  end;
+
+begin
+  if DisplayText then
+  begin
+    if (AColumn.FieldName = 'TenderName') then
+      Text := GetTenderName(ARecord.ValueByName('TenderID').asInteger)
+    else if (AColumn.FieldName = 'ErrorType') then
+      Text := GetErrorTypeText(AValue.AsInteger);
+  end;
+end;
+
+end.

+ 25 - 0
SubTenderGather/stgGatherUtils.pas

@@ -0,0 +1,25 @@
+unit stgGatherUtils;
+
+interface
+
+uses
+  stgGatherCacheData;
+
+  function GetErrorTypeText(AErrorType: Integer): string;
+
+implementation
+
+function GetErrorTypeText(AErrorType: Integer): string;
+begin
+  case AErrorType of
+    iErrorXmjAdd: Result := sErrorXmjAdd;
+    iErrorXmjDiff: Result := sErrorXmjDiff;
+    iErrorXmjLess: Result := sErrorXmjLess;
+    iErrorGclAdd: Result := sErrorGclAdd;
+    iErrorGclDiff: Result := sErrorGclDiff;
+    iErrorGclMore: Result := sErrorGclMore;
+    iErrorGclLess: Result := sErrorGclLess;
+  end;
+end;
+
+end.

+ 665 - 0
SubTenderGather/stgResultFrm.dfm

@@ -0,0 +1,665 @@
+object stgResultForm: TstgResultForm
+  Left = 192
+  Top = 123
+  Width = 1305
+  Height = 675
+  ActiveControl = zgGatherTree
+  BorderIcons = [biSystemMenu, biMaximize]
+  Caption = #20998#21253#27719#24635
+  Color = clBtnFace
+  Font.Charset = DEFAULT_CHARSET
+  Font.Color = clWindowText
+  Font.Height = -11
+  Font.Name = 'MS Sans Serif'
+  Font.Style = []
+  OldCreateOrder = False
+  Position = poMainFormCenter
+  PixelsPerInch = 96
+  TextHeight = 13
+  object jpsResult: TJimPages
+    Left = 0
+    Top = 22
+    Width = 1297
+    Height = 594
+    ActivePage = jpsResultBillsDetail
+    ActivePageIndex = 0
+    Align = alClient
+    Caption = 'jpsResult'
+    object jpsResultBillsDetail: TJimPage
+      Left = 0
+      Top = 0
+      Width = 1297
+      Height = 594
+      TabName = 'BillsDetail'
+      Caption = 'Tree'
+      object Splitter1: TSplitter
+        Left = 924
+        Top = 0
+        Height = 594
+        Align = alRight
+      end
+      object pnlGatherTree: TPanel
+        Left = 0
+        Top = 0
+        Width = 924
+        Height = 594
+        Align = alClient
+        BevelOuter = bvNone
+        TabOrder = 0
+        object zgGatherTree: TZJGrid
+          Left = 0
+          Top = 0
+          Width = 924
+          Height = 594
+          Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection, goShowTreeLine]
+          OptionsEx = []
+          ColCount = 7
+          ShowGridLine = False
+          DefaultColWidth = 73
+          DefaultFixedColWidth = 25
+          Selection.AlphaBlend = False
+          Selection.TransparentColor = False
+          FrozenCol = 0
+          FrozenRow = 0
+          OnCellGetColor = zgGatherTreeCellGetColor
+          OnMouseDown = zgGatherTreeMouseDown
+          Align = alClient
+        end
+      end
+      object pnlDetail: TPanel
+        Left = 927
+        Top = 0
+        Width = 370
+        Height = 594
+        Align = alRight
+        BevelOuter = bvNone
+        TabOrder = 1
+        object zgBillsDetail: TZJGrid
+          Left = 0
+          Top = 0
+          Width = 370
+          Height = 594
+          Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection]
+          OptionsEx = []
+          ShowGridLine = False
+          DefaultColWidth = 73
+          DefaultFixedColWidth = 25
+          Selection.AlphaBlend = False
+          Selection.TransparentColor = False
+          FrozenCol = 0
+          FrozenRow = 0
+          Align = alClient
+        end
+      end
+    end
+    object jpsResultErrorDetail: TJimPage
+      Left = 0
+      Top = 0
+      Width = 1297
+      Height = 594
+      TabName = 'ErrorDetail'
+      Caption = 'Main'
+      object pnlError: TPanel
+        Left = 0
+        Top = 0
+        Width = 1297
+        Height = 594
+        Align = alClient
+        BevelOuter = bvNone
+        TabOrder = 0
+        object Splitter2: TSplitter
+          Left = 440
+          Top = 0
+          Height = 594
+        end
+        object pnlErrorInfo: TPanel
+          Left = 0
+          Top = 0
+          Width = 440
+          Height = 594
+          Align = alLeft
+          BevelOuter = bvNone
+          TabOrder = 0
+          object zgErrorInfo: TZJGrid
+            Left = 0
+            Top = 0
+            Width = 440
+            Height = 594
+            Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection]
+            OptionsEx = []
+            ColCount = 3
+            ShowGridLine = False
+            DefaultColWidth = 73
+            DefaultFixedColWidth = 25
+            Selection.AlphaBlend = False
+            Selection.TransparentColor = False
+            FrozenCol = 0
+            FrozenRow = 0
+            OnMouseDown = zgErrorInfoMouseDown
+            Align = alClient
+          end
+        end
+        object pnlErrorDetail: TPanel
+          Left = 443
+          Top = 0
+          Width = 854
+          Height = 594
+          Align = alClient
+          BevelOuter = bvNone
+          TabOrder = 1
+          object zgErrorDetail: TZJGrid
+            Left = 0
+            Top = 0
+            Width = 854
+            Height = 594
+            Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection]
+            OptionsEx = []
+            ColCount = 6
+            RowCount = 6
+            FixedRowCount = 2
+            ShowGridLine = False
+            DefaultColWidth = 73
+            DefaultFixedColWidth = 25
+            Selection.AlphaBlend = False
+            Selection.TransparentColor = False
+            FrozenCol = 0
+            FrozenRow = 0
+            Align = alClient
+          end
+        end
+      end
+    end
+  end
+  object jtsGatherData: TJimTabSet
+    Left = 0
+    Top = 0
+    Width = 1297
+    Height = 22
+    Align = alTop
+    BackgroundColor = clGradientInactiveCaption
+    Font.Charset = DEFAULT_CHARSET
+    Font.Color = clWindowText
+    Font.Height = -12
+    Font.Name = 'smartSimSun'
+    Font.Style = []
+    SelectedColor = clWhite
+    XPSelectedColor = clWhite
+    XPUnSelectedColor = 15200496
+    Tabs.Strings = (
+      #27719#24635#32467#26524
+      #38169#35823#21015#34920)
+    TabIndex = 0
+    TabPosition = jtpTop
+    TabStyle = tdsNew
+    UnselectedColor = 15200496
+    OnChange = jtsGatherDataChange
+  end
+  object pnlResult: TPanel
+    Left = 0
+    Top = 616
+    Width = 1297
+    Height = 28
+    Align = alBottom
+    BevelOuter = bvNone
+    TabOrder = 2
+    Visible = False
+    object lblResult: TLabel
+      Left = 4
+      Top = 8
+      Width = 692
+      Height = 13
+      Caption = #20849#27719#24635'3'#20010#26631#27573#25968#25454#65292#20849#27719#24635#24037#31243#37327#28165#21333'X'#26465#65292#20854#20013'Y'#26465#27491#30830#27719#24635#65292#35813#37096#20998#21487#27491#30830#23548#20837#24635#21253#65292#26410#27491#30830#27719#24635#28165#21333#21487#35265#28165#21333#26126#32454#20013#28784#33394#37096#20998
+    end
+  end
+  object saGatherTree: TsdGridTreeDBA
+    Columns = <
+      item
+        Title.Caption = #39033#30446#33410#32534#21495
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Code'
+        Width = 180
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #28165#21333#32534#21495
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'B_Code'
+        Width = 80
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21517#31216
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Name'
+        Width = 240
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21333#20301
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Units'
+        Width = 50
+        ReadOnly = False
+      end
+      item
+        Title.Caption = 'ID'
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'ID'
+        Visible = False
+        ReadOnly = False
+      end
+      item
+        Title.Caption = 'ParentID'
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'ParentID'
+        Visible = False
+        ReadOnly = False
+      end
+      item
+        Title.Caption = 'NextSiblingID'
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'NextSiblingID'
+        Visible = False
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21512#21516#35745#37327
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'DealQuantity'
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #25968#37327#21464#26356#35745#37327
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'QcQuantity'
+        ReadOnly = False
+      end>
+    Grid = zgGatherTree
+    ExtendRowCount = 0
+    Options = []
+    AutoExpand = True
+    KeyFieldName = 'ID'
+    ParentFieldName = 'ParentID'
+    NextSiblingFieldName = 'NextSiblingID'
+    TreeOptions = []
+    TopLevelBold = True
+    Left = 104
+    Top = 110
+  end
+  object sdBillsDetail: TsdGridDBA
+    Columns = <
+      item
+        Title.Caption = #26631#27573
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'TenderName'
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #20301#32622
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'SerialNo'
+        Width = 50
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21512#21516#35745#37327
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'DealQuantity'
+        Width = 85
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #25968#37327#21464#26356#35745#37327
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'QcQuantity'
+        Width = 85
+        ReadOnly = False
+      end>
+    Grid = zgBillsDetail
+    ExtendRowCount = 0
+    Options = []
+    Left = 157
+    Top = 110
+  end
+  object sdErrorInfo: TsdGridDBA
+    Columns = <
+      item
+        Title.Caption = #21517#31216
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Name'
+        Width = 300
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #26410#27491#30830#27719#24635
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'ErrorCount'
+        Width = 80
+        ReadOnly = False
+      end>
+    Grid = zgErrorInfo
+    ExtendRowCount = 0
+    Options = []
+    Left = 104
+    Top = 196
+  end
+  object sdErrorDetail: TsdGridDBA
+    Columns = <
+      item
+        Title.Caption = #20986#38169#28304'|'#32534#21495
+        Title.CaptionAcrossCols = '2'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'RelaCode'
+        ReadOnly = False
+      end
+      item
+        Title.Caption = '|'#20301#32622
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'RelaSerialNo'
+        Width = 50
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21487#35745#37327#28165#21333'|'#32534#21495
+        Title.CaptionAcrossCols = '2'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'DetailCode'
+        ReadOnly = False
+      end
+      item
+        Title.Caption = '|'#20301#32622
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'DetailSerialNo'
+        Width = 50
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #38169#35823#31867#22411
+        Title.CaptionAcrossCols = '1'
+        Title.CaptionAcrossRows = 2
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'ErrorType'
+        Width = 200
+        ReadOnly = False
+      end>
+    Grid = zgErrorDetail
+    ExtendRowCount = 0
+    Options = []
+    Left = 160
+    Top = 195
+  end
+  object dxpmError: TdxBarPopupMenu
+    BarManager = MainForm.dxBarManager
+    ItemLinks = <
+      item
+        Item = MainForm.dxbtnExportTenderError
+        Visible = True
+      end
+      item
+        Item = MainForm.dxbtnExportAllError
+        Visible = True
+      end>
+    UseOwnFont = False
+    OnPopup = dxpmErrorPopup
+    Left = 104
+    Top = 235
+  end
+  object dxpmGatherTree: TdxBarPopupMenu
+    BarManager = MainForm.dxBarManager
+    ItemLinks = <
+      item
+        Item = MainForm.dxbtnExportStgResult
+        Visible = True
+      end
+      item
+        Item = MainForm.dxbtnExportStgResultExcel
+        Visible = True
+      end>
+    UseOwnFont = False
+    OnPopup = dxpmGatherTreePopup
+    Left = 104
+    Top = 148
+  end
+  object alStgResult: TActionList
+    Images = MainForm.Images
+    Left = 256
+    Top = 110
+    object actnExportAllError: TAction
+      Caption = #23548#20986#20840#37096#38169#35823#20449#24687
+      ImageIndex = 13
+      OnExecute = actnExportAllErrorExecute
+    end
+    object actnExportTenderError: TAction
+      Caption = #23548#20986#21333#26631#27573#38169#35823#20449#24687
+      ImageIndex = 13
+      OnExecute = actnExportTenderErrorExecute
+    end
+    object actnExportStgResultExcel: TAction
+      Caption = #23548#20986#20998#21253#27719#24635'Excel'#26684#24335
+      ImageIndex = 13
+      OnExecute = actnExportStgResultExcelExecute
+    end
+    object actnExportStgResult: TAction
+      Caption = #23548#20986#20998#21253#27719#24635#36719#20214#26684#24335
+      ImageIndex = 28
+      OnExecute = actnExportStgResultExecute
+    end
+  end
+end

+ 190 - 0
SubTenderGather/stgResultFrm.pas

@@ -0,0 +1,190 @@
+unit stgResultFrm;
+
+interface
+
+uses
+  stgGatherDm, sdIDTree, UtilMethods, stgExcelExport, stgSubGatherFile,
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, JimTabs, JimPages, sdGridDBA, sdGridTreeDBA, ZJGrid, ExtCtrls,
+  StdCtrls, dxBar, ActnList;
+
+type
+  TstgResultForm = class(TForm)
+    jpsResult: TJimPages;
+    jpsResultErrorDetail: TJimPage;
+    jpsResultBillsDetail: TJimPage;
+    jtsGatherData: TJimTabSet;
+    pnlGatherTree: TPanel;
+    zgGatherTree: TZJGrid;
+    saGatherTree: TsdGridTreeDBA;
+    pnlDetail: TPanel;
+    zgBillsDetail: TZJGrid;
+    Splitter1: TSplitter;
+    sdBillsDetail: TsdGridDBA;
+    pnlError: TPanel;
+    pnlErrorInfo: TPanel;
+    zgErrorInfo: TZJGrid;
+    sdErrorInfo: TsdGridDBA;
+    pnlResult: TPanel;
+    lblResult: TLabel;
+    Splitter2: TSplitter;
+    pnlErrorDetail: TPanel;
+    zgErrorDetail: TZJGrid;
+    sdErrorDetail: TsdGridDBA;
+    dxpmError: TdxBarPopupMenu;
+    dxpmGatherTree: TdxBarPopupMenu;
+    alStgResult: TActionList;
+    actnExportAllError: TAction;
+    actnExportTenderError: TAction;
+    actnExportStgResultExcel: TAction;
+    actnExportStgResult: TAction;
+    procedure jtsGatherDataChange(Sender: TObject; NewTab: Integer;
+      var AllowChange: Boolean);
+    procedure zgGatherTreeCellGetColor(Sender: TObject; ACoord: TPoint;
+      var AColor: TColor);
+    procedure zgErrorInfoMouseDown(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: Integer);
+    procedure zgGatherTreeMouseDown(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: Integer);
+    procedure dxpmErrorPopup(Sender: TObject);
+    procedure actnExportAllErrorExecute(Sender: TObject);
+    procedure actnExportTenderErrorExecute(Sender: TObject);
+    procedure dxpmGatherTreePopup(Sender: TObject);
+    procedure actnExportStgResultExcelExecute(Sender: TObject);
+    procedure actnExportStgResultExecute(Sender: TObject);
+  private
+    FGatherData: TstgGatherData;
+    FExcelExportor: TstgErrorExcelExport;
+    function GetExcelExportor: TstgErrorExcelExport;
+  public
+    destructor Destroy; override;
+
+    procedure SetGatherData(AGatherData: TstgGatherData);
+
+    property ExcelExportor: TstgErrorExcelExport read GetExcelExportor; 
+  end;
+
+implementation
+
+uses
+  MainFrm;
+
+{$R *.dfm}
+
+procedure TstgResultForm.jtsGatherDataChange(Sender: TObject;
+  NewTab: Integer; var AllowChange: Boolean);
+begin
+  jpsResult.ActivePageIndex := NewTab;
+end;
+
+procedure TstgResultForm.SetGatherData(AGatherData: TstgGatherData);
+begin
+  FGatherData := AGatherData;
+  saGatherTree.DataView := AGatherData.sdvGatherTree;
+  sdBillsDetail.DataView := AGatherData.sdvBillsDetail;
+  sdErrorInfo.DataView := AGatherData.sdvSubTenders;
+  sdErrorDetail.DataView := AGatherData.sdvErrorDetail;
+end;
+
+procedure TstgResultForm.zgGatherTreeCellGetColor(Sender: TObject;
+  ACoord: TPoint; var AColor: TColor);
+var
+  vNode: TsdIDTreeNode;
+begin
+  vNode := saGatherTree.IDTree.Items[ACoord.Y - zgGatherTree.FixedRowCount];
+  if Assigned(vNode) and vNode.Rec.ValueByName('IsSubTender').AsBoolean then
+    AColor := $00D5D5D5;
+end;
+
+procedure TstgResultForm.zgErrorInfoMouseDown(Sender: TObject;
+  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+begin
+  if Button = mbRight then
+    dxpmError.PopupFromCursorPos;
+end;
+
+procedure TstgResultForm.zgGatherTreeMouseDown(Sender: TObject;
+  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+begin
+  if Button = mbRight then
+    dxpmGatherTree.PopupFromCursorPos;
+end;
+
+procedure TstgResultForm.dxpmErrorPopup(Sender: TObject);
+begin
+  SetDxBtnAction(actnExportAllError, MainForm.dxbtnExportAllError);
+  SetDxBtnAction(actnExportTenderError, MainForm.dxbtnExportTenderError);
+end;
+
+procedure TstgResultForm.actnExportAllErrorExecute(Sender: TObject);
+var
+  sFileName: string;
+begin
+  if SaveExcelFile(sFileName) then
+    ExcelExportor.ExportAll(sFileName);
+end;
+
+procedure TstgResultForm.actnExportTenderErrorExecute(Sender: TObject);
+var
+  sFileName: string;
+begin
+  if SaveExcelFile(sFileName) then
+    ExcelExportor.ExportSubTender(sdErrorInfo.DataView.Current, sFileName);
+end;
+
+function TstgResultForm.GetExcelExportor: TstgErrorExcelExport;
+begin
+  if Assigned(FGatherData) then
+  begin
+    if not Assigned(FExcelExportor) then
+      FExcelExportor := TstgErrorExcelExport.Create(FGatherData);
+    Result := FExcelExportor;
+  end
+  else
+    ErrorMessage('当前无汇总数据,无法导出');
+end;
+
+destructor TstgResultForm.Destroy;
+begin
+  if Assigned(FExcelExportor) then
+    FExcelExportor.Free;
+  inherited;
+end;
+
+procedure TstgResultForm.dxpmGatherTreePopup(Sender: TObject);
+begin
+  SetDxBtnAction(actnExportStgResult, MainForm.dxbtnExportStgResult);
+  SetDxBtnAction(actnExportStgResultExcel, MainForm.dxbtnExportStgResultExcel);
+end;
+
+procedure TstgResultForm.actnExportStgResultExcelExecute(Sender: TObject);
+var
+  vExportor: TstgGatherExcelExport;
+  sFileName: string;
+begin
+  vExportor := TstgGatherExcelExport.Create(FGatherData);
+  try
+    if SaveExcelFile(sFileName) then
+      vExportor.ExportGather(sFileName);
+  finally
+    vExportor.Free;
+  end;
+end;
+
+procedure TstgResultForm.actnExportStgResultExecute(Sender: TObject);
+var
+  sFileName: string;
+  vExportor: TstgSubGatherFileExportor;
+begin
+  if SaveFile(sFileName, '.sgf') then
+  begin
+    vExportor := TstgSubGatherFileExportor.Create;
+    try
+      vExportor.ExportGatherDataTo(FGatherData, sFileName);
+    finally
+      vExportor.Free;
+    end;
+  end;
+end;
+
+end.

+ 258 - 0
SubTenderGather/stgSelectFileFrm.dfm

@@ -0,0 +1,258 @@
+object stgSelectFileForm: TstgSelectFileForm
+  Left = 443
+  Top = 206
+  Width = 910
+  Height = 533
+  Caption = #20998#21253#26631#27573#27719#24635
+  Color = clBtnFace
+  Font.Charset = ANSI_CHARSET
+  Font.Color = clWindowText
+  Font.Height = -12
+  Font.Name = #23435#20307
+  Font.Style = []
+  OldCreateOrder = False
+  Position = poDesktopCenter
+  PixelsPerInch = 96
+  TextHeight = 12
+  object pnlTop: TPanel
+    Left = 0
+    Top = 0
+    Width = 902
+    Height = 33
+    Align = alTop
+    BevelOuter = bvNone
+    TabOrder = 0
+    DesignSize = (
+      902
+      33)
+    object leSumBaseFile: TLabeledEdit
+      Left = 117
+      Top = 7
+      Width = 727
+      Height = 18
+      Anchors = [akLeft, akTop, akRight]
+      Ctl3D = False
+      EditLabel.Width = 108
+      EditLabel.Height = 12
+      EditLabel.Caption = #36873#25321#24635#21253#22522#20934#25991#20214#65306
+      LabelPosition = lpLeft
+      ParentCtl3D = False
+      TabOrder = 0
+    end
+    object btnSelectSbf: TButton
+      Left = 851
+      Top = 5
+      Width = 44
+      Height = 21
+      Anchors = [akTop, akRight]
+      Caption = '...'
+      TabOrder = 1
+      OnClick = btnSelectSbfClick
+    end
+  end
+  object pnlGatherFiles: TPanel
+    Left = 0
+    Top = 33
+    Width = 902
+    Height = 428
+    Align = alClient
+    BevelOuter = bvNone
+    TabOrder = 1
+    object pnlSelect: TPanel
+      Left = 0
+      Top = 0
+      Width = 450
+      Height = 428
+      Align = alLeft
+      BevelOuter = bvNone
+      TabOrder = 0
+      object zgTenderSelect: TZJGrid
+        Left = 0
+        Top = 19
+        Width = 450
+        Height = 409
+        Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection, goShowTreeLine]
+        OptionsEx = []
+        ColCount = 3
+        RowCount = 1
+        ShowGridLine = False
+        DefaultColWidth = 35
+        DefaultFixedColWidth = 25
+        DefaultFixedRowHeight = 22
+        Selection.AlphaBlend = False
+        Selection.TransparentColor = False
+        FrozenCol = 0
+        FrozenRow = 0
+        OnGetCellText = zgTenderSelectGetCellText
+        OnSetCellText = zgTenderSelectSetCellText
+        OnCellTextChanged = zgTenderSelectCellTextChanged
+        OnDrawCellText = zgTenderSelectDrawCellText
+        OnShowHint = zgTenderSelectShowHint
+        Align = alClient
+      end
+      object pnlSelectTitle: TPanel
+        Left = 0
+        Top = 0
+        Width = 450
+        Height = 19
+        Align = alTop
+        BevelOuter = bvNone
+        TabOrder = 1
+        object lblTenderList: TLabel
+          Left = 6
+          Top = 2
+          Width = 72
+          Height = 12
+          Caption = #21487#36873#39033#30446#21015#34920
+          Font.Charset = ANSI_CHARSET
+          Font.Color = clBlue
+          Font.Height = -12
+          Font.Name = #23435#20307
+          Font.Style = []
+          ParentFont = False
+        end
+      end
+    end
+    object pnlDivision: TPanel
+      Left = 450
+      Top = 0
+      Width = 3
+      Height = 428
+      Align = alLeft
+      BevelOuter = bvNone
+      TabOrder = 1
+    end
+    object pnlResult: TPanel
+      Left = 453
+      Top = 0
+      Width = 449
+      Height = 428
+      Align = alClient
+      BevelOuter = bvNone
+      TabOrder = 2
+      object zgResult: TZJGrid
+        Left = 0
+        Top = 19
+        Width = 449
+        Height = 409
+        OptionsEx = []
+        ColCount = 2
+        RowCount = 2
+        ShowGridLine = False
+        DefaultColWidth = 365
+        DefaultFixedColWidth = 25
+        DefaultFixedRowHeight = 22
+        Selection.AlphaBlend = False
+        Selection.TransparentColor = False
+        FrozenCol = 0
+        FrozenRow = 0
+        Align = alClient
+      end
+      object pnlResultTitle: TPanel
+        Left = 0
+        Top = 0
+        Width = 449
+        Height = 19
+        Align = alTop
+        BevelOuter = bvNone
+        TabOrder = 1
+        object lblResultList: TLabel
+          Left = 3
+          Top = 2
+          Width = 72
+          Height = 12
+          Caption = #25152#36873#39033#30446#21015#34920
+          Font.Charset = ANSI_CHARSET
+          Font.Color = clBlue
+          Font.Height = -12
+          Font.Name = #23435#20307
+          Font.Style = []
+          ParentFont = False
+        end
+      end
+    end
+  end
+  object pnlBottom: TPanel
+    Left = 0
+    Top = 461
+    Width = 902
+    Height = 41
+    Align = alBottom
+    BevelOuter = bvNone
+    TabOrder = 2
+    DesignSize = (
+      902
+      41)
+    object btnOk: TButton
+      Left = 731
+      Top = 8
+      Width = 75
+      Height = 25
+      Anchors = [akTop, akRight]
+      Caption = #30830#23450
+      TabOrder = 0
+      OnClick = btnOkClick
+    end
+    object btnCancel: TButton
+      Left = 817
+      Top = 8
+      Width = 75
+      Height = 25
+      Anchors = [akTop, akRight]
+      Caption = #21462#28040
+      ModalResult = 2
+      TabOrder = 1
+    end
+  end
+  object stdTenderSelect: TsdGridTreeDBA
+    Columns = <
+      item
+        Title.Caption = #36873#25321
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taCenter
+        EditType = sgeCheckBox
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        Width = 30
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21517#31216
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Name'
+        Width = 365
+        ReadOnly = True
+      end>
+    Grid = zgTenderSelect
+    ExtendRowCount = 0
+    Options = [aoAllowEdit]
+    AutoExpand = True
+    TreeCellCol = 2
+    KeyFieldName = 'ID'
+    ParentFieldName = 'ParentID'
+    NextSiblingFieldName = 'NextSiblingID'
+    TreeOptions = []
+    TopLevelBold = True
+    Left = 124
+    Top = 177
+  end
+end

+ 320 - 0
SubTenderGather/stgSelectFileFrm.pas

@@ -0,0 +1,320 @@
+unit stgSelectFileFrm;
+
+interface
+
+uses
+  stgGatherControl,
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, StdCtrls, ExtCtrls, sdGridDBA, sdGridTreeDBA, ZJGrid, sdIDTree;
+
+type
+  TstgSelectFileForm = class(TForm)
+    pnlTop: TPanel;
+    leSumBaseFile: TLabeledEdit;
+    btnSelectSbf: TButton;
+    pnlGatherFiles: TPanel;
+    pnlSelect: TPanel;
+    zgTenderSelect: TZJGrid;
+    pnlSelectTitle: TPanel;
+    lblTenderList: TLabel;
+    stdTenderSelect: TsdGridTreeDBA;
+    pnlDivision: TPanel;
+    pnlResult: TPanel;
+    zgResult: TZJGrid;
+    pnlResultTitle: TPanel;
+    lblResultList: TLabel;
+    pnlBottom: TPanel;
+    btnOk: TButton;
+    btnCancel: TButton;
+    procedure zgTenderSelectDrawCellText(ACanvas: TCanvas;
+      const ARect: TRect; const ACoord: TPoint; AGrid: TZJGrid;
+      const Text: String; var ADefaultDraw: Boolean);
+    procedure zgTenderSelectShowHint(var HintStr: String;
+      var CanShow: Boolean; var HintInfo: THintInfo; const ACoord: TPoint);
+    procedure zgTenderSelectSetCellText(Sender: TObject;
+      const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+    procedure zgTenderSelectGetCellText(Sender: TObject;
+      const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+    procedure zgTenderSelectCellTextChanged(Sender: TObject; Col,
+      Row: Integer);
+    procedure btnOkClick(Sender: TObject);
+    procedure btnSelectSbfClick(Sender: TObject);
+  private
+    FSelects: TList;
+
+    procedure AddRows(ANode: TsdIDTreeNode);
+    procedure RemoveRows(ANode: TsdIDTreeNode);
+
+    procedure InitResultGrid;
+    procedure AssignResultGrid;
+    procedure AssignResult;
+    function GetSelectCount: Integer;
+  public
+    constructor Create(AGatherControl: TstgGatherControl);
+    destructor Destroy; override;
+
+    procedure AssignSelect(AGatherControl: TstgGatherControl);
+    property SelectCount: Integer read GetSelectCount;
+  end;
+
+function SelectFileForSubTenderGather(AGatherControl: TstgGatherControl): Boolean;
+
+implementation
+
+uses MainFrm, Globals, UtilMethods;
+
+{$R *.dfm}
+
+function SelectFileForSubTenderGather(AGatherControl: TstgGatherControl): Boolean;
+var
+  vSelectFrm: TstgSelectFileForm;
+begin
+  vSelectFrm := TstgSelectFileForm.Create(AGatherControl);
+  try
+    Result := vSelectFrm.ShowModal = mrOk;
+    if Result then
+      vSelectFrm.AssignSelect(AGatherControl);
+  finally
+    vSelectFrm.Free;
+  end;
+end;
+
+procedure TstgSelectFileForm.zgTenderSelectDrawCellText(ACanvas: TCanvas;
+  const ARect: TRect; const ACoord: TPoint; AGrid: TZJGrid;
+  const Text: String; var ADefaultDraw: Boolean);
+
+  procedure GetBitmap(AImage: TBitmap);
+  begin
+    with stdTenderSelect.IDTree.Items[ACoord.Y - 1] do
+      if Rec.ValueByName('Type').AsInteger = 0 then
+        if Expanded and HasChildren then
+          MainForm.Images.GetBitmap(34, AImage)
+        else
+          MainForm.Images.GetBitmap(34, AImage)
+      else
+        MainForm.Images.GetBitmap(11, AImage);
+  end;
+
+const
+  rIconWidth = 16;
+  rIconHeight = 16;
+var
+  Img: TBitmap;
+  Cell: TZjCell;
+  rImg: TRect;
+begin
+ if (ACoord.X = 2) and (ACoord.Y > zgTenderSelect.FixedRowCount - 1) then
+  begin
+    Cell := zgTenderSelect.Cells[ACoord.X, ACoord.Y];
+    Img := TBitmap.Create;
+    try
+      GetBitmap(Img);
+      case Cell.Align of
+        gaTopLeft, gaTopCenter, gaTopRight:
+          rImg := Rect(ARect.Left + 2, ARect.Top, ARect.Left + rIconWidth, ARect.Top + rIconHeight);
+        gaCenterLeft, gaCenterCenter, gaCenterRight:
+          rImg := Rect(ARect.Left + 2, ARect.Top + (ARect.Bottom - ARect.Top - rIconHeight) div 2, ARect.Left + rIconWidth, ARect.Bottom - (ARect.Bottom - ARect.Top - rIconHeight) div 2);
+        gaBottomLeft, gaBottomCenter, gaBottomRight:
+          rImg := Rect(ARect.Left + 2, ARect.Bottom - rIconHeight, ARect.Left + rIconWidth, ARect.Bottom);
+      end;
+      ACanvas.StretchDraw(rImg, Img);
+      WriteText(ACanvas, Rect(ARect.Left + rIconWidth, ARect.Top, ARect.Right, ARect.Bottom)
+        , 2, 2, Text, Cell.Align, False);
+      ADefaultDraw := False;
+    finally
+      Img.Free;
+    end;
+  end;
+end;
+
+procedure TstgSelectFileForm.zgTenderSelectShowHint(var HintStr: String;
+  var CanShow: Boolean; var HintInfo: THintInfo; const ACoord: TPoint);
+var
+  vCell: TZjCell;
+  vNode: TsdIDTreeNode;
+  iLevelWidth: Integer;
+  rText: TRect;
+
+  procedure CalcTextRect(var R: TRect);
+  var
+    DC: HDC;
+    iTextHeight: Integer;
+  begin
+    DC := CreateCompatibleDC(0);
+    try
+      SelectObject(DC, vCell.Font.Handle);
+      iTextHeight := DrawText(DC, PChar(vCell.Text), Length(vCell.Text), R, DT_SINGLELINE or DT_VCenter
+        or DT_NOCLIP or DT_CALCRECT);
+    finally
+      DeleteDC(DC);
+    end;
+  end;
+
+begin
+  if ACoord.Y < 1 then Exit;
+
+  vCell := zgTenderSelect.Cells[ACoord.X, ACoord.Y];
+  with HintInfo do
+  begin
+    vNode := stdTenderSelect.IDTree.Items[ACoord.Y - 1];
+    if not Assigned(vNode) then Exit;
+    iLevelWidth := (vNode.Level + 1) * 20 + 16;
+
+    rText := CursorRect;
+    CalcTextRect(rText);
+    if (rText.Right - rText.Left + iLevelWidth > CursorRect.Right - CursorRect.Left) or
+      (rText.Right > ClientWidth) then
+    begin
+      CanShow := True;
+      HintStr := vCell.Text;
+      GetCursorPos(HintPos);
+    end;
+  end;
+end;
+
+procedure TstgSelectFileForm.zgTenderSelectSetCellText(Sender: TObject;
+  const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+var
+  stnNode: TsdIDTreeNode;
+begin
+  if ACoord.X = 1 then
+  begin
+    stnNode := stdTenderSelect.IDTree.Items[ACoord.Y - 1];
+    if Value = 'True' then
+      AddRows(stnNode)
+    else
+      RemoveRows(stnNode);
+    AssignResult;
+  end;
+end;
+
+procedure TstgSelectFileForm.zgTenderSelectGetCellText(Sender: TObject;
+  const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+var
+  stnNode: TsdIDTreeNode;
+begin
+  if ACoord.X = 1 then
+  begin
+    stnNode := stdTenderSelect.IDTree.Items[ACoord.Y - 1];
+    if Assigned(stnNode) and (FSelects.IndexOf(Pointer(stnNode.ID)) > -1) then
+      Value := 'True';
+  end;
+end;
+
+procedure TstgSelectFileForm.zgTenderSelectCellTextChanged(Sender: TObject;
+  Col, Row: Integer);
+begin
+  if (Col = 1) then
+    zgTenderSelect.InvalidateCol(1);
+end;
+
+procedure TstgSelectFileForm.AddRows(ANode: TsdIDTreeNode);
+var
+  iChild: Integer;
+begin
+  if not Assigned(ANode) then Exit;
+
+  if FSelects.IndexOf(Pointer(ANode.ID)) = -1 then
+    FSelects.Add(Pointer(ANode.ID));
+
+  if ANode.HasChildren then
+    for iChild := 0 to ANode.ChildCount - 1 do
+      AddRows(ANode.ChildNodes[iChild]);
+end;
+
+procedure TstgSelectFileForm.RemoveRows(ANode: TsdIDTreeNode);
+var
+  iChild: Integer;
+begin
+  if not Assigned(ANode) then Exit;
+
+  if FSelects.IndexOf(Pointer(ANode.ID)) > -1 then
+    FSelects.Remove(Pointer(ANode.ID));
+
+  if ANode.HasChildren then
+    for iChild := 0 to ANode.ChildCount - 1 do
+      RemoveRows(ANode.ChildNodes[iChild]);
+end;
+
+procedure TstgSelectFileForm.InitResultGrid;
+begin
+  zgResult.ColCount := 2;
+  zgResult.RowCount := 1;
+  zgResult.Cells[1, 0].Text := '所选项目';
+  zgResult.ColWidths[1] := 365;
+end;
+
+procedure TstgSelectFileForm.AssignResultGrid;
+var
+  i, iID: Integer;
+  vNode: TsdIDTreeNode;
+begin
+  for i := 0 to FSelects.Count - 1 do
+  begin
+    iID := Integer(FSelects.Items[i]);
+    vNode := stdTenderSelect.IDTree.FindNode(iID);
+    if vNode.Rec.ValueByName('Type').AsInteger = 1 then
+    begin
+      zgResult.RowCount := zgResult.RowCount + 1;
+      zgResult.Cells[1, zgResult.RowCount - 1].Text := vNode.Rec.ValueByName('Name').AsString;
+      zgResult.Cells[1, zgResult.RowCount - 1].Align := gaCenterLeft;
+      zgResult.Rows[zgResult.RowCount - 1].Data := vNode;
+    end;
+  end;
+end;
+
+procedure TstgSelectFileForm.AssignSelect(AGatherControl: TstgGatherControl);
+begin
+  AGatherControl.SumBaseFile := leSumBaseFile.Text;
+  AGatherControl.Projects.Assign(FSelects);
+end;
+
+constructor TstgSelectFileForm.Create(AGatherControl: TstgGatherControl);
+begin
+  inherited Create(nil);
+  stdTenderSelect.DataView := ProjectManager.sdvProjectsSpare;
+  FSelects := TList.Create;
+  FSelects.Assign(AGatherControl.Projects);
+  InitResultGrid;
+  leSumBaseFile.Text := AGatherControl.SumBaseFile;
+end;
+
+destructor TstgSelectFileForm.Destroy;
+begin
+  FSelects.Free;
+  inherited;
+end;
+
+procedure TstgSelectFileForm.AssignResult;
+begin
+  InitResultGrid;
+  AssignResultGrid;
+end;
+
+procedure TstgSelectFileForm.btnOkClick(Sender: TObject);
+begin
+  if (leSumBaseFile.Text = '') then
+    WarningMessage('请选择总包基准文件。', Handle)
+  else if not FileExists(leSumBaseFile.Text) then
+    WarningMessage('当前选择的总包基准文件不存在,请重新选择。', Handle)
+  else if SelectCount = 0 then
+    WarningMessage('请选择需要汇总的分包标段。', Handle)
+  else
+    ModalResult := mrOk;
+end;
+
+function TstgSelectFileForm.GetSelectCount: Integer;
+begin
+  Result := zgResult.RowCount - zgResult.FixedRowCount;
+end;
+
+procedure TstgSelectFileForm.btnSelectSbfClick(Sender: TObject);
+var
+  sFileName: string;
+begin
+  sFileName := leSumBaseFile.Text;
+  if SelectFile(sFileName, '.sbf') then
+    leSumBaseFile.Text := sFileName;
+end;
+
+end.

+ 214 - 0
SubTenderGather/stgSubGatherFile.pas

@@ -0,0 +1,214 @@
+unit stgSubGatherFile;
+// µ¼Èëµ¼³ö»ã×ܽá¹û
+
+interface
+
+uses
+  stgSubGatherFileDm, ADODB, sdDB, stgGatherDm, SysUtils, StageDm, mDataRecord;
+
+type
+  TstgSubGatherFileHelper = class
+  private
+    FTempFile: string;
+    FConnection: TADOConnection;
+    FGatherData: TstgSubGatherData;
+  public
+    constructor Create;
+    destructor Destroy; override;
+
+    procedure Open(const AFileName: string);
+    procedure Close;
+    procedure SaveTo(const AFileName: string);
+
+    property Connection: TADOConnection read FConnection;
+    property GatherData: TstgSubGatherData read FGatherData;
+  end;
+
+  TstgSubGatherFileExportor = class(TstgSubGatherFileHelper)
+  private
+    procedure LoadMemoryRecord(ARec: TsdDataRecord);
+    procedure LoadMemoryGatherData(AGatherData: TstgGatherData);
+  public
+    procedure ExportGatherDataTo(AGatherData:TstgGatherData; const AFileName: string);
+  end;
+
+  TstgSubGatherFileImportor = class(TstgSubGatherFileHelper)
+  private
+    procedure ClearOldData(AStageData: TStageData);
+    procedure ImportGatherData(AStageData: TStageData);
+  public
+    procedure ImportGatherDataTo(AStageData: TStageData; const AFileName: string);
+  end;
+
+implementation
+
+
+uses
+  UtilMethods, ZhAPI, Connections, stgTables, ScAutoUpdateUnit, Math;
+
+{ TstgSubGatherFileExportor }
+
+procedure TstgSubGatherFileExportor.ExportGatherDataTo(
+  AGatherData: TstgGatherData; const AFileName: string);
+begin
+  Open(GetEmptyDataBaseFileName);
+  try
+    LoadMemoryGatherData(AGatherData);
+  finally                             
+    SaveTo(AFileName);
+  end;
+end;
+
+procedure TstgSubGatherFileExportor.LoadMemoryRecord(ARec: TsdDataRecord);
+var
+  vRec: TsdDataRecord;
+begin
+  vRec := GatherData.sddBills.Add;
+  vRec.ValueByName('ID').AsInteger := ARec.ValueByName('ID').AsInteger;
+  vRec.ValueByName('ParentID').AsInteger := ARec.ValueByName('ParentID').AsInteger;
+  vRec.ValueByName('NextSiblingID').AsInteger := ARec.ValueByName('NextSiblingID').AsInteger;
+  vRec.ValueByName('Code').AsString := ARec.ValueByName('Code').AsString;
+  vRec.ValueByName('B_Code').AsString := ARec.ValueByName('B_Code').AsString;
+  vRec.ValueByName('Name').AsString := ARec.ValueByName('Name').AsString;
+  vRec.ValueByName('Units').AsString := ARec.ValueByName('Units').AsString;
+  vRec.ValueByName('IsSumBase').AsBoolean := ARec.ValueByName('IsSumBase').AsBoolean;
+  vRec.ValueByName('IsLeaf').AsBoolean := ARec.ValueByName('IsLeaf').AsBoolean;
+  vRec.ValueByName('DealQuantity').AsFloat := ARec.ValueByName('DealQuantity').AsFloat;
+  vRec.ValueByName('DealTotalPrice').AsFloat := ARec.ValueByName('DealTotalPrice').AsFloat;
+  vRec.ValueByName('QcQuantity').AsFloat := ARec.ValueByName('QcQuantity').AsFloat;
+  vRec.ValueByName('QcTotalPrice').AsFloat := ARec.ValueByName('QcTotalPrice').AsFloat;
+  vRec.ValueByName('QcBGLCode').AsString := ARec.ValueByName('QcBGLCode').AsString;
+  vRec.ValueByName('QcBGLNum').AsString := ARec.ValueByName('QcBGLNum').AsString;
+end;
+
+procedure TstgSubGatherFileExportor.LoadMemoryGatherData(
+  AGatherData: TstgGatherData);
+var
+  i: Integer;
+  vRec: TsdDataRecord;
+begin
+  GatherData.sddBills.BeginUpdate;
+  try
+    for i := 0 to AGatherData.sddGatherTree.RecordCount - 1 do
+    begin
+      vRec := AGatherData.sddGatherTree.Records[i];
+      LoadMemoryRecord(vRec);
+    end;
+  finally
+    GatherData.sddBills.EndUpdate;
+  end;
+end;
+
+{ TstgSubGatherFileHelper }
+
+procedure TstgSubGatherFileHelper.Close;
+begin
+  FConnection.Close;
+  if FileExists(FTempFile) then
+    DeleteFile(FTempFile);
+end;
+
+constructor TstgSubGatherFileHelper.Create;
+begin
+  FConnection := TADOConnection.Create(nil);
+  FConnection.LoginPrompt := False;
+  FGatherData := TstgSubGatherData.Create(nil);
+end;
+
+destructor TstgSubGatherFileHelper.Destroy;
+begin
+  Close;
+  FGatherData.Free;
+  FConnection.Free;
+  inherited;
+end;
+
+procedure TstgSubGatherFileHelper.Open(const AFileName: string);
+
+  procedure UpdateDataTables;
+  var
+    Updater: TScUpdater;
+  begin
+    Updater := TScUpdater.Create;
+    try
+      Updater.ForceUpdate := True;
+      Updater.Open('', FConnection, '', '');
+      Updater.AddTableDef(sStgBills, @tdStgBills, Length(tdStgBills), False, False);
+      Updater.ExcuteUpdate;
+    finally
+      Updater.Free;
+    end;
+  end;
+
+begin
+  FTempFile := GetTempFileName;
+  CopyFileOrFolder(AFileName, FTempFile);
+  FConnection.ConnectionString := Format(SAdoConnectStr, [FTempFile]);
+  FConnection.Open;
+  UpdateDataTables;
+  GatherData.Open(FConnection);
+end;
+
+procedure TstgSubGatherFileHelper.SaveTo(const AFileName: string);
+begin
+  FGatherData.Save;
+  CopyFileOrFolder(FTempFile, AFileName);
+end;
+
+{ TstgSubGatherFileImportor }
+
+procedure TstgSubGatherFileImportor.ClearOldData(AStageData: TStageData);
+var
+  i: Integer;
+  vRec: TStageRecord;
+begin
+  for i := 0 to AStageData.sddStage.RecordCount - 1 do
+  begin
+    vRec := TStageRecord(AStageData.sddStage.Records[i]);
+    vRec.DealQuantity.AsFloat := 0;
+    vRec.DealTotalPrice.AsFloat := 0;
+    vRec.DealFlag.AsInteger := 0;
+    vRec.DealFormula.AsString := '';
+    vRec.QcQuantity.AsFloat := 0;
+    vRec.QcTotalPrice.AsFloat := 0;
+    vRec.QcFlag.AsInteger := 0;
+    vRec.QcFormula.AsString := '';
+    vRec.QcBGLCode.AsString := '';
+    vRec.QcBGLNum.AsString := '';
+  end;
+end;
+
+procedure TstgSubGatherFileImportor.ImportGatherData(
+  AStageData: TStageData);
+var
+  i: Integer;
+  vOrgRec: TsdDataRecord;
+  vStageRec: TStageRecord;
+begin
+  for i := 0 to GatherData.sddBills.RecordCount - 1 do
+  begin
+    vOrgRec := GatherData.sddBills.Records[i];
+    if vOrgRec.ValueByName('IsSumBase').AsBoolean and vOrgRec.ValueByName('IsLeaf').AsBoolean then
+    begin
+      vStageRec := AStageData.StageRecordWithAdd(vOrgRec.ValueByName('ID').AsInteger);
+      vStageRec.DealQuantity.AsFloat := vOrgRec.ValueByName('DealQuantity').AsFloat;
+    end;
+  end;
+end;
+
+procedure TstgSubGatherFileImportor.ImportGatherDataTo(
+  AStageData: TStageData; const AFileName: string);
+begin
+  Open(AFileName);
+  AStageData.sddStage.BeginUpdate;
+  AStageData.BeforeBatchOperation;
+  try
+    ClearOldData(AStageData);
+    ImportGatherData(AStageData);
+  finally
+    AStageData.AfterBatchOperation;
+    AStageData.sddStage.EndUpdate;
+  end;
+end;
+
+end.

+ 68 - 0
SubTenderGather/stgSubGatherFileDm.dfm

@@ -0,0 +1,68 @@
+object stgSubGatherData: TstgSubGatherData
+  OldCreateOrder = False
+  Left = 27
+  Top = 244
+  Height = 202
+  Width = 186
+  object sdpBills: TsdADOProvider
+    TableName = 'Bills'
+    Left = 35
+    Top = 32
+  end
+  object sddBills: TsdDataSet
+    Active = False
+    Provider = sdpBills
+    Left = 35
+    Top = 96
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D650909507265636973696F6E02000453697A6502000001044E616D
+      650608506172656E744944094669656C644E616D650608506172656E74494408
+      44617461547970650203084461746153697A6502040549734B6579080F4E6565
+      6450726F636573734E616D650909507265636973696F6E02000453697A650200
+      0001044E616D65060D4E6578745369626C696E674944094669656C644E616D65
+      060D4E6578745369626C696E6749440844617461547970650203084461746153
+      697A6502040549734B6579080F4E65656450726F636573734E616D6509095072
+      65636973696F6E02000453697A6502000001044E616D650604436F6465094669
+      656C644E616D650604436F64650844617461547970650218084461746153697A
+      6502320549734B6579080F4E65656450726F636573734E616D65090950726563
+      6973696F6E02000453697A6502000001044E616D650606425F436F6465094669
+      656C644E616D650606425F436F64650844617461547970650218084461746153
+      697A6502320549734B6579080F4E65656450726F636573734E616D6509095072
+      65636973696F6E02000453697A6502000001044E616D6506044E616D65094669
+      656C644E616D6506044E616D650844617461547970650218084461746153697A
+      6503C8000549734B6579080F4E65656450726F636573734E616D650909507265
+      636973696F6E02000453697A6502000001044E616D650605556E697473094669
+      656C644E616D650605556E697473084461746154797065021808446174615369
+      7A6502140549734B6579080F4E65656450726F636573734E616D650909507265
+      636973696F6E02000453697A6502000001044E616D650609497353756D426173
+      65094669656C644E616D650609497353756D4261736508446174615479706502
+      05084461746153697A6502010549734B6579080F4E65656450726F636573734E
+      616D650909507265636973696F6E02000453697A6502000001044E616D650606
+      49734C656166094669656C644E616D65060649734C6561660844617461547970
+      650205084461746153697A6502010549734B6579080F4E65656450726F636573
+      734E616D650909507265636973696F6E02000453697A6502000001044E616D65
+      060C4465616C5175616E74697479094669656C644E616D65060C4465616C5175
+      616E746974790844617461547970650206084461746153697A6502080549734B
+      6579080F4E65656450726F636573734E616D650909507265636973696F6E0200
+      0453697A6502000001044E616D65060E4465616C546F74616C50726963650946
+      69656C644E616D65060E4465616C546F74616C50726963650844617461547970
+      650206084461746153697A6502080549734B6579080F4E65656450726F636573
+      734E616D650909507265636973696F6E02000453697A6502000001044E616D65
+      060A51635175616E74697479094669656C644E616D65060A51635175616E7469
+      74790844617461547970650206084461746153697A6502080549734B6579080F
+      4E65656450726F636573734E616D650909507265636973696F6E02000453697A
+      6502000001044E616D65060C5163546F74616C5072696365094669656C644E61
+      6D65060C5163546F74616C507269636508446174615479706502060844617461
+      53697A6502080549734B6579080F4E65656450726F636573734E616D65090950
+      7265636973696F6E02000453697A6502000001044E616D650609516342474C43
+      6F6465094669656C644E616D650609516342474C436F64650844617461547970
+      650218084461746153697A6503FF000549734B6579080F4E65656450726F6365
+      73734E616D650909507265636973696F6E02000453697A6502000001044E616D
+      650608516342474C4E756D094669656C644E616D650608516342474C4E756D08
+      44617461547970650218084461746153697A6503FF000549734B6579080F4E65
+      656450726F636573734E616D650909507265636973696F6E02000453697A6502
+      000000}
+  end
+end

+ 36 - 0
SubTenderGather/stgSubGatherFileDm.pas

@@ -0,0 +1,36 @@
+unit stgSubGatherFileDm;
+// 导入导出汇总结果,连接数据表
+
+interface
+
+uses
+  SysUtils, Classes, sdDB, sdProvider, ADODB, DB;
+
+type
+  TstgSubGatherData = class(TDataModule)
+    sdpBills: TsdADOProvider;
+    sddBills: TsdDataSet;
+  private
+  public
+    procedure Open(AConnection: TADOConnection);
+    procedure Save;
+  end;
+
+implementation
+
+{$R *.dfm}
+
+{ TstgSubGatherData }
+
+procedure TstgSubGatherData.Open(AConnection: TADOConnection);
+begin
+  sdpBills.Connection := AConnection;
+  sddBills.Open;
+end;
+
+procedure TstgSubGatherData.Save;
+begin
+  sddBills.Save;
+end;
+
+end.

+ 30 - 0
SubTenderGather/stgTables.pas

@@ -0,0 +1,30 @@
+unit stgTables;
+
+interface
+
+uses
+  DataBaseTables;
+
+const
+  sStgBills = 'Bills';
+  tdStgBills : array [0..14] of TScFieldDef = (
+    (FieldName: 'ID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
+    (FieldName: 'ParentID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'NextSiblingID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Code'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'B_Code'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Name'; FieldType: ftString; Size: 200; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Units'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'IsSumBase'; FieldType: ftBoolean; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'IsLeaf'; FieldType: ftBoolean; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'DealQuantity'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'DealTotalPrice'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'QcQuantity'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'QcTotalPrice'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'QcBGLCode'; FieldType: ftString; Size: 255; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'QcBGLNum'; FieldType: ftString; Size: 255; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
+  );
+
+implementation
+
+end.

+ 2 - 2
Units/CacheTree.pas

@@ -55,7 +55,7 @@ type
 
     function GetNodeID(ANode: TCacheNode): Integer;
   public
-    constructor Create(ACacheTree: TCacheTree; AID: Integer);
+    constructor Create(ACacheTree: TCacheTree; AID: Integer); virtual;
     destructor Destroy; override;
 
     procedure InsertChild(AChildNode: TCacheNode);
@@ -87,7 +87,7 @@ type
     function GetFirstNode: TCacheNode;
     procedure SetNewNodeID(const Value: Integer);
   protected
-    function GetNewNodeID: Integer;   
+    function GetNewNodeID: Integer;
     function GetNewNode: TCacheNode; virtual;
   public
     constructor Create; virtual;

+ 7 - 1
Units/CalcDecimal.pas

@@ -23,6 +23,7 @@ type
 
     function RoundTo(AValue: Double): Double;
     function StrRoundTo(const AValue: string): string;
+    function CheckSameNum(AValue1, AValue2: Double): Boolean;
 
     procedure ClearLinkViewCols;
     procedure AddLinkViewCol(ACol: TObject);
@@ -78,7 +79,7 @@ type
 implementation
 
 uses
-  ProjectData, UtilMethods, SysUtils;
+  ProjectData, UtilMethods, SysUtils, Math;
 
 { TDecimal }
 
@@ -87,6 +88,11 @@ begin
   FLinkViewCols.Add(ACol);
 end;
 
+function TDecimal.CheckSameNum(AValue1, AValue2: Double): Boolean;
+begin
+  Result := Abs(RoundTo(AValue1 - AValue2)) < CompareValue;
+end;
+
 procedure TDecimal.ClearLinkViewCols;
 begin
   FLinkViewCols.Clear;

+ 112 - 4
Units/ColVisibleManager.pas

@@ -3,7 +3,7 @@ unit ColVisibleManager;
 interface
 
 uses
-  Classes, sdGridDBA, ZhAPI;
+  Classes, sdGridDBA, ZhAPI, sdGridTreeDBA;
 
 type
   TColVisible = class
@@ -28,6 +28,9 @@ type
     FBGLCode: Boolean;
     FAlias: Boolean;
     FDesign: Boolean;
+    FApprovalCode: Boolean;
+    FIsGatherZJJL: Boolean;
+    function GetVisible: Boolean;
   public
     constructor Create(ACol: TsdGridColumn); override;
 
@@ -37,35 +40,54 @@ type
     property BGLCode: Boolean read FBGLCode write FBGLCode;
     property Design: Boolean read FDesign write FDesign;
     property Alias: Boolean read FAlias write FAlias;
+    property ApprovalCode: Boolean read FApprovalCode write FApprovalCode;
+    property IsGatherZJJL: Boolean read FIsGatherZJJL write FIsGatherZJJL;
+
+    property Visible: Boolean read GetVisible;
   end;
 
   TColVisibleManager = class
   private
     FColVisibles: TList;
+    function GetColVisible(AIndex: Integer): TColVisible;
   protected
     function CreateColVisible(ACol: TsdGridColumn): TColVisible; virtual;
   public
     constructor Create(ACols: TsdGridColumnList);
     destructor Destroy; override;
 
-    procedure RefreshVisible;
+    procedure RefreshVisible; virtual;
 
     procedure ShowGridCol(AShow: Boolean; ABeginCol, AEndCol: Integer);
+
+    property ColVisible[AIndex: Integer]: TColVisible read GetColVisible;
   end;
 
   TBM_ColVisibleManager = class(TColVisibleManager)
+  private
+    FGridFixedColCount: Integer;
+    FOrgTreeCol: Integer;
+    FGridTreeDBA: TsdGridTreeDBA;
   protected
     function CreateColVisible(ACol: TsdGridColumn): TColVisible; override;
   public
+    constructor Create(AGridTreeDBA: TsdGridTreeDBA);
+
     procedure ShowPriceChange(AShow: Boolean);
     procedure ShowBGLCode(AShow: Boolean);
     procedure ShowDesign(AShow: Boolean);
     procedure ShowAlias(AShow: Boolean);
+    procedure ShowApprovalCode(AShow: Boolean);
+    procedure ShowIsGather(AShow: Boolean);
+
+    procedure RefreshVisible; override;
+
+    property GridTreeDBA: TsdGridTreeDBA read FGridTreeDBA;
   end;
 
 implementation
 
-uses SysUtils;
+uses SysUtils, ZJGrid;
 
 { TColVisible }
 
@@ -90,11 +112,18 @@ begin
   FBGLCode := True;
   FDesign := True;
   FAlias := True;
+  FApprovalCode := True;
+  FIsGatherZJJL := True;
+end;
+
+function TBM_ColVisible.GetVisible: Boolean;
+begin
+  Result := FCustom and FPriceChange and FBGLCode and FDesign and FAlias and FApprovalCode and FIsGatherZJJL;
 end;
 
 procedure TBM_ColVisible.RefreshVisible;
 begin
-  FDBACol.Visible := FCustom and FPriceChange and FBGLCode and FDesign and FAlias;
+  FDBACol.Visible := FCustom and FPriceChange and FBGLCode and FDesign and FAlias and FApprovalCode and FIsGatherZJJL;
 end;
 
 { TColVisibleManager }
@@ -125,6 +154,11 @@ begin
   inherited;
 end;
 
+function TColVisibleManager.GetColVisible(AIndex: Integer): TColVisible;
+begin
+  Result := TColVisible(FColVisibles[AIndex]);
+end;
+
 procedure TColVisibleManager.RefreshVisible;
 var
   iCol: Integer;
@@ -160,12 +194,58 @@ end;
 
 { TBM_ColVisibleManager }
 
+constructor TBM_ColVisibleManager.Create(AGridTreeDBA: TsdGridTreeDBA);
+begin
+  inherited Create(AGridTreeDBA.Columns);
+  FGridTreeDBA := AGridTreeDBA;
+  FOrgTreeCol := AGridTreeDBA.TreeCellCol;
+  if Assigned(AGridTreeDBA.Grid) then
+    FGridFixedColCount := AGridTreeDBA.Grid.FixedColCount
+  else
+    FGridFixedColCount := 1;
+end;
+
 function TBM_ColVisibleManager.CreateColVisible(
   ACol: TsdGridColumn): TColVisible;
 begin
   Result := TBM_ColVisible.Create(ACol);
 end;
 
+procedure TBM_ColVisibleManager.RefreshVisible;
+var
+  i, iCount: Integer;
+  vGrid: TZJGrid;
+begin
+  (*
+  iCount := 0;
+  for i := 0 to FOrgTreeCol - FGridFixedColCount do
+  begin
+    if TBM_ColVisible(ColVisible[i]).Visible then
+      Inc(iCount);
+  end;
+  FGridTreeDBA.TreeCellCol := FGridFixedColCount + iCount - 1;
+  *)
+  inherited;
+  iCount := 0;
+  for i := 0 to FOrgTreeCol - FGridFixedColCount do
+  begin
+    if TBM_ColVisible(ColVisible[i]).Visible then
+      Inc(iCount);
+  end;
+  if FGridTreeDBA.TreeCellCol <> FGridFixedColCount + iCount - 1 then
+  begin
+    vGrid := FGridTreeDBA.Grid;
+    FGridTreeDBA.Grid := nil;
+    vGrid.BeginUpdate;
+    vGrid.CellClass.Cols[FGridTreeDBA.TreeCellCol] := vGrid.CellClass.DefaultCellClass;
+    vGrid.ColCount := vGrid.FixedColCount;                                             
+    vGrid.RowCount := vGrid.FixedRowCount + FGridTreeDBA.ExtendRowCount;
+    FGridTreeDBA.TreeCellCol := FGridFixedColCount + iCount - 1;
+    FGridTreeDBA.Grid := vGrid;
+    vGrid.EndUpdate;
+  end;
+end;
+
 procedure TBM_ColVisibleManager.ShowAlias(AShow: Boolean);
 var
   iCol: Integer;
@@ -180,6 +260,20 @@ begin
   RefreshVisible;
 end;
 
+procedure TBM_ColVisibleManager.ShowApprovalCode(AShow: Boolean);
+var
+  iCol: Integer;
+  vCol: TBM_ColVisible;
+begin
+  for iCol := 0 to FColVisibles.Count - 1 do
+  begin
+    vCol := TBM_ColVisible(FColVisibles.Items[iCol]);
+    if SameText('ApprovalCode', vCol.DBACol.FieldName) then
+      vCol.FApprovalCode := AShow;
+  end;
+  RefreshVisible;
+end;
+
 procedure TBM_ColVisibleManager.ShowBGLCode(AShow: Boolean);
 var
   iCol: Integer;
@@ -216,6 +310,20 @@ begin
   RefreshVisible;
 end;
 
+procedure TBM_ColVisibleManager.ShowIsGather(AShow: Boolean);
+var
+  iCol: Integer;
+  vCol: TBM_ColVisible;
+begin
+  for iCol := 0 to FColVisibles.Count - 1 do
+  begin
+    vCol := TBM_ColVisible(FColVisibles.Items[iCol]);
+    if SameText('IsGatherZJJL', vCol.DBACol.FieldName) then
+      vCol.FIsGatherZJJL := AShow;
+  end;
+  RefreshVisible;
+end;
+
 procedure TBM_ColVisibleManager.ShowPriceChange(AShow: Boolean);
 var
   iCol: Integer;

+ 22 - 0
Units/ConfigDoc.pas

@@ -23,7 +23,10 @@ type
     FOverRangeType: Integer;
     FExcelWithMis: Boolean;
     FIsLog: Boolean;
+    FBatchInsertFrmHeight: Integer;
+    FBatchInsertFrmWidth: Integer;
 
+    procedure LoadSectionOfCustomize;
     procedure LoadSectionOfUnitList;
     procedure LoadSectionOfStdFile;
     procedure LoadSectionOfPath;
@@ -33,6 +36,7 @@ type
     procedure SaveIniFile;
     procedure SaveSectionOfStdFile;
     procedure SaveSectionOfOptions;
+    procedure SaveSectionOfCustomize;
 
     function GetStandardGclLib: string;
     function GetStandardXmLib: string;
@@ -61,6 +65,10 @@ type
     property AutoSaveInterval: Integer read FAutoSaveInterval write FAutoSaveInterval;
     property OverRangeType: Integer read FOverRangeType write FOverRangeType;
     property ExcelWithMis: Boolean read FExcelWithMis write FExcelWithMis;
+
+    // Customize
+    property BatchInsertFrmHeight: Integer read FBatchInsertFrmHeight write FBatchInsertFrmHeight;
+    property BatchInsertFrmWidth: Integer read FBatchInsertFrmWidth write FBatchInsertFrmWidth;
   end;
 
 implementation
@@ -108,10 +116,17 @@ begin
   LoadSectionOfStdFile;
   LoadSectionOfPath;
   LoadSectionOfOptions;
+  LoadSectionOfCustomize;
 
   FIsLog := FIniFile.ReadBool('Other', 'IsLog', True);
 end;
 
+procedure TConfigInfo.LoadSectionOfCustomize;
+begin
+  FBatchInsertFrmHeight := FIniFile.ReadInteger('Customize', 'BatchInsertFrmHeight', 382);
+  FBatchInsertFrmWidth := FIniFile.ReadInteger('Customize', 'BatchInsertFrmWidth', 779);
+end;
+
 procedure TConfigInfo.LoadSectionOfOptions;
 begin
   FCompanyName := FIniFile.ReadString('Options', 'CompanyName', '');
@@ -149,6 +164,13 @@ procedure TConfigInfo.SaveIniFile;
 begin
   SaveSectionOfStdFile;
   SaveSectionOfOptions;
+  SaveSectionOfCustomize;
+end;
+
+procedure TConfigInfo.SaveSectionOfCustomize;
+begin
+  FIniFile.WriteInteger('Customize', 'BatchInsertFrmHeight', FBatchInsertFrmHeight);
+  FIniFile.WriteInteger('Customize', 'BatchInsertFrmWidth', FBatchInsertFrmWidth);
 end;
 
 procedure TConfigInfo.SaveSectionOfOptions;

+ 1 - 1
Units/Connections.pas

@@ -8,7 +8,7 @@ uses
 const
   ProductName = 'Measure';
   EmptyFileVersion = '1.0.0.0';
-  FileVersion = '1.0.1.12';
+  FileVersion = '1.0.1.18';
   EncryptVersion = 'Auto1.0';
   SAdoConnectStr = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;' +
                    'User ID=Admin;Password='''';Persist Security Info=True';

+ 34 - 8
Units/DataBaseTables.pas

@@ -107,7 +107,7 @@ const
 
   {清单数据 -- 台账编辑界面}
   SBills = 'Bills';
-  tdBills: array [0..86] of TScFieldDef =(
+  tdBills: array [0..88] of TScFieldDef =(
     (FieldName: 'ID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
     (FieldName: 'ParentID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False),
     (FieldName: 'NextSiblingID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False),
@@ -287,7 +287,11 @@ const
     // 签约清单金额
     (FieldName: 'GclDealTotalPrice'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
     {------------------ End Reports --------------------------}
-    (FieldName: 'PM_AddTotalPrice'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
+    (FieldName: 'PM_AddTotalPrice'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 批复编号
+    (FieldName: 'ApprovalCode'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 计量汇总,生成中间计量时,是否汇总其下所有工程量清单
+    (FieldName: 'IsGatherZJJL'; FieldType: ftBoolean; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
   );
 
   {合同支付}
@@ -340,7 +344,7 @@ const
 
   {变更令}
   SBGL = 'BGL';
-  tdBGL: array [0..11] of TScFieldDef =(
+  tdBGL: array [0..13] of TScFieldDef =(
     (FieldName: 'ID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
     // 变更令号
     (FieldName: 'Code'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
@@ -363,7 +367,11 @@ const
     // 已执行
     (FieldName: 'ExecutionRate'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
     // 变更令类型:一般、较大、重大
-    (FieldName: 'BGLType'; FieldType: ftString; Size: 10; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
+    (FieldName: 'BGLType'; FieldType: ftString; Size: 10; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 是否来自变更令系统
+    (FieldName: 'IsCloud'; FieldType: ftBoolean; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 变更令系统中ID
+    (FieldName: 'WebID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
   );
 
   SBGBills = 'BGBills';
@@ -972,7 +980,7 @@ const
 
   // 中间计量表 -- 见文件“计量\需求\变更令\计量支付窗口主界面结构示意.doc”
   SZJJL = 'ZJJL';
-  tdZJJL: array [0..14] of TScFieldDef =(
+  tdZJJL: array [0..19] of TScFieldDef =(
     (FieldName: 'ID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
     // 所属项目节ID -- 仅允许在最底层项目节输入
     (FieldName: 'BillsID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False),
@@ -1002,16 +1010,34 @@ const
     // 计量单元
     (FieldName: 'UnitName'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
     // 图号
-    (FieldName: 'DrawingCode'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
+    (FieldName: 'DrawingCode'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+
+    // 计量汇总模式特有
+    (FieldName: 'GatherBillsID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'B_Code'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Name'; FieldType: ftString; Size: 200; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Units'; FieldType: ftString; Size: 20; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Price'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
+  );
+
+  SZJJL_Detail = 'ZJJL_Detail';
+  tdZJJL_Detail: array [0..1] of TScFieldDef = (
+    (FieldName: 'ID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
+    (FieldName: 'BillsID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False)
   );
 
   SZJJL_History = 'ZJJL_History';
-  tdZJJL_History: array [0..4] of TScFieldDef =(
+  tdZJJL_History: array [0..8] of TScFieldDef =(
     (FieldName: 'ID'; FieldType: ftInteger; Size: 0; Precision: 0; NotNull: True; PrimaryKey: True; 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)
+    (FieldName: 'FieldValue'; FieldType: ftMemo; Size: 60535; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 计量汇总模式特有
+    (FieldName: 'B_Code'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Name'; FieldType: ftString; Size: 200; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Units'; FieldType: ftString; Size: 20; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Price'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
   );
 
   // 报表数据

+ 1 - 1
Units/DetailExcelImport.pas

@@ -128,7 +128,7 @@ function TDetailExcelImport.GetCellStr(ARow: TExportRow;
   ACol: Integer): string;
 begin
   if (ACol < ARow.Cells.Count) and (ACol >= 0) then
-    Result := ARow.Cells[ACol].SqlText
+    Result := TrimInvalidChar(ARow.Cells[ACol].SqlText)
   else
     Result := '';
 end;

+ 15 - 7
Units/GclBillsGatherModel.pas

@@ -4,7 +4,7 @@ unit GclBillsGatherModel;
 interface
 
 uses
-  Classes, mDataRecord, BillsTree;
+  Classes, mDataRecord, BillsTree, CalcDecimal;
 
 type
   TGatherDataWriteEvent = procedure (AGcls, AXmjs: TList) of object;
@@ -248,6 +248,7 @@ type
     FDeal_BGLQuantity: Double;
     FDeal_BGLTotalPrice: Double;
     FDeal_BGLPercent: Double;
+    FDecimal: TCalcDecimal;
 
     procedure InitCalculate;
     procedure GatherDetailGcl;
@@ -265,7 +266,7 @@ type
     function GetLeafXmjCount: Integer;
     function GetLeafXmj(AIndex: Integer): TLeafXmjNode;
   public
-    constructor Create(AID: Integer);
+    constructor Create(AID: Integer; ADecimal: TCalcDecimal);
     destructor Destroy; override;
 
     procedure AddLeafXmj(ALeafXmj: TLeafXmjNode);
@@ -343,6 +344,8 @@ type
 
     property DetailBGLCount: Integer read GetDetailBGLCount;
     property DetailBGL[AIndex: Integer]: TDetailBGLNode read GetDetailBGL;
+
+    property Decimal: TCalcDecimal read FDecimal;
   end;
 
   TGclGatherModel = class
@@ -361,6 +364,7 @@ type
     FNewDetailBGLID: Integer;
 
     FWriteGatherData: TGatherDataWriteEvent;
+    FDecimal: TCalcDecimal;
 
     procedure BeginGather;
     procedure EndGather;
@@ -399,6 +403,8 @@ type
 
     // 在使用汇总模型的数据单元创建数据库写入方法,并赋值,否则汇总数据不写入
     property WriteGatherData: TGatherDataWriteEvent read FWriteGatherData write FWriteGatherData;
+
+    property Decimal: TCalcDecimal read FDecimal;
   end;
 
 implementation
@@ -488,6 +494,7 @@ begin
   FBillsTree := TProjectData(FProjectData).BillsMeasureData.BillsMeasureTree;
   FGatherDeal := False;
   FGatherBGL := False;
+  FDecimal := TProjectData(FProjectData).ProjProperties.DecimalManager.Common;
 end;
 
 destructor TGclGatherModel.Destroy;
@@ -681,7 +688,7 @@ end;
 function TGclGatherModel.NewGclNode(const AB_Code, AName, AUnits: string;
   APrice: Double): TGclNode;
 begin
-  Result := TGclNode.Create(FNewGclID);
+  Result := TGclNode.Create(FNewGclID, FDecimal);
   FGcls.Add(Result);
   Result.B_Code := TrimRight(AB_Code);
   Result.Name := TrimRight(AName);
@@ -748,21 +755,22 @@ end;
 
 procedure TGclNode.CalculateOther;
 begin
-  FDeal_BGLQuantity := FQuantity + FBGLQuantity;
-  FDeal_BGLTotalPrice := FTotalPrice + FBGLTotalPrice;
+  FDeal_BGLQuantity := Decimal.Quantity.RoundTo(FQuantity + FBGLQuantity);
+  FDeal_BGLTotalPrice := Decimal.TotalPrice.RoundTo(FTotalPrice + FBGLTotalPrice);
   if FDeal_BGLTotalPrice <> 0 then
     FDeal_BGLPercent := CommonRoundTo(FEndGatherTotalPrice/FDeal_BGLTotalPrice*100, -2)
   else
     FDeal_BGLPercent := 0;
 end;
 
-constructor TGclNode.Create(AID: Integer);
+constructor TGclNode.Create(AID: Integer; ADecimal: TCalcDecimal);
 begin
   FID := AID;
   FDetailGcls := TList.Create;
   FDetailDeals := TList.Create;
   FDetailBGLs := TList.Create;
   FLeafXmjs := TList.Create;
+  FDecimal := ADecimal;
 end;
 
 destructor TGclNode.Destroy;
@@ -1069,7 +1077,7 @@ constructor TLeafXmjNode.Create(ALeafXmj, APeg: TBillsIDTreeNode);
   begin
     // 如果计量单元节点的名称为桩号(转化为判断计量单元节点与桩号节点为同一个)
     if not Assigned(APegNode) or (ANode.ID = APegNode.ID) then
-      // 取分工程
+      // 取分工程
       Result := GetNameFenXiang(ANode, APegNode)
     // 反之,取分项工程+计量单元
     else

+ 1 - 1
Units/MCacheTree.pas

@@ -675,7 +675,7 @@ begin
   begin
     sCodeID2 := ConvertDigitCode(Node.Code, 3, '-');
     sB_CodeID2 := ConvertDigitCode(Node.B_Code, 4, '-');
-    if sCodeID < sCodeID2 then
+    if (sCodeID <> '') and (sCodeID < sCodeID2) then
     begin
       Result := Node;
       Break;

+ 271 - 0
Units/MeasureGatherZJJL.pas

@@ -0,0 +1,271 @@
+unit MeasureGatherZJJL;
+
+interface
+
+uses
+  Classes, BillsTree;
+
+type
+  TmgZJJLDetail = class
+  private
+    FRelaNode: TBillsIDTreeNode;
+  public
+    constructor Create(ADetailNode: TBillsIDTreeNode);
+    destructor destroy; override;
+
+    property RelaNode: TBillsIDTreeNode read FRelaNode;
+  end;
+
+  TmgZJJL = class
+  private
+    FB_Code: string;
+    FName: string;
+    FUnits: string;
+    FPrice: Double;
+    FGatherNode: TBillsIDTreeNode;
+    FDetails: TList;
+    FPegName: string;
+    FBeginPeg: string;
+    FBGLCode: string;
+    FEndPeg: string;
+    FUnitName: string;
+    FDrawingCode: string;
+    FFBFXName: string;
+
+    function FindDetail(ADetailNode: TBillsIDTreeNode): TmgZJJLDetail;
+    function NewDetail(ADetailNode: TMeasureBillsIDTreeNode): TmgZJJLDetail;
+
+    function GetDrawingCode(ANode: TBillsIDTreeNode): string;
+    function GetPeg(ANode: TBillsIDTreeNode): string;
+    procedure FilterPeg;
+
+    function GetDetail(AIndex: Integer): TmgZJJLDetail;
+    function GetDetailCount: Integer;
+  public
+    constructor Create(ADetailNode, AGatherNode: TBillsIDTreeNode);
+    destructor Destroy; override;
+
+    function AddDetail(ADetailNode: TBillsIDTreeNode): TmgZJJLDetail;
+
+    property B_Code: string read FB_Code;
+    property Name: string read FName;
+    property Units: string read FUnits;
+    property Price: Double read FPrice;
+    property GatherNode: TBillsIDTreeNode read FGatherNode;
+
+    property BGLCode: string read FBGLCode;
+    property BeginPeg: string read FBeginPeg;
+    property EndPeg: string read FEndPeg;
+    property DrawingCode: string read FDrawingCode;
+
+    property DetailCount: Integer read GetDetailCount;
+    property Detail[AIndex: Integer]: TmgZJJLDetail read GetDetail;
+  end;
+
+  TmgZJJLManager = class
+  private
+    FZJJLs: TList;
+
+    function FindZJJL(ADetailNode, AGatherNode: TBillsIDTreeNode): TmgZJJL;
+    function NewZJJL(ADetailNode, AGatherNode: TBillsIDTreeNode): TmgZJJL;
+
+    function GetZJJL(AIndex: Integer): TmgZJJL;
+    function GetZJJLCount: Integer;
+  public
+    constructor Create;
+    destructor Destroy; override;
+
+    function AddZJJL(ADetailNode, AGatherNode: TBillsIDTreeNode): TmgZJJL;
+    function AddZJJLAndDetail(ADetailNode, AGatherNode: TBillsIDTreeNode): TmgZJJLDetail;
+
+    property ZJJLCount: Integer read GetZJJLCount;
+    property ZJJL[AIndex: Integer]: TmgZJJL read GetZJJL;
+  end;
+
+implementation
+
+uses
+  sdDB, mDataRecord, ZhAPI, UtilMethods, mPegFilter;
+
+{ TmgZJJL }
+
+function TmgZJJL.AddDetail(ADetailNode: TBillsIDTreeNode): TmgZJJLDetail;
+begin
+  Result := FindDetail(ADetailNode);
+  if not Assigned(Result) then
+    Result := NewDetail(TMeasureBillsIDTreeNode(ADetailNode));
+end;
+
+constructor TmgZJJL.Create(ADetailNode, AGatherNode: TBillsIDTreeNode);
+begin
+  FB_Code := ADetailNode.Rec.B_Code.AsString;
+  FName := ADetailNode.Rec.Name.AsString;
+  FUnits := ADetailNode.Rec.Units.AsString;
+  FPrice := ADetailNode.Rec.Price.AsFloat;
+  FGatherNode := AGatherNode;
+  FDetails := TList.Create;
+  AddDetail(ADetailNode);
+
+  FDrawingCode := GetDrawingCode(AGatherNode);
+  FilterPeg;
+end;
+
+destructor TmgZJJL.Destroy;
+begin
+  ClearObjects(FDetails);
+  FDetails.Free;
+  inherited;
+end;
+
+procedure TmgZJJL.FilterPeg;
+var
+  vPegFilter: TPegStrFilter;
+begin
+  vPegFilter := TPegStrFilter.Create;
+  try
+    vPegFilter.PegStr := GetPeg(FGatherNode);
+    FBeginPeg := vPegFilter.BeginPeg;
+    FEndPeg := vPegFilter.EndPeg;
+  finally
+    vPegFilter.Free;
+  end;
+end;
+
+function TmgZJJL.FindDetail(ADetailNode: TBillsIDTreeNode): TmgZJJLDetail;
+var
+  i: Integer;
+begin
+  Result := nil;
+  for i := 0 to DetailCount - 1 do
+  begin
+    if Detail[i].RelaNode = ADetailNode then
+    begin
+      Result := Detail[i];
+      Break;
+    end;
+  end;
+end;
+
+function TmgZJJL.GetDetail(AIndex: Integer): TmgZJJLDetail;
+begin
+  Result := TmgZJJLDetail(FDetails.Items[AIndex]);
+end;
+
+function TmgZJJL.GetDetailCount: Integer;
+begin
+  Result := FDetails.Count;
+end;
+
+function TmgZJJL.GetDrawingCode(ANode: TBillsIDTreeNode): string;
+begin
+  Result := '';
+  if Assigned(ANode) then
+  begin
+    Result := ANode.Rec.DrawingCode.AsString;
+    if Result = '' then
+      Result := GetDrawingCode(TBillsIDTreeNode(ANode.Parent));
+  end;
+end;
+
+function TmgZJJL.GetPeg(ANode: TBillsIDTreeNode): string;
+begin
+  Result := '';
+  if Assigned(ANode) then
+  begin
+    if CheckPeg(ANode.Rec.Name.AsString) then
+      Result := ANode.Rec.Name.AsString
+    else
+      Result := GetPeg(TBillsIDTreeNode(ANode.Parent));
+  end;
+end;
+
+function TmgZJJL.NewDetail(ADetailNode: TMeasureBillsIDTreeNode): TmgZJJLDetail;
+begin
+  Result := TmgZJJLDetail.Create(ADetailNode);
+  FDetails.Add(Result);
+  if Assigned(ADetailNode.StageRec) then
+    FBGLCode := MergeRelaBGL(FBGLCode, ADetailNode.StageRec.QcBGLCode.AsString);
+end;
+
+{ TmgZJJLDetail }
+
+constructor TmgZJJLDetail.Create(ADetailNode: TBillsIDTreeNode);
+begin
+  FRelaNode := ADetailNode;
+end;
+
+destructor TmgZJJLDetail.destroy;
+begin
+
+  inherited;
+end;
+
+{ TmgZJJLManager }
+
+function TmgZJJLManager.AddZJJL(ADetailNode,
+  AGatherNode: TBillsIDTreeNode): TmgZJJL;
+begin
+  Result := FindZJJL(ADetailNode, AGatherNode);
+  if not Assigned(Result) then
+    Result := NewZJJL(ADetailNode, AGatherNode);
+end;
+
+function TmgZJJLManager.AddZJJLAndDetail(ADetailNode,
+  AGatherNode: TBillsIDTreeNode): TmgZJJLDetail;
+var
+  vZJJL: TmgZJJL;
+begin
+  vZJJL := AddZJJL(ADetailNode, AGatherNode);
+  Result := vZJJL.AddDetail(ADetailNode);
+end;
+
+constructor TmgZJJLManager.Create;
+begin
+  FZJJLs := TList.Create;
+end;
+
+destructor TmgZJJLManager.Destroy;
+begin
+  ClearObjects(FZJJLs);
+  FZJJLs.Free;
+  inherited;
+end;
+
+function TmgZJJLManager.FindZJJL(ADetailNode,
+  AGatherNode: TBillsIDTreeNode): TmgZJJL;
+var
+  i: Integer;
+begin
+  Result := nil;
+  for i := 0 to ZJJLCount - 1 do
+  begin
+    if (ZJJL[i].B_Code = ADetailNode.Rec.B_Code.AsString) and
+       (ZJJL[i].Name = ADetailNode.Rec.Name.AsString) and
+       (ZJJL[i].Units = ADetailNode.Rec.Units.AsString) and
+       (ZJJL[i].Price = ADetailNode.Rec.Price.AsFloat) and
+       (ZJJL[i].GatherNode = AGatherNode) then
+    begin
+      Result := ZJJL[i];
+      Break;
+    end;
+  end;
+end;
+
+function TmgZJJLManager.GetZJJL(AIndex: Integer): TmgZJJL;
+begin
+  Result := TmgZJJL(FZJJLs.Items[AIndex]);
+end;
+
+function TmgZJJLManager.GetZJJLCount: Integer;
+begin
+  Result := FZJJLs.Count;
+end;
+
+function TmgZJJLManager.NewZJJL(ADetailNode,
+  AGatherNode: TBillsIDTreeNode): TmgZJJL;
+begin
+  Result := TmgZJJL.Create(ADetailNode, AGatherNode);
+  FZJJLs.Add(Result);
+end;
+
+end.

+ 13 - 1
Units/ProjectCommands.pas

@@ -467,6 +467,8 @@ begin
   vInfo.Attributes['PhaseCount'] := FProjectData.ProjProperties.PhaseCount;
   vInfo.Attributes['AuditStatus'] := FProjectData.ProjProperties.AuditStatus;
   vInfo.Attributes['FileName'] := ExtractSimpleFileName(FFileName);
+  vInfo.Attributes['CommonDigit'] := InfoRec.ValueByName('CommonDigit').AsInteger;
+  vInfo.Attributes['DealPayDigit'] := InfoRec.ValueByName('DealPayDigit').AsInteger;
 
   if G_IsCloud then
   begin
@@ -667,6 +669,8 @@ begin
   FCurNode.Rec.ValueByName('PhaseCount').AsInteger := AXmlNode.Attributes['PhaseCount'];
   FCurNode.Rec.ValueByName('AuditStatus').AsInteger := FNewAuditStatus;
   FCurNode.Rec.ValueByName('CreateDate').AsString := FormatDateTime('yyyy-mm-dd', Date);
+  FCurNode.Rec.ValueByName('CommonDigit').AsInteger := StrToIntDef(AXmlNode.Attributes['CommonDigit'], 0);
+  FCurNode.Rec.ValueByName('DealPayDigit').AsInteger := StrToIntDef(AXmlNode.Attributes['DealPayDigit'], 0);
 
   if G_IsCloud then
   begin
@@ -674,6 +678,8 @@ begin
     FCurNode.Rec.ValueByName('WebOwnerID').AsInteger := AXmlNode.Attributes['WebOwnerID'];
     FCurNode.Rec.ValueByName('WebAuthorID').AsInteger := AXmlNode.Attributes['WebAuthorID'];
   end;
+
+  ProjectManager.CalculateParentInfo(FCurNode.ParentID);
 end;
 
 procedure TReceiveProject.LoadTenderProperty(AXmlNode: IXMLNode);
@@ -822,10 +828,12 @@ begin
   vInfo.Attributes['EndTotalPrice'] := InfoRec.ValueByName('EndTotalPrice').AsFloat;
   vInfo.Attributes['PreTotalPrice'] := InfoRec.ValueByName('PreTotalPrice').AsFloat;
   vInfo.Attributes['PhasePay'] := InfoRec.ValueByName('PhasePay').AsFloat;
-  vInfo.Attributes['Deal_BGLTotalPrice'] := InfoRec.ValueByName('Deal_BGLTotalPrice').AsFloat;  
+  vInfo.Attributes['Deal_BGLTotalPrice'] := InfoRec.ValueByName('Deal_BGLTotalPrice').AsFloat;
   vInfo.Attributes['PhaseCount'] := InfoRec.ValueByName('PhaseCount').AsInteger;
   vInfo.Attributes['AuditStatus'] := InfoRec.ValueByName('AuditStatus').AsInteger;
   vInfo.Attributes['FileName'] := ExtractSimpleFileName(FResultFile);
+  vInfo.Attributes['CommonDigit'] := InfoRec.ValueByName('CommonDigit').AsInteger;
+  vInfo.Attributes['DealPayDigit'] := InfoRec.ValueByName('DealPayDigit').AsInteger;
 
   if G_IsCloud then
   begin
@@ -1097,6 +1105,8 @@ begin
   FNewNode.Rec.ValueByName('PhaseCount').AsInteger := AXmlNode.Attributes['PhaseCount'];
   FNewNode.Rec.ValueByName('AuditStatus').AsInteger := AXmlNode.Attributes['AuditStatus'];
   FNewNode.Rec.ValueByName('CreateDate').AsString := FormatDateTime('yyyy-mm-dd', Date);
+  FNewNode.Rec.ValueByName('CommonDigit').AsInteger := StrToIntDef(AXmlNode.Attributes['CommonDigit'], 0);
+  FNewNode.Rec.ValueByName('DealPayDigit').AsInteger := StrToIntDef(AXmlNode.Attributes['DealPayDigit'], 0);
 
   if G_IsCloud then
   begin
@@ -1104,6 +1114,8 @@ begin
     FNewNode.Rec.ValueByName('WebOwnerID').AsInteger := AXmlNode.Attributes['WebOwnerID'];
     FNewNode.Rec.ValueByName('WebAuthorID').AsInteger := AXmlNode.Attributes['WebAuthorID'];
   end;
+
+  ProjectManager.CalculateParentInfo(FNewNode.ParentID);
 end;
 
 procedure TTenderImport.LoadTenderProperty(AXmlNode: IXMLNode);

+ 139 - 30
Units/ProjectData.pas

@@ -88,8 +88,11 @@ type
     procedure CloseAllData;
     procedure OpenAllData;
 
+    procedure CheckCalcBeforeSave;
     procedure InnerSave;
 
+    procedure LoadCheckersData;
+
     function GetMainFileName: string;
     procedure SetPhaseIndex(const Value: Integer);
     function GetTempPath: string;
@@ -141,7 +144,11 @@ type
     {OpenForGather: BillsData, BillsMeasureTree, DealPaymentData, BGLData, PhaseData(根据PhaseIndex指定打开)}
     procedure OpenForGather(const AFileName: string; APhaseIndex: Integer = -1);
     {OpenForSignOnline: BillsData, BillsMeasureTree, PhaseData(根据PhaseIndex指定打开)}
-    procedure OpenForSignOnline(const AFileName: string; APhaseIndex: Integer = -1);
+    procedure OpenForSignOnline(AProjRec: TsdDataRecord; APhaseIndex: Integer = -1);
+    {OpenForSumUpBase: BillsData, BillsComplieTree}
+    procedure OpenForSumUpBase(const AFileName: string);
+    {OpenForSumUpGather: BillsData, BillsMeasureTree, PhaseData(根据PhaseIndex指定打开),直接调用OpenForSignOnline}
+    procedure OpenForSumUpGather(const AFileName: string; APhaseIndex: Integer = -1);
     //-----------------------  End ---后台打开 ------------------------
 
     procedure SaveDebugFile(const AFileName: string);
@@ -194,6 +201,7 @@ type
 
     procedure ImportCloudTenderFile(const AFileName: string);
     procedure ImportDmfFile(const AFileName: string);
+    procedure ImportSubTenderGather(const AFileName: string);
 
     function CheckPassword: Boolean;
 
@@ -263,10 +271,12 @@ type
 
 implementation
 
-uses UtilMethods, Globals, ProjectCommands, sdIDTree, StageDm,
+uses
+  UtilMethods, Globals, ProjectCommands, sdIDTree, StageDm,
   ZJJLDm, PHPWebDm, XMLDoc, XMLIntf, ConstUnit, PasswordInputFrm,
   mProgressProFrm, mDataRecord, ConditionalDefines, DbTreeImport,
-  StrUtils, sdProvider, CalcDecimal;
+  StrUtils, sdProvider, CalcDecimal, Math, CslJson, OrderCheckerFme,
+  stgSubGatherFile, Forms, ProgressHintFrm, BillsTree, Controls;
 
 { TProjectData }
 
@@ -531,6 +541,7 @@ begin
   InfoRec.ValueByName('AuditStatus').AsInteger := FProjProperties.AuditStatus;
   InfoRec.ValueByName('CommonDigit').AsInteger := FProjProperties.DecimalManager.Common.TotalPrice.Digit;
   InfoRec.ValueByName('DealPayDigit').AsInteger := FProjProperties.DecimalManager.DealPay.TotalPrice.Digit;
+  ProjectManager.CalculateParentInfo(InfoRec.ValueByName('ParentID').AsInteger);
   ProjectManager.Save;
 end;
 
@@ -903,18 +914,37 @@ procedure TProjectData.CopyPhaseData;
             '  From Bills As B, P_Stage As PS, P_ZJJL As PZ' +
             '  Where (PZ.BillsID = B.LeafXmjParentID) And (B.ID = PS.BillsID) And (B.IsLeaf=True)';
     ExecuteSql(sSql);
+    sSql := 'Select PZD.ID, PZD.BillsID, B.Quantity As Quantity, B.TotalPrice As TotalPrice,' +
+            '    PS.DealQuantity As DealQuantity, PS.DealTotalPrice As DealTotalPrice,' +
+            '    PS.QcQuantity As QcQuantity, PS.QcTotalPrice As QcTotalPrice,' +
+            '    PS.GatherQuantity As GatherQuantity, PS.GatherTotalPrice As GatherTotalPrice,' +
+            '    PS.PreDealQuantity As PreDealQuantity, PS.PreDealTotalPrice As PreDealTotalPrice,' +
+            '    PS.PreQcQuantity As PreQcQuantity, PS.PreQcTotalPrice As PreQcTotalPrice,' +
+            '    PS.PreGatherQuantity As PreGatherQuantity, PS.PreGatherTotalPrice As PreGatherTotalPrice,' +
+            '    PS.EndDealQuantity As EndDealQuantity, PS.EndDealTotalPrice As EndDealTotalPrice,' +
+            '    PS.EndQcQuantity As EndQcQuantity, PS.EndQcTotalPrice As EndQcTotalPrice,' +
+            '    PS.EndGatherQuantity As EndGatherQuantity, PS.EndGatherTotalPrice As EndGatherTotalPrice' +
+            '  Into P_ZJJL_DetailBills' +
+            '  From Bills As B, P_Stage As PS, P_ZJJL_Detail As PZD' +
+            '  Where (PZD.BillsID = PS.BillsID) And (B.ID = PZD.BillsID)';
+    ExecuteSql(sSql);
   end;
 
   procedure CopyZJJLData(const AFileName: string);
   var
     sSql: string;
   begin
-    sSql := 'Select ID, BillsID, Code, CertificateCode, BillsCode, FormulaMemo, RelaFile,' +
+    sSql := 'Select ID, BillsID, GatherBillsID, Code, CertificateCode, BillsCode, FormulaMemo, RelaFile,' +
             '    BGLCode, PegName, FBFXName, BeginPeg, EndPeg, UnitName, DrawingCode' +
             '  Into P_ZJJL' +
             '  From ' + PhaseData.ZJJLData.sdpZJJL.TableName +
             '  In ' + Format('''%s''', [AFileName]);
     ExecuteSql(sSql);
+    sSql := 'Select ID, BillsID' +
+            '  Into P_ZJJL_Detail' +
+            '  From ' + PhaseData.ZJJLData.sdpZJJLDetail.TableName +
+            '  In ' + Format('''%s''', [AFileName]);
+    ExecuteSql(sSql);
     CopyZJJLBillsData;
   end;
 
@@ -1251,13 +1281,13 @@ procedure TProjectData.ImportCloudTenderFile(const AFileName: string);
                 '    OrgQuantity, OrgTotalPrice, MisQuantity, MisTotalPrice, OthQuantity, OthTotalPrice,' +
                 '    CalcType,' +
                 '    DgnQuantity1, DgnQuantity2,'+
-                '    Peg, DrawingCode, MemoStr, HasBookMark, MarkMemo)'+
+                '    Peg, DrawingCode, MemoStr, HasBookMark, MarkMemo, ApprovalCode)'+
                 '  Select ID, ParentID, NextSiblingID,'+
                 '    Code, B_Code, Name, Units, Alias, Price, NewPrice,' +
                 '    OrgQuantity, OrgTotalPrice, MisQuantity, MisTotalPrice, OthQuantity, OthTotalPrice,' +
                 '    CalcType,' +
                 '    DgnQuantity1, DgnQuantity2,'+
-                '    Peg, DrawingCode, MemoStr, HasBookMark, MarkMemo'+
+                '    Peg, DrawingCode, MemoStr, HasBookMark, MarkMemo, ApprovalCode'+
                 '  From Bills In ''%s''';
 
     sDealBillsSql = 'Insert Into DealBills Select ID, B_Code, Name, Units, Price, Quantity, TotalPrice'+
@@ -1440,7 +1470,7 @@ begin
   FBillsData.Open(FConnection.Connection);
   FBillsCompileData.Open;
   FDealPaymentData.Open(FConnection.Connection);
-  FBGLData.Open(FConnection.Connection);  
+  FBGLData.Open(FConnection.Connection);
 end;
 
 procedure TProjectData.OpenForReply(const AFileName: string);
@@ -1967,7 +1997,10 @@ var
   sFileName: string;
 begin
   sFileName := ExtractFileName(AFileName);
-  FConnection.SaveDebugFile(FDebugDir + '\' + sFileName);
+  if FDebugDir = '' then
+    FConnection.SaveDebugFile('E:\' + sFileName)
+  else
+    FConnection.SaveDebugFile(FDebugDir + '\' + sFileName);
 end;
 
 procedure TProjectData.SaveTempDataBaseFile(const AFileName: string);
@@ -1998,7 +2031,7 @@ begin
   FProjProperties.Open(FConnection.Connection);
   UpdateOldData;
   FBillsData.Open(FConnection.Connection);
-  FBillsCompileData.Open;
+  FBillsMeasureData.Open;
   FDealPaymentData.Open(FConnection.Connection);
   FBGLData.Open(FConnection.Connection);
   if ProjProperties.PhaseCount > 0 then
@@ -2017,29 +2050,16 @@ begin
   Result := PhaseIndex < ProjProperties.PhaseCount;
 end;
 
-procedure TProjectData.OpenForSignOnline(const AFileName: string;
+procedure TProjectData.OpenForSignOnline(AProjRec: TsdDataRecord;
   APhaseIndex: Integer);
 begin
-  FProjectID := -1;
-  UnZipFile(AFileName, TempPath);
-  FConnection.Open(MainFileName);
-  UpdateProjectDataBase;
-  FProjProperties.Open(FConnection.Connection);
-  UpdateOldData;
-  FBillsData.Open(FConnection.Connection);
-  FBillsMeasureData.Open;
-  FDealPaymentData.Open(FConnection.Connection);
-  FBGLData.Open(FConnection.Connection);
-  if ProjProperties.PhaseCount > 0 then
-  begin
-    if (APhaseIndex <= ProjProperties.PhaseCount) and (APhaseIndex > 0) then
-      FPhaseIndex := APhaseIndex
-    else
-      FPhaseIndex := ProjProperties.PhaseCount;
-    FPhaseData.SimpleOpen2(Format('%sPhase%d.dat', [TempPath, FPhaseIndex]));
-  end;
-  FBillsMeasureData.ResetTreeNodeStageRec;
-
+  FWebID := AProjRec.ValueByName('WebID').AsInteger;
+  FWebOwnerID := AProjRec.ValueByName('WebOwnerID').AsInteger;
+  FWebAuthorID := AProjRec.ValueByName('WebAuthorID').AsInteger;
+  
+  OpenForGather(GetMyProjectsFilePath + AProjRec.ValueByName('FileName').AsString, APhaseIndex);
+  if _IsCloud then
+    LoadCheckersData;
   CopyPhaseData(False);
 end;
 
@@ -2112,6 +2132,8 @@ begin
   try
     AppendProjectLog('Save Main Data');
 
+    CheckCalcBeforeSave;
+
     UpdateSysProgress(5, '正在保存数据');
     SaveLastestPhaseMainData;
     UpdateSysProgress(10, '正在保存数据');
@@ -2177,4 +2199,91 @@ begin
   FIsGuest := Value;
 end;
 
+procedure TProjectData.LoadCheckersData;
+var
+  sURL: string;
+  vA: TOVArr;
+  i, iIndex: Integer;
+  vStatus: TCheckStatus;
+begin
+  Checkers.Clear;
+  sURL := Format('%suser/get/all/%d/%d/measure', [PHPWeb.MeasureURL, WebID, PhaseIndex]);
+  if PHPWeb.Search(sURL, [''], [''], vA) = 1 then
+  begin
+    for i := Low(vA) to High(vA) do
+    begin
+      vStatus :=  TCheckStatus(StrToInt(vA[i, 3])-1);
+      iIndex := Checkers.Add(StrToInt(vA[i, 4]), vA[i, 0], vA[i, 2], vA[i, 6], vA[i, 8]);
+      if vStatus in [csFinished, csNotPass] then
+        Checkers.LastChecker := Checkers.Item[iIndex];
+    end;
+  end
+end;
+
+procedure TProjectData.OpenForSumUpBase(const AFileName: string);
+begin
+  FProjectID := -1;
+  UnZipFile(AFileName, TempPath);
+  FConnection.Open(MainFileName);
+  UpdateProjectDataBase;
+  FProjProperties.Open(FConnection.Connection);
+  UpdateOldData;
+  FBillsData.Open(FConnection.Connection);
+  FBillsCompileData.Open;
+end;
+
+procedure TProjectData.OpenForSumUpGather(const AFileName: string;
+  APhaseIndex: Integer);
+begin
+  OpenForGather(AFileName, APhaseIndex);
+end;
+
+procedure TProjectData.ImportSubTenderGather(const AFileName: string);
+var
+  vImportor: TstgSubGatherFileImportor;
+begin
+  if PhaseData.StageDataReadOnly then Exit;
+
+  vImportor := TstgSubGatherFileImportor.Create;
+  try
+    vImportor.ImportGatherDataTo(PhaseData.StageData, AFileName);
+  finally
+    CalculateAll;
+    vImportor.Free;
+  end;
+end;
+
+procedure TProjectData.CheckCalcBeforeSave;
+
+  function NeedReCalc: Boolean;
+  var
+    vTopNode: TsdIDTreeNode;
+  begin
+    Result := False;
+    vTopNode := BillsMeasureData.BillsMeasureTree.FirstNode;
+    while not Result and Assigned(vTopNode) do
+    begin
+      if not BillsMeasureData.CheckNodeGatherCalc(TMeasureBillsIDTreeNode(vTopNode)) then
+        Result := True;
+      vTopNode := vTopNode.NextSibling;
+    end;
+  end;
+
+var
+  i: Integer;
+  fLeafSum, fTopParent: Double;
+begin
+  if PhaseData.Active and (not StageDataReadOnly) and NeedReCalc then
+  begin
+    Screen.Cursor := crHourGlass;
+    try
+      ShowProgressHint('检查到有需要计算的清单,请稍候...');
+      CalculateAll;
+      CloseProgressHint;
+    finally
+      Screen.Cursor := crDefault;
+    end;
+  end;
+end;
+
 end.

+ 20 - 0
Units/ProjectProperty.pas

@@ -90,6 +90,8 @@ type
     FCLegal_2: string;
     FSName_2: string;
     FSDate_2: string;
+    FShowOverRange: Boolean;
+    FShowApprovalCode: Boolean;
 
     function GetDisplayFormat(ADigit: Integer): string;
 
@@ -134,6 +136,8 @@ type
     procedure SetReportShowState(const Value: Boolean);
     procedure SetReportShowStateText(const Value: string);
     procedure SetReportShowStateWithoutReply(const Value: Boolean);
+    procedure SetShowOverRange(const Value: Boolean);
+    procedure SetShowApprovalCode(const Value: Boolean);
   public
     constructor Create(AProjectData: TObject);
     destructor Destroy; override;
@@ -259,6 +263,8 @@ type
     property ShowBGLCode: Boolean read FShowBGLCode write SetShowBGLCode;
     property ShowDesignQuantity: Boolean read FShowDesignQuantity write SetShowDesignQuantity;
     property ShowAlias: Boolean read FShowAlias write SetShowAlias;
+    property ShowOverRange: Boolean read FShowOverRange write SetShowOverRange;
+    property ShowApprovalCode: Boolean read FShowApprovalCode write SetShowApprovalCode;
 
     property ShowReportShading: Boolean read FShowReportShading write SetShowReportShading;
     property ReportShading: string read FReportShading write SetReportShading;
@@ -553,6 +559,8 @@ begin
   FShowBGLCode := GetBoolPropertyDef('ShowBGLCode', True);
   FShowDesignQuantity := GetBoolPropertyDef('ShowDesignQuantity', False);
   FShowAlias := GetBoolPropertyDef('ShowAlias', False);
+  FShowOverRange := GetBoolPropertyDef('ShowOverRange', True);
+  FShowApprovalCode := GetBoolPropertyDef('ShowApprovalCode', False);
 
   FShowReportShading := GetBoolPropertyDef('ShowReportShading', False);
   FReportShading := GetStrPropertyDef('ReportShading', '');
@@ -750,6 +758,12 @@ begin
   FPropertyInqurity.Value['ShowAlias'] := Value;
 end;
 
+procedure TProjProperties.SetShowApprovalCode(const Value: Boolean);
+begin
+  FShowApprovalCode := Value;
+  FPropertyInqurity.Value['ShowApprovalCode'] := Value;
+end;
+
 procedure TProjProperties.SetShowBGLCode(const Value: Boolean);
 begin
   FShowBGLCode := Value;
@@ -762,6 +776,12 @@ begin
   FPropertyInqurity.Value['ShowDesignQuantity'] := Value;
 end;
 
+procedure TProjProperties.SetShowOverRange(const Value: Boolean);
+begin
+  FShowOverRange := Value;
+  FPropertyInqurity.Value['ShowOverRange'] := Value;
+end;
+
 procedure TProjProperties.SetShowPriceChange(const Value: Boolean);
 begin
   FShowPriceChange := Value;

+ 1 - 0
Units/UpdateDataBase.pas

@@ -175,6 +175,7 @@ begin
     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(SZJJL_Detail, @tdZJJL_Detail, length(tdZJJL_Detail), False, False);
     Updater.AddTableDef(SReportData, @tdReportData, Length(tdReportData), False, False);
     Updater.ExcuteUpdate;
   finally

+ 22 - 2
Units/UtilMethods.pas

@@ -17,6 +17,7 @@ type
   function PriceRoundTo(AValue: Double): Double;
   function TotalPriceRoundTo(AValue: Double): Double;
   function CommonRoundTo(AValue: Double; ADigit: Integer; RoundMode: TRoundMode = rmNearest): Double;
+  function CommonCalcRoundTo(AValue: Double): Double;
 
   {Interface Control}
   procedure AlignControl(AControl, AParent: TWinControl; AAlign: TAlign);
@@ -62,6 +63,7 @@ type
   function CheckPeg(const AStr: string): Boolean;
   function CheckValidPassword(APassword: string): Boolean;
   function ValidInteger(var AKey: Char): Boolean;
+  function TrimInvalidChar(const AText: string): string;
 
   {MergeStrings}
   function MergeRelaBGL(const ABGLCode1, ABGLCode2: string): string;
@@ -232,12 +234,17 @@ begin
     end;
   P := @X;
   CopyMemory(P, @Buf[0], SizeOf(X));
-  if (ADigit < 0) and (ADigit < GetTrueDigit(AValue)) then
+  if (ADigit <= -6) and (ADigit < GetTrueDigit(AValue)) then
     Result := AValue
   else
     Result := InnerRoundTo(X, ADigit, RoundMode);
 end;
 
+function CommonCalcRoundTo(AValue: Double): Double;
+begin
+  Result := CommonRoundTo(AValue, -10);
+end;
+
 {Interface Control}
 procedure AlignControl(AControl, AParent: TWinControl; AAlign: TAlign);
 begin
@@ -377,7 +384,7 @@ end;
 function GetAppTempPath: string;
 begin
   Result := GetAppFilePath + 'Temp\';
-  if DirectoryExists(Result) then
+  if not DirectoryExists(Result) then
     CreateDirectoryInDeep(Result);
 end;
 
@@ -678,6 +685,19 @@ begin
   end;
 end;
 
+function TrimInvalidChar(const AText: string): string;
+var
+  i, iLength: Integer;
+begin
+  Result := '';
+  iLength := Length(AText);
+  for i := 1 to iLength do
+  begin
+    if not (AText[i] in [#0]) then
+      Result := Result + AText[i];
+  end;
+end;
+
 {MergeStrings}
 function MergeRelaBGL(const ABGLCode1, ABGLCode2: string): string;
 var

+ 6 - 0
Units/mDataRecord.pas

@@ -76,10 +76,12 @@ type
     FLockedNewPrice: TsdValue;
     FCreatePhaseID: TsdValue;
     FIsMeasureAdd: TsdValue;
+    FIsGatherZJJL: TsdValue;
 
     FPeg: TsdValue;
     FDrawingCode: TsdValue;
     FMemoStr: TsdValue;
+    FApprovalCode: TsdValue;
 
     FDgnQuantity1: TsdValue;
     FDgnQuantity2: TsdValue;
@@ -166,10 +168,12 @@ type
     property LockedNewPrice: TsdValue read FLockedNewPrice;
     property CreatePhaseID: TsdValue read FCreatePhaseID;
     property IsMeasureAdd: TsdValue read FIsMeasureAdd;
+    property IsGatherZJJL: TsdValue read FIsGatherZJJL;
 
     property Peg: TsdValue read FPeg;
     property DrawingCode: TsdValue read FDrawingCode;
     property MemoStr: TsdValue read FMemoStr;
+    property ApprovalCode: TsdValue read FApprovalCode;
 
     property DgnQuantity1: TsdValue read FDgnQuantity1;
     property DgnQuantity2: TsdValue read FDgnQuantity2;
@@ -560,10 +564,12 @@ begin
   FLockedNewPrice := ValueByName('LockedNewPrice');
   FCreatePhaseID := ValueByName('CreatePhaseID');
   FIsMeasureAdd := ValueByName('IsMeasureAdd');
+  FIsGatherZJJL := ValueByName('IsGatherZJJL');
 
   FPeg := ValueByName('Peg');
   FDrawingCode := ValueByName('DrawingCode');
   FMemoStr := ValueByName('MemoStr');
+  FApprovalCode := ValueByName('ApprovalCode');
 
   FDgnQuantity1 := ValueByName('DgnQuantity1');
   FDgnQuantity2 := ValueByName('DgnQuantity2');