Browse Source

1. 合并代码,包括[清单汇总]、[材料调差]、[报表内存表],便于以后维护
2. 关闭报表界面后,删除报表缓存数据,以减少文件大小

MaiXinRong 9 years ago
parent
commit
e897c3b290

+ 24 - 24
DataModules/BillsGatherDm.dfm

@@ -493,30 +493,30 @@ object BillsGatherData: TBillsGatherData
     FieldListData = {
       0101044E616D6506024944094669656C644E616D650602494408446174615479
       70650203084461746153697A6502040549734B6579080F4E65656450726F6365
-      73734E616D65090001044E616D65060742696C6C734944094669656C644E616D
-      65060742696C6C7349440844617461547970650203084461746153697A650204
-      0549734B6579080F4E65656450726F636573734E616D65090001044E616D6506
-      09424742696C6C734944094669656C644E616D650609424742696C6C73494408
-      44617461547970650203084461746153697A6502040549734B6579080F4E6565
-      6450726F636573734E616D65090001044E616D65060542474C4944094669656C
-      644E616D65060542474C49440844617461547970650203084461746153697A65
-      02040549734B6579080F4E65656450726F636573734E616D65090001044E616D
-      65060742474C436F6465094669656C644E616D65060742474C436F6465084461
-      7461547970650218084461746153697A6502320549734B6579080F4E65656450
-      726F636573734E616D65090001044E616D65060742474C4E616D65094669656C
-      644E616D65060742474C4E616D65084461746154797065021808446174615369
-      7A6503C8000549734B6579080F4E65656450726F636573734E616D6509000104
-      4E616D65060F42474C417070726F76616C436F6465094669656C644E616D6506
-      0F42474C417070726F76616C436F646508446174615479706502180844617461
-      53697A6502320549734B6579080F4E65656450726F636573734E616D65090001
-      044E616D65060E42474C44726177696E67436F6465094669656C644E616D6506
-      0E42474C44726177696E67436F64650844617461547970650218084461746153
-      697A6502320549734B6579080F4E65656450726F636573734E616D6509000104
-      4E616D6506085175616E74697479094669656C644E616D6506085175616E7469
-      74790844617461547970650206084461746153697A6502080549734B6579080F
-      4E65656450726F636573734E616D65090001044E616D65060A546F74616C5072
-      696365094669656C644E616D65060A546F74616C507269636508446174615479
-      70650206084461746153697A6502080549734B6579080F4E65656450726F6365
+      73734E616D65090001044E616D650609424742696C6C734944094669656C644E
+      616D650609424742696C6C734944084461746154797065020308446174615369
+      7A6502040549734B6579080F4E65656450726F636573734E616D65090001044E
+      616D65060542474C4944094669656C644E616D65060542474C49440844617461
+      547970650203084461746153697A6502040549734B6579080F4E65656450726F
+      636573734E616D65090001044E616D65060742474C436F6465094669656C644E
+      616D65060742474C436F64650844617461547970650218084461746153697A65
+      02320549734B6579080F4E65656450726F636573734E616D65090001044E616D
+      65060742474C4E616D65094669656C644E616D65060742474C4E616D65084461
+      7461547970650218084461746153697A6503C8000549734B6579080F4E656564
+      50726F636573734E616D65090001044E616D65060F42474C417070726F76616C
+      436F6465094669656C644E616D65060F42474C417070726F76616C436F646508
+      44617461547970650218084461746153697A6502320549734B6579080F4E6565
+      6450726F636573734E616D65090001044E616D65060E42474C44726177696E67
+      436F6465094669656C644E616D65060E42474C44726177696E67436F64650844
+      617461547970650218084461746153697A6502320549734B6579080F4E656564
+      50726F636573734E616D65090001044E616D6506085175616E74697479094669
+      656C644E616D6506085175616E74697479084461746154797065020608446174
+      6153697A6502080549734B6579080F4E65656450726F636573734E616D650900
+      01044E616D65060A546F74616C5072696365094669656C644E616D65060A546F
+      74616C50726963650844617461547970650206084461746153697A6502080549
+      734B6579080F4E65656450726F636573734E616D65090001044E616D65060742
+      696C6C734944094669656C644E616D65060742696C6C73494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
       73734E616D65090000}
   end
   object sdvDetailBGLBills: TsdDataView

+ 19 - 9
DataModules/BillsGatherDm.pas

@@ -96,6 +96,8 @@ var
 begin
   vGather := TGclGatherModel.Create(FProjectData);
   try
+    vGather.GatherDeal := True;
+    vGather.GatherBGL := True;
     vGather.WriteGatherData := WriteGatherRecord;
     vGather.Execute;
   finally
@@ -152,6 +154,7 @@ procedure TBillsGatherData.WriteGatherRecord(AGcls: TList);
     for iDeal := 0 to AGclNode.DetailDealCount - 1 do
     begin
       vDeal := AGclNode.DetailDeal[iDeal];
+      Rec := sddDetailDealBills.Add;
       Rec.ValueByName('ID').AsInteger := vDeal.ID;
       Rec.ValueByName('BillsID').AsInteger := AGclNode.ID;
       Rec.ValueByName('DealID').AsInteger := vDeal.DealID;
@@ -175,6 +178,7 @@ procedure TBillsGatherData.WriteGatherRecord(AGcls: TList);
     for iBGL := 0 to AGclNode.DetailBGLCount - 1 do
     begin
       vBGL := AGclNode.DetailBGL[iBGL];
+      Rec := sddDetailBGLBills.Add;
       Rec.ValueByName('ID').AsInteger := vBGL.ID;
       Rec.ValueByName('BillsID').AsInteger := AGclNode.ID;
       Rec.ValueByName('BGBillsID').AsInteger := vBGL.BGBillsID;
@@ -203,16 +207,22 @@ procedure TBillsGatherData.WriteGatherRecord(AGcls: TList);
       Rec.ValueByName('ID').AsInteger := vDetailGcl.ID;
       Rec.ValueByName('BillsID').AsInteger := AGclNode.ID;
       Rec.ValueByName('TreeSerialNo').AsInteger := vDetailGcl.TreeSerialNo;
-
       Rec.ValueByName('RelaBillsID').AsInteger := vDetailGcl.BillsID;
-      Rec.ValueByName('LeafXmjID').AsInteger := vDetailGcl.LeafXmjID;
-      Rec.ValueByName('XmjCode').AsString := vDetailGcl.XmjCode;
-      Rec.ValueByName('XmjName').AsString := vDetailGcl.XmjName;
-      Rec.ValueByName('XmjUnits').AsString := vDetailGcl.XmjUnits;
-      Rec.ValueByName('NameDanWei').AsString := vDetailGcl.NameDanWei;
-      Rec.ValueByName('NameFenXiang').AsString := vDetailGcl.NameFenXiang;
-      Rec.ValueByName('NameFenBu').AsString := vDetailGcl.NameFenBu;
-      Rec.ValueByName('NameUnit').AsString := vDetailGcl.NameUnit;
+
+      if Assigned(vDetailGcl.LeafXmj) then
+      begin
+        Rec.ValueByName('LeafXmjID').AsInteger := vDetailGcl.LeafXmj.ID;
+        Rec.ValueByName('XmjCode').AsString := vDetailGcl.LeafXmj.XmjCode;
+        Rec.ValueByName('XmjName').AsString := vDetailGcl.LeafXmj.XmjName;
+        Rec.ValueByName('XmjUnits').AsString := vDetailGcl.LeafXmj.XmjUnits;
+        Rec.ValueByName('NameDanWei').AsString := vDetailGcl.LeafXmj.NameDanWei;
+        Rec.ValueByName('NameFenXiang').AsString := vDetailGcl.LeafXmj.NameFenXiang;
+        Rec.ValueByName('NameFenBu').AsString := vDetailGcl.LeafXmj.NameFenBu;
+        Rec.ValueByName('NameUnit').AsString := vDetailGcl.LeafXmj.NameUnit;
+        Rec.ValueByName('Peg').AsString := vDetailGcl.LeafXmj.Peg;
+        Rec.ValueByName('Position').AsString := vDetailGcl.LeafXmj.Position;
+        Rec.ValueByName('DrawingCode').AsString := vDetailGcl.LeafXmj.DrawingCode;
+      end;
 
       Rec.ValueByName('CurDealQuantity').AsFloat := vDetailGcl.CurDealQuantity;
       Rec.ValueByName('CurDealTotalPrice').AsFloat := vDetailGcl.CurDealTotalPrice;

+ 21 - 16
DataModules/PriceMarginBillsDm.dfm

@@ -83,22 +83,27 @@ object PriceMarginBillsData: TPriceMarginBillsData
       4B6579080F4E65656450726F636573734E616D65090001044E616D6506035065
       67094669656C644E616D65060350656708446174615479706502180844617461
       53697A6503C8000549734B6579080F4E65656450726F636573734E616D650900
-      01044E616D65060F4375724465616C5175616E74697479094669656C644E616D
-      65060F4375724465616C5175616E746974790844617461547970650206084461
-      746153697A6502080549734B6579080F4E65656450726F636573734E616D6509
-      0001044E616D65060D43757251635175616E74697479094669656C644E616D65
-      060D43757251635175616E746974790844617461547970650206084461746153
-      697A6502080549734B6579080F4E65656450726F636573734E616D6509000104
-      4E616D6506114375724761746865725175616E74697479094669656C644E616D
-      6506114375724761746865725175616E74697479084461746154797065020608
-      4461746153697A6502080549734B6579080F4E65656450726F636573734E616D
-      65090001044E616D650610504D5F507265546F74616C5072696365094669656C
-      644E616D650610504D5F507265546F74616C5072696365084461746154797065
-      0206084461746153697A6502080549734B6579080F4E65656450726F63657373
-      4E616D65090001044E616D65060D504D5F546F74616C5072696365094669656C
-      644E616D65060D504D5F546F74616C5072696365084461746154797065020608
-      4461746153697A6502080549734B6579080F4E65656450726F636573734E616D
-      65090000}
+      01044E616D650608506F736974696F6E094669656C644E616D650608506F7369
+      74696F6E0844617461547970650218084461746153697A6503C8000549734B65
+      79080F4E65656450726F636573734E616D65090001044E616D65060B44726177
+      696E67436F6465094669656C644E616D65060B44726177696E67436F64650844
+      617461547970650218084461746153697A6502320549734B6579080F4E656564
+      50726F636573734E616D65090001044E616D65060F4375724465616C5175616E
+      74697479094669656C644E616D65060F4375724465616C5175616E7469747908
+      44617461547970650206084461746153697A6502080549734B6579080F4E6565
+      6450726F636573734E616D65090001044E616D65060D43757251635175616E74
+      697479094669656C644E616D65060D43757251635175616E7469747908446174
+      61547970650206084461746153697A6502080549734B6579080F4E6565645072
+      6F636573734E616D65090001044E616D6506114375724761746865725175616E
+      74697479094669656C644E616D6506114375724761746865725175616E746974
+      790844617461547970650206084461746153697A6502080549734B6579080F4E
+      65656450726F636573734E616D65090001044E616D650610504D5F507265546F
+      74616C5072696365094669656C644E616D650610504D5F507265546F74616C50
+      726963650844617461547970650206084461746153697A6502080549734B6579
+      080F4E65656450726F636573734E616D65090001044E616D65060D504D5F546F
+      74616C5072696365094669656C644E616D65060D504D5F546F74616C50726963
+      650844617461547970650206084461746153697A6502080549734B6579080F4E
+      65656450726F636573734E616D65090000}
   end
   object sdvGclBills: TsdDataView
     Active = False

+ 15 - 9
DataModules/PriceMarginBillsDm.pas

@@ -149,16 +149,22 @@ procedure TPriceMarginBillsData.WriteGclBillsData(AGcls: TList);
       Rec.ValueByName('ID').AsInteger := vDetailGcl.ID;
       Rec.ValueByName('BillsID').AsInteger := AGclNode.ID;
       Rec.ValueByName('TreeSerialNo').AsInteger := vDetailGcl.TreeSerialNo;
-
       Rec.ValueByName('RelaBillsID').AsInteger := vDetailGcl.BillsID;
-      Rec.ValueByName('LeafXmjID').AsInteger := vDetailGcl.LeafXmjID;
-      Rec.ValueByName('XmjCode').AsString := vDetailGcl.XmjCode;
-      Rec.ValueByName('XmjName').AsString := vDetailGcl.XmjName;
-      Rec.ValueByName('XmjUnits').AsString := vDetailGcl.XmjUnits;
-      Rec.ValueByName('NameDanWei').AsString := vDetailGcl.NameDanWei;
-      Rec.ValueByName('NameFenXiang').AsString := vDetailGcl.NameFenXiang;
-      Rec.ValueByName('NameFenBu').AsString := vDetailGcl.NameFenBu;
-      Rec.ValueByName('NameUnit').AsString := vDetailGcl.NameUnit;
+
+      if Assigned(vDetailGcl.LeafXmj) then
+      begin
+        Rec.ValueByName('LeafXmjID').AsInteger := vDetailGcl.LeafXmj.ID;
+        Rec.ValueByName('XmjCode').AsString := vDetailGcl.LeafXmj.XmjCode;
+        Rec.ValueByName('XmjName').AsString := vDetailGcl.LeafXmj.XmjName;
+        Rec.ValueByName('XmjUnits').AsString := vDetailGcl.LeafXmj.XmjUnits;
+        Rec.ValueByName('NameDanWei').AsString := vDetailGcl.LeafXmj.NameDanWei;
+        Rec.ValueByName('NameFenXiang').AsString := vDetailGcl.LeafXmj.NameFenXiang;
+        Rec.ValueByName('NameFenBu').AsString := vDetailGcl.LeafXmj.NameFenBu;
+        Rec.ValueByName('NameUnit').AsString := vDetailGcl.LeafXmj.NameUnit;
+        Rec.ValueByName('Peg').AsString := vDetailGcl.LeafXmj.Peg;
+        Rec.ValueByName('Position').AsString := vDetailGcl.LeafXmj.Position;
+        Rec.ValueByName('DrawingCode').AsString := vDetailGcl.LeafXmj.DrawingCode;
+      end;
 
       Rec.ValueByName('CurDealQuantity').AsFloat := vDetailGcl.CurDealQuantity;
       Rec.ValueByName('CurQcQuantity').AsFloat := vDetailGcl.CurQcQuantity;

+ 102 - 444
DataModules/ReportMemoryDm/rmGcl_XmjBillsDm.pas

@@ -3,7 +3,8 @@ unit rmGcl_XmjBillsDm;
 interface
 
 uses
-  SysUtils, Classes, ProjectData, DB, DBClient, sdIDTree, sdDB;
+  SysUtils, Classes, ProjectData, DB, DBClient, sdIDTree, sdDB,
+  GclBillsGatherModel;
 
 type
   {-----------------------------
@@ -25,70 +26,6 @@ type
   -----------------------------}
   TGXType = (gxtTopGcl, gxtFlowGcl, gxtWithoutXmj);
 
-  TXmjNode = class
-  private
-    FCode: string;
-    FName: string;
-    FUnits: string;
-
-    FOrgQuantity: Double;
-    FOrgTotalPrice: Double;
-    FMisQuantity: Double;
-    FMisTotalPrice: Double;
-    FOthQuantity: Double;
-    FOthTotalPrice: Double;
-
-    FQuantity: Double;
-    FTotalPrice: Double;
-
-    FDrawingCode: string;
-    FPeg: string;
-    FNameDanWei: string;
-    FNameFenBu: string;
-    FNameFenXiang: string;
-    FNameUnit: string;
-    FPosition: string;
-  end;
-
-  TGclNode = class
-  private
-    FB_Code: string;
-    FIndexCode: string;
-    FName: string;
-    FUnits: string;
-    FPrice: Double;
-    FNewPrice: Double;
-
-    FDealQuantity: Double;
-    FDealTotalPrice: Double;
-
-    FOrgQuantity: Double;
-    FOrgTotalPrice: Double;
-    FMisQuantity: Double;
-    FMisTotalPrice: Double;
-    FOthQuantity: Double;
-    FOthTotalPrice: Double;
-
-    FQuantity: Double;
-    FTotalPrice: Double;
-
-    FXmjList: TList;
-
-    function FindXmjNode(ANode: TsdIDTreeNode): TXmjNode;
-    function NewXmjNode(ANode, APeg: TsdIDTreeNode): TXmjNode;
-
-    function GetXmjCount: Integer;
-    function GetXmjNode(AIndex: Integer): TXmjNode;
-  public
-    constructor Create;
-    destructor Destroy; override;
-
-    function AddXmjNode(ANode, APeg: TsdIDTreeNode): TXmjNode;
-
-    property XmjCount: Integer read GetXmjCount;
-    property XmjNode[AIndex: Integer]: TXmjNode read GetXmjNode;
-  end;
-
   TrmGcl_XmjBillsData = class(TDataModule)
     cdsGcl: TClientDataSet;
     cdsGclIndexCode: TStringField;
@@ -120,27 +57,22 @@ type
     cdsGclOthTotalPrice: TFloatField;
   private
     FProjectData: TProjectData;
-    FGclList: TList;
     FIndex: Integer;
     FGXType: TGXType;
 
     procedure BeforeOperation;
     procedure AfterOperation;
 
-    procedure AddRelaLeafXmj(AGclNode: TGclNode; ARec: TsdDataRecord);
-    function GetGclNode(ARec: TsdDataRecord): TGclNode;
-    procedure FilterGclBills(ANode: TsdIDTreeNode);
-    procedure FilterBills(ANode: TsdIDTreeNode);
-    procedure FilterDealBills;
-
     procedure WriteXmjNode(AGclNode: TGclNode);
     procedure WriteGclNode(AGclNode: TGclNode);
-    procedure WriteTopGclTypeData;
+    procedure WriteTopGclTypeData(AGcls: TList);
 
     procedure WriteFlowGclNode(AGclNode: TGclNode);
-    procedure WriteFlowGclTypeData;
+    procedure WriteFlowGclTypeData(AGcls: TList);
+
+    procedure WriteData(AGcls: TList);
 
-    procedure WriteData;
+    procedure GatherData;
   public
     function AssignData(AProjectData: TProjectData; AGXType: TGXType): TDataSet;
   end;
@@ -152,212 +84,10 @@ uses
 
 {$R *.dfm}
 
-{ TGclNode }
-
-constructor TGclNode.Create;
-begin
-  FXmjList := TList.Create;
-end;
-
-destructor TGclNode.Destroy;
-begin
-  ClearObjects(FXmjList);
-  FXmjList.Free;
-  inherited;
-end;
-
-function TGclNode.FindXmjNode(ANode: TsdIDTreeNode): TXmjNode;
-var
-  i: Integer;
-begin
-  Result := nil;
-  for i := 0 to XmjCount - 1 do
-  begin
-    if SameText(XmjNode[i].FCode, ANode.Rec.ValueByName('Code').AsString) and
-       SameText(XmjNode[i].FName, ANode.Rec.ValueByName('Name').AsString) and
-       SameText(XmjNode[i].FUnits, ANode.Rec.ValueByName('Units').AsString) then
-    begin
-      Result := XmjNode[i];
-      Break;
-    end;
-  end;
-end;
-
-function TGclNode.AddXmjNode(
-  ANode, APeg: TsdIDTreeNode): TXmjNode;
-begin
-  Result := FindXmjNode(ANode);
-  if not Assigned(Result) then
-    Result := NewXmjNode(ANode, APeg);
-end;
-
-function TGclNode.GetXmjCount: Integer;
-begin
-  Result := FXmjList.Count;
-end;
-
-function TGclNode.GetXmjNode(AIndex: Integer): TXmjNode;
-begin
-  Result := TXmjNode(FXmjList.Items[AIndex]);
-end;
-
-function TGclNode.NewXmjNode(
-  ANode, APeg: TsdIDTreeNode): TXmjNode;
-
-  function GetPegName(APegNode: TsdIDTreeNode): string;
-  begin
-    if Assigned(APegNode) then
-      Result := APegNode.Rec.ValueByName('Name').AsString
-    else
-      Result := '';
-  end;
-
-  // 取树结构的第ALevel层节点的名称(level从0开始)
-  function GetNameByLevel(ANode: TsdIDTreeNode; ALevel: Integer): string;
-  begin
-    Result := '';
-    if not Assigned(ANode) then Exit;
-    if ANode.Level = ALevel then
-      Result := ANode.Rec.ValueByName('Name').AsString
-    else if ANode.Level > ALevel then
-      Result := GetNameByLevel(ANode.Parent, ALevel);
-  end;
-
-  function GetNameDanWei(ANode: TsdIDTreeNode): string;
-  begin
-    // 取树结构的第二层节点的名称
-    Result := GetNameByLevel(ANode, 1);
-  end;
-
-  // ANode为计量单元节点,APegNode为桩号节点
-  function GetNameFenBu(ANode, APegNode: TsdIDTreeNode): string;
-  var
-    vCurNode: TsdIDTreeNode;
-  begin
-    // 如果计量单元节点的名称为桩号(转化为判断计量单元节点与桩号节点为同一个)
-    if not Assigned(APegNode) or (ANode.ID = APegNode.ID) then
-      // 取树结构的第三层节点的名称
-      Result := GetNameByLevel(ANode, 2)
-    // 否则,取桩号节点的子节点的名称
-    else
-    begin
-      vCurNode := ANode;
-      while vCurNode.Level > APegNode.Level + 1 do
-        vCurNode := vCurNode.Parent;
-      Result := vCurNode.Rec.ValueByName('Name').AsString;
-    end;
-  end;
-
-  function GetNameFenXiang(ANode, APegNode: TsdIDTreeNode): string;
-  var
-    iTopLevel: Integer;
-    vCurNode: TsdIDTreeNode;
-  begin
-    if Assigned(APegNode) then
-    begin
-      iTopLevel := 3;
-      if APegNode.ID <> ANode.ID then
-        iTopLevel := APegNode.Level + 2;
-      Result := '';
-      vCurNode := ANode.Parent;
-      while vCurNode.Level >= iTopLevel do
-      begin
-        Result := vCurNode.Rec.ValueByName('Name').AsString + ';' + Result;
-        vCurNode := vCurNode.Parent;
-      end;
-    end
-    else
-      Result := GetNameByLevel(ANode, 3);
-  end;
-
-  function GetNameUnit(ANode: TsdIDTreeNode): string;
-  begin
-    Result := ANode.Rec.ValueByName('Name').AsString;
-  end;
-
-  function GetDrawingCode(ANode: TsdIDTreeNode): string;
-  begin
-    Result := '';
-    if not Assigned(ANode) then Exit;
-    Result := ANode.Rec.ValueByName('DrawingCode').AsString;
-    if Result = '' then
-      Result := GetDrawingCode(ANode.Parent);
-  end;
-
-  function GetPosition(ANode, APegNode: TsdIDTreeNode): string;
-  begin
-    // 如果计量单元节点的名称为桩号(转化为判断计量单元节点与桩号节点为同一个)
-    if not Assigned(APegNode) or (ANode.ID = APegNode.ID) then
-      // 取分部工程
-      Result := GetNameFenXiang(ANode, APegNode)
-    // 反之,取分项工程+计量单元
-    else
-      Result := GetNameFenXiang(ANode, APegNode) + GetNameUnit(ANode);
-  end;
-
-begin
-  Result := TXmjNode.Create;
-  FXmjList.Add(Result);
-  Result.FCode := ANode.Rec.ValueByName('Code').AsString;
-  Result.FName := ANode.Rec.ValueByName('Name').AsString;
-  Result.FUnits := ANode.Rec.ValueByName('Units').AsString;
-  Result.FPeg := GetPegName(APeg);
-  Result.FNameDanWei := GetNameDanWei(ANode);
-  Result.FNameFenBu := GetNameFenBu(ANode, APeg);
-  Result.FNameFenXiang := GetNameFenXiang(ANode, APeg);
-  Result.FNameUnit := GetNameUnit(ANode);
-  Result.FPosition := GetPosition(ANode, APeg);
-  Result.FDrawingCode := GetDrawingCode(ANode);
-end;
-
 { TrmGclBillsData }
 
-procedure TrmGcl_XmjBillsData.AddRelaLeafXmj(AGclNode: TGclNode;
-  ARec: TsdDataRecord);
-
-  function GetFirstXmjParent(AID: Integer): TsdIDTreeNode;
-  begin
-    with TProjectData(FProjectData).BillsCompileData do
-      Result := BillsCompileTree.FindNode(AID);
-    while Assigned(Result) and (Result.Rec.ValueByName('B_Code').AsString <> '') do
-      Result := Result.Parent;
-  end;
-
-  function GetPegNode(ANode: TsdIDTreeNode): TsdIDTreeNode;
-  begin
-    Result := nil;
-    if not Assigned(ANode) then Exit;
-    if CheckPeg(ANode.Rec.ValueByName('Name').AsString) then
-      Result := ANode
-    else
-      Result := GetPegNode(ANode.Parent);
-  end;
-
-var
-  vNode, vPeg: TsdIDTreeNode;
-  XmjNode: TXmjNode;
-begin
-  vNode := GetFirstXmjParent(ARec.ValueByName('ID').AsInteger);
-  if not Assigned(vNode) then Exit;
-
-  vPeg := GetPegNode(vNode);
-  XmjNode := AGclNode.AddXmjNode(vNode, vPeg);
-
-  XmjNode.FOrgQuantity := XmjNode.FOrgQuantity + ARec.ValueByName('OrgQuantity').AsFloat;
-  XmjNode.FOrgTotalPrice := XmjNode.FOrgTotalPrice + ARec.ValueByName('OrgTotalPrice').AsFloat;
-  XmjNode.FMisQuantity := XmjNode.FMisQuantity + ARec.ValueByName('MisQuantity').AsFloat;
-  XmjNode.FMisTotalPrice := XmjNode.FMisTotalPrice + ARec.ValueByName('MisTotalPrice').AsFloat;
-  XmjNode.FOthQuantity := XmjNode.FOthQuantity + ARec.ValueByName('OthQuantity').AsFloat;
-  XmjNode.FOthTotalPrice := XmjNode.FOthTotalPrice + ARec.ValueByName('OthTotalPrice').AsFloat;
-
-  XmjNode.FQuantity := XmjNode.FQuantity + ARec.ValueByName('Quantity').AsFloat;
-  XmjNode.FTotalPrice := XmjNode.FTotalPrice + ARec.ValueByName('TotalPrice').AsFloat;
-end;
-
 procedure TrmGcl_XmjBillsData.AfterOperation;
 begin
-  ClearObjects(FGclList);
-  FGclList.Free;
   if FGXType = gxtWithoutXmj then
   begin
     cdsGcl.Filter := 'B_Code <> ''''';
@@ -369,13 +99,11 @@ end;
 function TrmGcl_XmjBillsData.AssignData(
   AProjectData: TProjectData; AGXType: TGXType): TDataSet;
 begin
+  FProjectData := AProjectData;
   FGXType := AGXType;
   BeforeOperation;
   try
-    FProjectData := AProjectData;
-    FilterBills(AProjectData.BillsCompileData.BillsCompileTree.FirstNode);
-    FilterDealBills;
-    WriteData;
+    GatherData;
   finally
     AfterOperation;
     Result := cdsGcl;
@@ -384,154 +112,82 @@ end;
 
 procedure TrmGcl_XmjBillsData.BeforeOperation;
 begin
-  FGclList := TList.Create;
   cdsGcl.Active := True;
   cdsGcl.Filtered := False;
   cdsGcl.EmptyDataSet;
 end;
 
-procedure TrmGcl_XmjBillsData.FilterBills(ANode: TsdIDTreeNode);
-begin
-  if not Assigned(ANode) then Exit;
-  if ANode.HasChildren then
-    FilterBills(ANode.FirstChild)
-  else
-    FilterGclBills(ANode);
-  FilterBills(ANode.NextSibling);
-end;
-
-procedure TrmGcl_XmjBillsData.FilterDealBills;
+procedure TrmGcl_XmjBillsData.GatherData;
 var
-  iIndex: Integer;
-  Rec: TsdDataRecord;
-  GclNode: TGclNode;
+  vGather: TGclGatherModel;
 begin
-  with FProjectData.DealBillsData do
-    for iIndex := 0 to sddDealBills.RecordCount - 1 do
-    begin
-      Rec := sddDealBills.Records[iIndex];
-      GclNode := GetGclNode(Rec);
-      GclNode.FDealQuantity := GclNode.FDealQuantity + Rec.ValueByName('Quantity').AsFloat;
-      GclNode.FDealTotalPrice := GclNode.FDealTotalPrice + Rec.ValueByName('TotalPrice').AsFloat;
-    end;
-end;
-
-procedure TrmGcl_XmjBillsData.FilterGclBills(ANode: TsdIDTreeNode);
-var
-  Rec: TsdDataRecord;
-  GclNode: TGclNode;
-begin
-  if not Assigned(ANode) then Exit;
-  Rec := ANode.Rec;
-  if Rec.ValueByName('B_Code').AsString = '' then Exit;
-
-  GclNode := GetGclNode(Rec);
-
-  GclNode.FOrgQuantity := GclNode.FOrgQuantity + Rec.ValueByName('OrgQuantity').AsFloat;
-  GclNode.FOrgTotalPrice := GclNode.FOrgTotalPrice + Rec.ValueByName('OrgTotalPrice').AsFloat;
-  GclNode.FMisQuantity := GclNode.FMisQuantity + Rec.ValueByName('MisQuantity').AsFloat;
-  GclNode.FMisTotalPrice := GclNode.FMisTotalPrice + Rec.ValueByName('MisTotalPrice').AsFloat;
-  GclNode.FOthQuantity := GclNode.FOthQuantity + Rec.ValueByName('OthQuantity').AsFloat;
-  GclNode.FOthTotalPrice := GclNode.FOthTotalPrice + Rec.ValueByName('OthTotalPrice').AsFloat;
-
-  GclNode.FQuantity := GclNode.FQuantity + Rec.ValueByName('Quantity').AsFloat;
-  GclNode.FTotalPrice := GclNode.FTotalPrice + Rec.ValueByName('TotalPrice').AsFloat;
-  AddRelaLeafXmj(GclNode, Rec);
-end;
-
-function TrmGcl_XmjBillsData.GetGclNode(ARec: TsdDataRecord): TGclNode;
-
-  function CreateGclNode: TGclNode;
-  begin
-    Result := TGclNode.Create;
-    FGclList.Add(Result);
-    Result.FB_Code := ARec.ValueByName('B_Code').AsString;
-    Result.FIndexCode := B_CodeToIndexCode(ARec.ValueByName('B_Code').AsString);
-    Result.FName := Trim(ARec.ValueByName('Name').AsString);
-    Result.FUnits := ARec.ValueByName('Units').AsString;
-    Result.FPrice := ARec.ValueByName('Price').AsFloat;
-    if Assigned(ARec.ValueByName('NewPrice')) then
-      Result.FNewPrice := ARec.ValueByName('NewPrice').AsFloat
-    else
-      Result.FNewPrice := 0;
-  end;
-
-var
-  I: Integer;
-  GclNode: TGclNode;
-begin
-  Result := nil;
-  for I := 0 to FGclList.Count - 1 do
-  begin
-    GclNode := TGclNode(FGclList.Items[I]);
-    if SameText(GclNode.FB_Code, ARec.ValueByName('B_Code').AsString) and
-        SameText(GclNode.FName, Trim(ARec.ValueByName('Name').AsString)) and
-        SameText(GclNode.FUnits, ARec.ValueByName('Units').AsString) and
-        (GclNode.FPrice = ARec.ValueByName('Price').AsFloat) then
-    begin
-      Result := GclNode;
-      Break;
-    end;
+  vGather := TGclGatherModel.Create(FProjectData);
+  try
+    vGather.GatherDeal := True;
+    vGather.WriteGatherData := WriteData;
+    vGather.Execute;
+  finally
+    vGather.Free;
   end;
-  if not Assigned(Result) then
-    Result := CreateGclNode;
 end;
 
-procedure TrmGcl_XmjBillsData.WriteData;
+procedure TrmGcl_XmjBillsData.WriteData(AGcls: TList);
 begin
   case FGXType of
-    gxtTopGcl, gxtWithoutXmj: WriteTopGclTypeData;
-    gxtFlowGcl: WriteFlowGclTypeData;
+    gxtTopGcl, gxtWithoutXmj: WriteTopGclTypeData(AGcls);
+    gxtFlowGcl: WriteFlowGclTypeData(AGcls);
   end;
 end;
 
 procedure TrmGcl_XmjBillsData.WriteFlowGclNode(AGclNode: TGclNode);
 var
   i: Integer;
-  XmjNode: TXmjNode;
+  DetailGcl: TDetailGclNode;
 begin
-  for i := 0 to AGclNode.XmjCount - 1 do
+  for i := 0 to AGclNode.DetailGclCount - 1 do
   begin
-    XmjNode := AGclNode.XmjNode[i];
+    DetailGcl := AGclNode.DetailGcl[i];
     cdsGcl.Append;
-    cdsGclIndexCode.AsString := AGclNode.FIndexCode;
+    cdsGclIndexCode.AsString := AGclNode.IndexCode;
     cdsGclIndexID.AsInteger := i+1;
 
-    cdsGclB_Code.AsString := AGclNode.FB_Code;
-    cdsGclName.AsString := AGclNode.FName;
-    cdsGclUnits.AsString := AGclNode.FUnits;
-    cdsGclPrice.AsFloat := AGclNode.FPrice;
-    cdsGclNewPrice.AsFloat := AGclNode.FNewPrice;
-
-    cdsGclCode.AsString := XmjNode.FCode;
-    cdsGclPeg.AsString := XmjNode.FPeg;
-    cdsGclNameDanWei.AsString := XmjNode.FNameDanWei;
-    cdsGclNameFenBu.AsString := XmjNode.FNameFenBu;
-    cdsGclNameFenXiang.AsString := XmjNode.FNameFenXiang;
-    cdsGclNameUnit.AsString := XmjNode.FNameUnit;
-    cdsGclDrawingCode.AsString := XmjNode.FDrawingCode;
-    cdsGclPosition.AsString := XmjNode.FPosition;
-
-    cdsGclOrgQuantity.AsFloat := XmjNode.FOrgQuantity;
-    cdsGclOrgTotalPrice.AsFloat := XmjNode.FOrgTotalPrice;
-    cdsGclMisQuantity.AsFloat := XmjNode.FMisQuantity;
-    cdsGclMisTotalPrice.AsFloat := XmjNode.FMisTotalPrice;
-    cdsGclOthQuantity.AsFloat := XmjNode.FOthQuantity;
-    cdsGclOthTotalPrice.AsFloat := XmjNode.FOthTotalPrice;
-
-    cdsGclQuantity.AsFloat := XmjNode.FQuantity;
-    cdsGclTotalPrice.AsFloat := XmjNode.FTotalPrice;
+    cdsGclB_Code.AsString := AGclNode.B_Code;
+    cdsGclName.AsString := AGclNode.Name;
+    cdsGclUnits.AsString := AGclNode.Units;
+    cdsGclPrice.AsFloat := AGclNode.Price;
+
+    if Assigned(DetailGcl.LeafXmj) then
+    begin
+      cdsGclCode.AsString := DetailGcl.LeafXmj.XmjCode;
+      cdsGclPeg.AsString := DetailGcl.LeafXmj.Peg;
+      cdsGclNameDanWei.AsString := DetailGcl.LeafXmj.NameDanWei;
+      cdsGclNameFenBu.AsString := DetailGcl.LeafXmj.NameFenBu;
+      cdsGclNameFenXiang.AsString := DetailGcl.LeafXmj.NameFenXiang;
+      cdsGclNameUnit.AsString := DetailGcl.LeafXmj.NameUnit;
+      cdsGclDrawingCode.AsString := DetailGcl.LeafXmj.DrawingCode;
+      cdsGclPosition.AsString := DetailGcl.LeafXmj.Position;
+    end;
+
+    cdsGclOrgQuantity.AsFloat := DetailGcl.OrgQuantity;
+    cdsGclOrgTotalPrice.AsFloat := DetailGcl.OrgTotalPrice;
+    cdsGclMisQuantity.AsFloat := DetailGcl.MisQuantity;
+    cdsGclMisTotalPrice.AsFloat := DetailGcl.MisTotalPrice;
+    cdsGclOthQuantity.AsFloat := DetailGcl.OthQuantity;
+    cdsGclOthTotalPrice.AsFloat := DetailGcl.OthTotalPrice;
+
+    cdsGclQuantity.AsFloat := DetailGcl.Quantity;
+    cdsGclTotalPrice.AsFloat := DetailGcl.TotalPrice;
     cdsGcl.Post;
   end;
 end;
 
-procedure TrmGcl_XmjBillsData.WriteFlowGclTypeData;
+procedure TrmGcl_XmjBillsData.WriteFlowGclTypeData(AGcls: TList);
 var
   i: Integer;
 begin
   FIndex := 0;
-  for i := 0 to FGclList.Count - 1 do
-    WriteFlowGclNode(TGclNode(FGclList.Items[i]));
+  for i := 0 to AGcls.Count - 1 do
+    WriteFlowGclNode(TGclNode(AGcls.Items[i]));
 end;
 
 procedure TrmGcl_XmjBillsData.WriteGclNode(
@@ -540,72 +196,74 @@ var
   i: Integer;
 begin
   cdsGcl.Append;
-  cdsGclIndexCode.AsString := AGclNode.FIndexCode;
+  cdsGclIndexCode.AsString := AGclNode.IndexCode;
   cdsGclIndexID.AsInteger := 0;
 
-  cdsGclB_Code.AsString := AGclNode.FB_Code;
-  cdsGclName.AsString := AGclNode.FName;
-  cdsGclUnits.AsString := AGclNode.FUnits;
-
-  cdsGclPrice.AsFloat := AGclNode.FPrice;
-  cdsGclNewPrice.AsFloat := AGclNode.FNewPrice;
-
-  cdsGclQuantity.AsFloat := AGclNode.FQuantity;
-  cdsGclTotalPrice.AsFloat := AGclNode.FTotalPrice;
-  cdsGclDealQuantity.AsFloat := AGclNode.FDealQuantity;
-  cdsGclDealTotalPrice.AsFloat := AGclNode.FDealTotalPrice;
-  cdsGclDifferQuantity.AsFloat := AGclNode.FDealQuantity - AGclNode.FQuantity;
-  cdsGclDifferTotalPrice.AsFloat := AGclNode.FDealTotalPrice - AGclNode.FTotalPrice;
-
-  cdsGclOrgQuantity.AsFloat := AGclNode.FOrgQuantity;
-  cdsGclOrgTotalPrice.AsFloat := AGclNode.FOrgTotalPrice;
-  cdsGclMisQuantity.AsFloat := AGclNode.FMisQuantity;
-  cdsGclMisTotalPrice.AsFloat := AGclNode.FMisTotalPrice;
-  cdsGclOthQuantity.AsFloat := AGclNode.FOthQuantity;
-  cdsGclOthTotalPrice.AsFloat := AGclNode.FOthTotalPrice;
+  cdsGclB_Code.AsString := AGclNode.B_Code;
+  cdsGclName.AsString := AGclNode.Name;
+  cdsGclUnits.AsString := AGclNode.Units;
+  cdsGclPrice.AsFloat := AGclNode.Price;
+
+  cdsGclQuantity.AsFloat := AGclNode.Quantity;
+  cdsGclTotalPrice.AsFloat := AGclNode.TotalPrice;
+  cdsGclDealQuantity.AsFloat := AGclNode.DealQuantity;
+  cdsGclDealTotalPrice.AsFloat := AGclNode.DealTotalPrice;
+  cdsGclDifferQuantity.AsFloat := AGclNode.DealQuantity - AGclNode.Quantity;
+  cdsGclDifferTotalPrice.AsFloat := AGclNode.DealTotalPrice - AGclNode.TotalPrice;
+
+  cdsGclOrgQuantity.AsFloat := AGclNode.OrgQuantity;
+  cdsGclOrgTotalPrice.AsFloat := AGclNode.OrgTotalPrice;
+  cdsGclMisQuantity.AsFloat := AGclNode.MisQuantity;
+  cdsGclMisTotalPrice.AsFloat := AGclNode.MisTotalPrice;
+  cdsGclOthQuantity.AsFloat := AGclNode.OthQuantity;
+  cdsGclOthTotalPrice.AsFloat := AGclNode.OthTotalPrice;
   cdsGcl.Post;
   WriteXmjNode(AGclNode);
 end;
 
-procedure TrmGcl_XmjBillsData.WriteTopGclTypeData;
+procedure TrmGcl_XmjBillsData.WriteTopGclTypeData(AGcls: TList);
 var
   i: Integer;
 begin
   FIndex := 0;
-  for i := 0 to FGclList.Count - 1 do
-    WriteGclNode(TGclNode(FGclList.Items[i]));
+  for i := 0 to AGcls.Count - 1 do
+    WriteGclNode(TGclNode(AGcls.Items[i]));
 end;
 
 procedure TrmGcl_XmjBillsData.WriteXmjNode(
   AGclNode: TGclNode);
 var
   i: Integer;
-  XmjNode: TXmjNode;
+  DetailGcl: TDetailGclNode;
 begin
-  for i := 0 to AGclNode.XmjCount - 1 do
+  for i := 0 to AGclNode.DetailGclCount - 1 do
   begin
-    XmjNode := AGclNode.XmjNode[i];
+    DetailGcl := AGclNode.DetailGcl[i];
     cdsGcl.Append;
-    cdsGclIndexCode.AsString := AGclNode.FIndexCode;
+    cdsGclIndexCode.AsString := AGclNode.IndexCode;
     cdsGclIndexID.AsInteger := FIndex;
-    cdsGclCode.AsString := XmjNode.FCode;
-    cdsGclPeg.AsString := XmjNode.FPeg;
-    cdsGclNameDanWei.AsString := XmjNode.FNameDanWei;
-    cdsGclNameFenBu.AsString := XmjNode.FNameFenBu;
-    cdsGclNameFenXiang.AsString := XmjNode.FNameFenXiang;
-    cdsGclNameUnit.AsString := XmjNode.FNameUnit;
-    cdsGclPosition.AsString := XmjNode.FPosition;
-    cdsGclDrawingCode.AsString := XmjNode.FDrawingCode;
-
-    cdsGclOrgQuantity.AsFloat := XmjNode.FOrgQuantity;
-    cdsGclOrgTotalPrice.AsFloat := XmjNode.FOrgTotalPrice;
-    cdsGclMisQuantity.AsFloat := XmjNode.FMisQuantity;
-    cdsGclMisTotalPrice.AsFloat := XmjNode.FMisTotalPrice;
-    cdsGclOthQuantity.AsFloat := XmjNode.FOthQuantity;
-    cdsGclOthTotalPrice.AsFloat := XmjNode.FOthTotalPrice;
-
-    cdsGclQuantity.AsFloat := XmjNode.FQuantity;
-    cdsGclTotalPrice.AsFloat := XmjNode.FTotalPrice;
+
+    if Assigned(DetailGcl.LeafXmj) then
+    begin
+      cdsGclCode.AsString := DetailGcl.LeafXmj.XmjCode;
+      cdsGclPeg.AsString := DetailGcl.LeafXmj.Peg;
+      cdsGclNameDanWei.AsString := DetailGcl.LeafXmj.NameDanWei;
+      cdsGclNameFenBu.AsString := DetailGcl.LeafXmj.NameFenBu;
+      cdsGclNameFenXiang.AsString := DetailGcl.LeafXmj.NameFenXiang;
+      cdsGclNameUnit.AsString := DetailGcl.LeafXmj.NameUnit;
+      cdsGclPosition.AsString := DetailGcl.LeafXmj.Position;
+      cdsGclDrawingCode.AsString := DetailGcl.LeafXmj.DrawingCode;
+    end;
+
+    cdsGclOrgQuantity.AsFloat := DetailGcl.OrgQuantity;
+    cdsGclOrgTotalPrice.AsFloat := DetailGcl.OrgTotalPrice;
+    cdsGclMisQuantity.AsFloat := DetailGcl.MisQuantity;
+    cdsGclMisTotalPrice.AsFloat := DetailGcl.MisTotalPrice;
+    cdsGclOthQuantity.AsFloat := DetailGcl.OthQuantity;
+    cdsGclOthTotalPrice.AsFloat := DetailGcl.OthTotalPrice;
+
+    cdsGclQuantity.AsFloat := DetailGcl.Quantity;
+    cdsGclTotalPrice.AsFloat := DetailGcl.TotalPrice;
     cdsGcl.Post;
     Inc(FIndex);
   end;

+ 1 - 1
Forms/ReportsFrm.dfm

@@ -61,7 +61,7 @@ object ReportsForm: TReportsForm
     Width = 223
     Height = 25
     BevelInner = bvLowered
-    TabOrder = 4
+    TabOrder = 3
     object chkExcelMode: TCheckBox
       Left = 6
       Top = 4

+ 1 - 0
Forms/ReportsFrm.pas

@@ -180,6 +180,7 @@ begin
     ReportsForm.ShowModal;
   finally
     ReportsForm.Free;
+    AProjectData.ClearReportCacheData;
   end;
 end;
 

+ 4 - 0
Frames/BillsGatherFme.dfm

@@ -92,6 +92,8 @@ object BillsGatherFrame: TBillsGatherFrame
           Top = 0
           Caption = ' '#30456#20851#31614#32422#28165#21333' '
           ImageIndex = 1
+          Style = tbsCheck
+          OnClick = tobtnDetailGclClick
         end
         object tobtnDetailBGL: TToolButton
           Tag = 2
@@ -99,6 +101,8 @@ object BillsGatherFrame: TBillsGatherFrame
           Top = 0
           Caption = #30456#20851#21464#26356#28165#21333
           ImageIndex = 2
+          Style = tbsCheck
+          OnClick = tobtnDetailGclClick
         end
       end
     end

+ 195 - 61
Units/GclBillsGatherModel.pas

@@ -9,13 +9,9 @@ uses
 type
   TGatherDataWriteEvent = procedure (AGLJs: TList) of object;
 
-  TDetailGclNode = class
+  TLeafXmjNode = class
   private
     FID: Integer;
-    FBillsID: Integer;
-    FTreeSerialNo: Integer;
-
-    FLeafXmjID: Integer;
     FXmjCode: string;
     FXmjName: string;
     FXmjUnits: string;
@@ -26,6 +22,34 @@ type
     FNameUnit: string;
     FPosition: string;
     FDrawingCode: string;
+  public
+    constructor Create(ALeafXmj, APeg: TBillsIDTreeNode);
+
+    property ID: Integer read FID;
+    property XmjCode: string read FXmjCode;
+    property XmjName: string read FXmjName;
+    property XmjUnits: string read FXmjUnits;
+    property Peg: string read FPeg;
+    property NameDanWei: string read FNameDanWei;
+    property NameFenBu: string read FNameFenBu;
+    property NameFenXiang: string read FNameFenXiang;
+    property NameUnit: string read FNameUnit;
+    property Position: string read FPosition;
+    property DrawingCode: string read FDrawingCode;
+  end;
+
+  TDetailGclNode = class
+  private
+    FID: Integer;
+    FBillsID: Integer;
+    FTreeSerialNo: Integer;
+
+    FOrgQuantity: Double;
+    FOrgTotalPrice: Double;
+    FMisQuantity: Double;
+    FMisTotalPrice: Double;
+    FOthQuantity: Double;
+    FOthTotalPrice: Double;
 
     FQuantity: Double;
     FTotalPrice: Double;
@@ -60,26 +84,21 @@ type
 
     FPM_PreTotalPrice: Double;
     FPM_TotalPrice: Double;
+
+    FLeafXmj: TLeafXmjNode;
   public
     constructor Create(AID: Integer);
 
-    procedure AddPosData(ALeafXmj, APeg: TBillsIDTreeNode);
-
     property ID: Integer read FID;
     property BillsID: Integer read FBillsID write FBillsID;
     property TreeSerialNo: Integer read FTreeSerialNo write FTreeSerialNo;
 
-    property LeafXmjID: Integer read FLeafXmjID;
-    property XmjCode: string read FXmjCode;
-    property XmjName: string read FXmjName;
-    property XmjUnits: string read FXmjUnits;
-    property Peg: string read FPeg;
-    property NameDanWei: string read FNameDanWei;
-    property NameFenBu: string read FNameFenBu;
-    property NameFenXiang: string read FNameFenXiang;
-    property NameUnit: string read FNameUnit;
-    property Position: string read FPosition;
-    property DrawingCode: string read FDrawingCode;
+    property OrgQuantity: Double read FOrgQuantity write FOrgQuantity;
+    property OrgTotalPrice: Double read FOrgTotalPrice write FOrgTotalPrice;
+    property MisQuantity: Double read FMisQuantity write FMisQuantity;
+    property MisTotalPrice: Double read FMisTotalPrice write FMisTotalPrice;
+    property OthQuantity: Double read FOthQuantity write FOthQuantity;
+    property OthTotalPrice: Double read FOthTotalPrice write FOthTotalPrice;
 
     property Quantity: Double read FQuantity write FQuantity;
     property TotalPrice: Double read FTotalPrice write FTotalPrice;
@@ -114,6 +133,8 @@ type
 
     property PM_PreTotalPrice: Double read FPM_PreTotalPrice write FPM_PreTotalPrice;
     property PM_TotalPrice: Double read FPM_TotalPrice write FPM_TotalPrice;
+
+    property LeafXmj: TLeafXmjNode read FLeafXmj write FLeafXmj;
   end;
 
   TDetailDealNode = class
@@ -167,6 +188,7 @@ type
     FDetailGcls: TList;
     FDetailDeals: TList;
     FDetailBGLs: TList;
+    FLeafXmjs: TList;
 
     FID: Integer;
 
@@ -176,6 +198,13 @@ type
     FUnits: string;
     FPrice: Double;
 
+    FOrgQuantity: Double;
+    FOrgTotalPrice: Double;
+    FMisQuantity: Double;
+    FMisTotalPrice: Double;
+    FOthQuantity: Double;
+    FOthTotalPrice: Double;
+
     FQuantity: Double;
     FTotalPrice: Double;
 
@@ -230,10 +259,13 @@ type
     function GetDetailDealCount: Integer;
     function GetDetailGcl(AIndex: Integer): TDetailGclNode;
     function GetDetailGclCount: Integer;
+    function GetLeafXmjCount: Integer;
+    function GetLeafXmj(AIndex: Integer): TLeafXmjNode;
   public
     constructor Create(AID: Integer);
     destructor Destroy; override;
 
+    procedure AddLeafXmj(ALeafXmj: TLeafXmjNode);
     function AddDetailGcl(AID: Integer): TDetailGclNode;
     function AddDetailDeal(AID: Integer): TDetailDealNode;
     function AddDetailBGL(AID: Integer): TDetailBGLNode;
@@ -248,6 +280,13 @@ type
     property Units: string read FUnits write FUnits;
     property Price: Double read FPrice write FPrice;
 
+    property OrgQuantity: Double read FOrgQuantity;
+    property OrgTotalPrice: Double read FOrgTotalPrice;
+    property MisQuantity: Double read FMisQuantity;
+    property MisTotalPrice: Double read FMisTotalPrice;
+    property OthQuantity: Double read FOthQuantity;
+    property OthTotalPrice: Double read FOthTotalPrice;
+
     property Quantity: Double read FQuantity;
     property TotalPrice: Double read FTotalPrice;
 
@@ -293,6 +332,8 @@ type
 
     property DetailGclCount: Integer read GetDetailGclCount;
     property DetailGcl[AIndex: Integer]: TDetailGclNode read GetDetailGcl;
+    property LeafXmjCount: Integer read GetLeafXmjCount;
+    property LeafXmj[AIndex: Integer]: TLeafXmjNode read GetLeafXmj;
 
     property DetailDealCount: Integer read GetDetailDealCount;
     property DetailDeal[AIndex: Integer]: TDetailDealNode read GetDetailDeal;
@@ -305,10 +346,12 @@ type
   private
     FProjectData: TObject;
     FBillsTree: TBillsIDTree;
+    FMergeDetailGcl: Boolean;
     FGatherDeal: Boolean;
     FGatherBGL: Boolean;
 
     FGcls: TList;
+    FXmjs: TList;
     FNewGclID: Integer;
     FNewDetailGclID: Integer;
     FNewDetailDealID: Integer;
@@ -319,6 +362,10 @@ type
     procedure BeginGather;
     procedure EndGather;
 
+    function FindLeafXmj(ALeafXmj: TBillsIDTreeNode): TLeafXmjNode;
+    function NewLeafXmj(ALeafXmj: TBillsIDTreeNode): TLeafXmjNode;
+    function GetLeafXmj(ANode: TBillsIDTreeNode): TLeafXmjNode;
+
     function FindGclNode(const AB_Code, AName, AUnits: string; APrice: Double): TGclNode;
     function NewGclNode(const AB_Code, AName, AUnits: string; APrice: Double): TGclNode;
     function GetGclNode(const AB_Code, AName, AUnits: string; APrice: Double): TGclNode; overload;
@@ -360,34 +407,23 @@ uses
 { TGclGatherModel }
 
 procedure TGclGatherModel.AddBillsNode(ANode: TBillsIDTreeNode);
-
-  function GetFirstXmjParent: TBillsIDTreeNode;
-  begin
-    Result := ANode;
-    while Assigned(Result) and (Result.Rec.B_Code.AsString <> '') do
-      Result := TBillsIDTreeNode(Result.Parent);
-  end;
-
-  function GetPegNode(ALeafXmj: TBillsIDTreeNode): TBillsIDTreeNode;
-  begin
-    Result := nil;
-    if not Assigned(ALeafXmj) then Exit;
-    if CheckPeg(ALeafXmj.Rec.Name.AsString) then
-      Result := ANode
-    else
-      Result := GetPegNode(TBillsIDTreeNode(ALeafXmj.Parent));
-  end;
-
 var
   vGclNode: TGclNode;
   vDetailGclNode: TDetailGclNode;
-  vLeafXmj, vPeg: TBillsIDTreeNode;
+  vLeafXmj: TLeafXmjNode;
 begin
   vGclNode := GetGclNode(ANode.Rec);
   vDetailGclNode := vGclNode.AddDetailGcl(NewDetailGclID);
   vDetailGclNode.BillsID := ANode.ID;
   vDetailGclNode.TreeSerialNo := ANode.MajorIndex;
 
+  vDetailGclNode.OrgQuantity := ANode.Rec.OrgQuantity.AsFloat;
+  vDetailGclNode.OrgTotalPrice := ANode.Rec.OrgTotalPrice.AsFloat;
+  vDetailGclNode.MisQuantity := ANode.Rec.MisQuantity.AsFloat;
+  vDetailGclNode.MisTotalPrice := ANode.Rec.MisTotalPrice.AsFloat;
+  vDetailGclNode.OthQuantity := ANode.Rec.OthQuantity.AsFloat;
+  vDetailGclNode.OthTotalPrice := ANode.Rec.OthTotalPrice.AsFloat;
+
   vDetailGclNode.Quantity := ANode.Rec.Quantity.AsFloat;
   vDetailGclNode.TotalPrice := ANode.Rec.TotalPrice.AsFloat;
 
@@ -425,14 +461,14 @@ begin
   vDetailGclNode.AddGatherQuantity := ANode.Rec.AddGatherQuantity.AsFloat;
   vDetailGclNode.AddGatherTotalPrice := ANode.Rec.AddGatherTotalPrice.AsFloat;
 
-  vLeafXmj := GetFirstXmjParent;
-  vPeg := GetPegNode(vLeafXmj);
-  vDetailGclNode.AddPosData(vLeafXmj, vPeg);
+  vDetailGclNode.LeafXmj := GetLeafXmj(ANode);
+  vGclNode.AddLeafXmj(vDetailGclNode.LeafXmj);
 end;
 
 procedure TGclGatherModel.BeginGather;
 begin
   FGcls := TList.Create;
+  FXmjs := TList.Create;
 end;
 
 procedure TGclGatherModel.CalculateAll;
@@ -458,6 +494,8 @@ end;
 
 procedure TGclGatherModel.EndGather;
 begin
+  ClearObjects(FXmjs);
+  FXmjs.Free;
   ClearObjects(FGcls);
   FGcls.Free;
 end;
@@ -498,6 +536,24 @@ begin
   end;
 end;
 
+function TGclGatherModel.FindLeafXmj(
+  ALeafXmj: TBillsIDTreeNode): TLeafXmjNode;
+var
+  iXmj: Integer;
+  vLeafXmj: TLeafXmjNode;
+begin
+  Result := nil;
+  for iXmj := 0 to FXmjs.Count - 1 do
+  begin
+    vLeafXmj := TLeafXmjNode(FXmjs.Items[iXmj]);
+    if vLeafXmj.ID = ALeafXmj.ID then
+    begin
+      Result := vLeafXmj;
+      Break;
+    end;
+  end;
+end;
+
 procedure TGclGatherModel.GatherBGLData;
 var
   vGclNode: TGclNode;
@@ -525,6 +581,7 @@ begin
         DetailBGL.Quantity := cdsBGBillsQuantity.AsFloat;
         DetailBGL.TotalPrice := cdsBGBillsTotalPrice.AsFloat;
       end;
+      cdsBGBills.Next;
     end;
   end;
 end;
@@ -578,6 +635,28 @@ begin
     Result := NewGclNode(AB_Code, AName, AUnits, APrice);
 end;
 
+function TGclGatherModel.GetLeafXmj(
+  ANode: TBillsIDTreeNode): TLeafXmjNode;
+
+  function GetFirstXmjParent: TBillsIDTreeNode;
+  begin
+    Result := ANode;
+    while Assigned(Result) and (Result.Rec.B_Code.AsString <> '') do
+      Result := TBillsIDTreeNode(Result.Parent);  
+  end;
+
+var
+  vFirstXmjParent: TBillsIDTreeNode;
+begin
+  vFirstXmjParent := GetFirstXmjParent;
+  Result := nil;
+  if not Assigned(vFirstXmjParent) then Exit;
+
+  Result := FindLeafXmj(vFirstXmjParent);
+  if not Assigned(Result) then
+    Result := NewLeafXmj(vFirstXmjParent);
+end;
+
 function TGclGatherModel.GetNewDetailBGLID: Integer;
 begin
   Result := FNewDetailBGLID;
@@ -608,6 +687,27 @@ begin
   Inc(FNewGclID);
 end;
 
+function TGclGatherModel.NewLeafXmj(
+  ALeafXmj: TBillsIDTreeNode): TLeafXmjNode;
+
+  function GetPegNode(ANode: TBillsIDTreeNode): TBillsIDTreeNode;
+  begin
+    Result := nil;
+    if not Assigned(ANode) then Exit;
+    if CheckPeg(ANode.Rec.Name.AsString) then
+      Result := ANode
+    else
+      Result := GetPegNode(TBillsIDTreeNode(ANode.Parent));
+  end;
+
+var
+  vPeg: TBillsIDTreeNode;
+begin
+  vPeg := GetPegNode(ALeafXmj);
+  Result := TLeafXmjNode.Create(ALeafXmj, vPeg);
+  FXmjs.Add(Result);
+end;
+
 { TGclNode }
 
 function TGclNode.AddDetailBGL(AID: Integer): TDetailBGLNode;
@@ -628,6 +728,12 @@ begin
   FDetailGcls.Add(Result);
 end;
 
+procedure TGclNode.AddLeafXmj(ALeafXmj: TLeafXmjNode);
+begin
+  if FLeafXmjs.IndexOf(ALeafXmj) = -1 then
+    FLeafXmjs.Add(ALeafXmj); 
+end;
+
 procedure TGclNode.Calculate;
 begin
   InitCalculate;
@@ -653,10 +759,12 @@ begin
   FDetailGcls := TList.Create;
   FDetailDeals := TList.Create;
   FDetailBGLs := TList.Create;
+  FLeafXmjs := TList.Create;
 end;
 
 destructor TGclNode.Destroy;
 begin
+  FLeafXmjs.Free;
   ClearObjects(FDetailBGLs);
   FDetailBGLs.Free;
   ClearObjects(FDetailDeals);
@@ -700,6 +808,13 @@ begin
   for iGcl := 0 to DetailGclCount - 1 do
   begin
     vDetailGcl := DetailGcl[iGcl];
+    FOrgQuantity := FOrgQuantity + vDetailGcl.OrgQuantity;
+    FOrgTotalPrice := FOrgTotalPrice + vDetailGcl.OrgTotalPrice;
+    FMisQuantity := FMisQuantity + vDetailGcl.MisQuantity;
+    FMisTotalPrice := FMisTotalPrice + vDetailGcl.MisTotalPrice;
+    FOthQuantity := FOthQuantity + vDetailGcl.OthQuantity;
+    FOthTotalPrice := FOthTotalPrice + vDetailGcl.OthTotalPrice;
+
     FQuantity := FQuantity + vDetailGcl.Quantity;
     FTotalPrice := FTotalPrice + vDetailGcl.TotalPrice;
 
@@ -763,8 +878,25 @@ begin
   Result := FDetailGcls.Count;
 end;
 
+function TGclNode.GetLeafXmj(AIndex: Integer): TLeafXmjNode;
+begin
+  Result := TLeafXmjNode(FLeafXmjs.Items[AIndex]);
+end;
+
+function TGclNode.GetLeafXmjCount: Integer;
+begin
+  Result := FLeafXmjs.Count;
+end;
+
 procedure TGclNode.InitCalculate;
 begin
+  FOrgQuantity := 0;
+  FOrgTotalPrice := 0;
+  FMisQuantity := 0;
+  FMisTotalPrice := 0;
+  FOthQuantity := 0;
+  FOthTotalPrice := 0;
+
   FQuantity := 0;
   FTotalPrice := 0;
 
@@ -815,7 +947,28 @@ end;
 
 { TDetailGclNode }
 
-procedure TDetailGclNode.AddPosData(ALeafXmj, APeg: TBillsIDTreeNode);
+constructor TDetailGclNode.Create(AID: Integer);
+begin
+  FID := AID;
+end;
+
+{ TDetailBGLNode }
+
+constructor TDetailBGLNode.Create(AID: Integer);
+begin
+  FID := AID;
+end;
+
+{ TDetailDealNode }
+
+constructor TDetailDealNode.Create(AID: Integer);
+begin
+  FID := AID;
+end;
+
+{ TLeafXmjNode }
+
+constructor TLeafXmjNode.Create(ALeafXmj, APeg: TBillsIDTreeNode);
 
   function GetPegName: string;
   begin
@@ -912,7 +1065,7 @@ procedure TDetailGclNode.AddPosData(ALeafXmj, APeg: TBillsIDTreeNode);
 begin
   if not Assigned(ALeafXmj) then Exit;
 
-  FLeafXmjID := ALeafXmj.ID;
+  FID := ALeafXmj.ID;
   FXmjCode := ALeafXmj.Rec.Code.AsString;
   FXmjName := ALeafXmj.Rec.Name.AsString;
   FXmjUnits := ALeafXmj.Rec.Units.AsString;
@@ -925,23 +1078,4 @@ begin
   FDrawingCode := GetDrawingCode(ALeafXmj);
 end;
 
-constructor TDetailGclNode.Create(AID: Integer);
-begin
-  FID := AID;
-end;
-
-{ TDetailBGLNode }
-
-constructor TDetailBGLNode.Create(AID: Integer);
-begin
-  FID := AID;
-end;
-
-{ TDetailDealNode }
-
-constructor TDetailDealNode.Create(AID: Integer);
-begin
-  FID := AID;
-end;
-
 end.

+ 26 - 25
Units/ProjectData.pas

@@ -160,6 +160,7 @@ type
 
     {For Reports: 复制当期的全部数据到项目数据中}
     procedure CopyPhaseData;
+    procedure ClearReportCacheData;
 
     procedure CalculateAll;
     procedure CalculatePriceMargin;
@@ -753,30 +754,6 @@ end;
 
 procedure TProjectData.CopyPhaseData;
 
-  procedure DeletePhaseTable;
-  var
-    FTableList: TStringList;
-    iIndex: Integer;
-    sDeleteTableSql: String;
-  begin
-    FTableList := TStringList.Create;
-    try
-      FConnection.Connection.GetTableNames(FTableList);
-      iIndex := 0;
-      while iIndex < FTableList.Count do
-      begin
-        if Pos('P_', FTableList.Strings[iIndex]) = 1 then
-        begin
-          sDeleteTableSql := Format('Drop Table %s', [FTableList.Strings[iIndex]]);
-          ExecuteSql(sDeleteTableSql);
-        end;
-        Inc(iIndex);
-      end;
-    finally
-      FTableList.Free;
-    end;
-  end;
-
   procedure CopyStageData(const AFileName, ASourceTable, AResultTable: string);
   const
     sCopySql = 'Select BillsID, DealQuantity, DealTotalPrice, QcQuantity, QcTotalPrice, QcBGLCode, QcBGLNum,' +
@@ -1031,7 +1008,7 @@ procedure TProjectData.CopyPhaseData;
 
 begin
   Save;
-  DeletePhaseTable;
+  ClearReportCacheData;
   CopyCacheReportsData;
   if FPhaseIndex > 0 then
     CopyCurPhaseData;
@@ -1691,4 +1668,28 @@ begin
   FProjectGLData.LoadStagePM_CalcData;
 end;
 
+procedure TProjectData.ClearReportCacheData;
+var
+  FTableList: TStringList;
+  iIndex: Integer;
+  sDeleteTableSql: String;
+begin
+  FTableList := TStringList.Create;
+  try
+    FConnection.Connection.GetTableNames(FTableList);
+    iIndex := 0;
+    while iIndex < FTableList.Count do
+    begin
+      if Pos('P_', FTableList.Strings[iIndex]) = 1 then
+      begin
+        sDeleteTableSql := Format('Drop Table %s', [FTableList.Strings[iIndex]]);
+        ExecuteSql(sDeleteTableSql);
+      end;
+      Inc(iIndex);
+    end;
+  finally
+    FTableList.Free;
+  end;
+end;
+
 end.