Browse Source

新增材料调差界面
1. 调差工料,可增删改工料机
2. 清单汇总,汇总分项清单中所有工程量清单,展示部分数据
3. 清单汇总--详细清单,可设置调差工料
4. 调差工料应用到相同清单
PS:以上全部功能,本次提交代码,无任何限制,为中途提交防止代码丢失

MaiXinRong 9 years ago
parent
commit
e6151d3acd

+ 47 - 0
DataModules/DetailGLDm.dfm

@@ -0,0 +1,47 @@
+object DetailGLData: TDetailGLData
+  OldCreateOrder = False
+  Left = 623
+  Top = 444
+  Height = 237
+  Width = 201
+  object sdpDetailGL: TsdADOProvider
+    TableName = 'DetailGL'
+    Left = 64
+    Top = 24
+  end
+  object sddDetailGL: TsdDataSet
+    Active = False
+    Provider = sdpDetailGL
+    Left = 64
+    Top = 80
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D65090001044E616D65060742696C6C734944094669656C644E616D
+      65060742696C6C7349440844617461547970650203084461746153697A650204
+      0549734B6579080F4E65656450726F636573734E616D65090001044E616D6506
+      04474C4944094669656C644E616D650604474C49440844617461547970650203
+      084461746153697A6502040549734B6579080F4E65656450726F636573734E61
+      6D65090001044E616D650604436F6465094669656C644E616D650604436F6465
+      0844617461547970650203084461746153697A6502040549734B6579080F4E65
+      656450726F636573734E616D65090001044E616D6506085175616E7469747909
+      4669656C644E616D6506085175616E7469747908446174615479706502060844
+      61746153697A6502080549734B6579080F4E65656450726F636573734E616D65
+      090001044E616D65060D43726561746550686173654944094669656C644E616D
+      65060D4372656174655068617365494408446174615479706502030844617461
+      53697A6502040549734B6579080F4E65656450726F636573734E616D65090001
+      044E616D65060D43726561746553746167654944094669656C644E616D65060D
+      437265617465537461676549440844617461547970650203084461746153697A
+      6502040549734B6579080F4E65656450726F636573734E616D65090001044E61
+      6D650610504D5F507265546F74616C5072696365094669656C644E616D650610
+      504D5F507265546F74616C507269636508446174615479706502060844617461
+      53697A6502080549734B6579080F4E65656450726F636573734E616D65090001
+      044E616D650610504D5F437572546F74616C5072696365094669656C644E616D
+      650610504D5F437572546F74616C507269636508446174615479706502060844
+      61746153697A6502080549734B6579080F4E65656450726F636573734E616D65
+      090001044E616D650610504D5F456E64546F74616C5072696365094669656C64
+      4E616D650610504D5F456E64546F74616C507269636508446174615479706502
+      06084461746153697A6502080549734B6579080F4E65656450726F636573734E
+      616D65090000}
+  end
+end

+ 181 - 0
DataModules/DetailGLDm.pas

@@ -0,0 +1,181 @@
+unit DetailGLDm;
+
+interface
+
+uses
+  SysUtils, Classes, sdDB, sdProvider, ADODB, Variants;
+
+type
+  TDetailGLData = class(TDataModule)
+    sdpDetailGL: TsdADOProvider;
+    sddDetailGL: TsdDataSet;
+  private
+    FProjectData: TObject;
+
+    function FindDetailGL(ABillsID, AGLID: Integer): TsdDataRecord;
+    procedure ClearDetailGLs(ABillsID: Integer);
+  public
+    constructor Create(AProjectData: TObject);
+    destructor Destroy; override;
+
+    procedure Open(AConnection: TADOConnection);
+    procedure Close;
+    procedure Save;
+
+    function AddDetailGL(ABillsID: Integer; AGLRec: TsdDataRecord; var sMessage: string): TsdDataRecord;
+    procedure AddDetailGLs(ABillsID: Integer; AGLs: TList);
+
+    procedure LoadDetailGLs(ABillsID: Integer; AGLs: TList);
+    procedure ResetDetailGLs(ABillsID: Integer; AGLs: TList);
+
+    property ProjectData: TObject read FProjectData write FProjectData;
+  end;
+
+implementation
+
+uses
+  Math, UtilMethods, ProjectData, ProjectProperty;
+
+{$R *.dfm}
+
+{ TDetailGLData }
+
+function TDetailGLData.AddDetailGL(ABillsID: Integer;
+  AGLRec: TsdDataRecord; var sMessage: string): TsdDataRecord;
+begin
+  sMessage := '';
+  Result := FindDetailGL(ABillsID, AGLRec.ValueByName('ID').AsInteger);
+  if not Assigned(Result) then
+  begin
+    Result := sddDetailGL.Add(True);
+    Result.ValueByName('ID').AsInteger := GetsdDataSetNewID(sddDetailGL, 'idxID');
+    Result.ValueByName('BillsID').AsInteger := ABillsID;
+    Result.ValueByName('GLID').AsInteger := AGLRec.ValueByName('ID').AsInteger;
+    Result.ValueByName('Code').AsString := AGLRec.ValueByName('Code').AsString;
+    with TProjectData(FProjectData).ProjProperties do
+    begin
+      Result.ValueByName('CreatePhaseID').AsInteger := PhaseCount;
+      Result.ValueByName('CreateStageID').AsInteger := AuditStatus;
+    end;    
+    Result.EndUpdate;
+  end
+  else
+    sMessage := Format('编号:%s 名称:%s', [AGLRec.ValueByName('Code').AsString, AGLRec.ValueByName('Name').AsString]);
+end;
+
+procedure TDetailGLData.AddDetailGLs(ABillsID: Integer; AGLs: TList);
+var
+  i: Integer;
+  sHint, sMessage: string;
+begin
+  for i := 0 to AGLs.Count - 1 do
+  begin
+    AddDetailGL(ABillsID, TsdDataRecord(AGLs.Items[i]), sMessage);
+    if sMessage <> '' then
+    begin
+      if sHint <> '' then
+        sHint := sHint + #13#10;
+      sHint := sHint + sMessage;
+    end;
+  end;
+  if sMessage <> '' then
+    TipMessage('以下工料已添加至该清单,请勿重复添加:' + #13#10 + sHint);
+end;
+
+procedure TDetailGLData.ResetDetailGLs(ABillsID: Integer; AGLs: TList);
+var
+  i, iNewID: Integer;
+  Rec, GLRec: TsdDataRecord;
+begin
+  sddDetailGL.BeginUpdate;
+  try
+    ClearDetailGLs(ABillsID);
+    iNewID := GetsdDataSetNewID(sddDetailGL, 'idxID');
+    for i := 0 to AGLs.Count - 1 do
+    begin
+      GLRec := TsdDataRecord(AGLs.Items[i]);
+      Rec := sddDetailGL.Add;
+      Rec.ValueByName('ID').AsInteger := iNewID + i;
+      Rec.ValueByName('BillsID').AsInteger := ABillsID;
+      Rec.ValueByName('GLID').AsInteger := GLRec.ValueByName('GLID').AsInteger;
+      Rec.ValueByName('Code').AsInteger := GLRec.ValueByName('Code').AsInteger;
+      Rec.ValueByName('Quantity').AsFloat := GLRec.ValueByName('Quantity').AsFloat;
+      with TProjectData(FProjectData).ProjProperties do
+      begin
+        Rec.ValueByName('CreatePhaseID').AsInteger := PhaseCount;
+        Rec.ValueByName('CreateStageID').AsInteger := AuditStatus;
+      end;
+    end;
+  finally
+    sddDetailGL.EndUpdate;
+  end;
+end;
+
+procedure TDetailGLData.ClearDetailGLs(ABillsID: Integer);
+var
+  idx: TsdIndex;
+  Rec: TsdDataRecord;
+begin
+  idx := sddDetailGL.FindIndex('idxBillsID');
+  Rec := idx.FindKey(ABillsID);
+  while Assigned(Rec) do
+  begin
+    sddDetailGL.Remove(Rec);
+    Rec := idx.FindKey(ABillsID);
+  end;
+end;
+
+procedure TDetailGLData.Close;
+begin
+  sddDetailGL.Close;
+end;
+
+constructor TDetailGLData.Create(AProjectData: TObject);
+begin
+  inherited Create(nil);
+  FProjectData := AProjectData;
+  sddDetailGL.AddIndex('idxView', 'BillsID;Code');
+  sddDetailGL.AddIndex('idxFind', 'BillsID;GLID');
+  sddDetailGL.AddIndex('idxBillsID', 'BillsID');
+  sddDetailGL.AddIndex('idxID', 'ID');
+end;
+
+destructor TDetailGLData.Destroy;
+begin
+
+  inherited;
+end;
+
+function TDetailGLData.FindDetailGL(ABillsID,
+  AGLID: Integer): TsdDataRecord;
+var
+  idx: TsdIndex;
+begin
+  idx := sddDetailGL.FindIndex('idxFind');
+  Result := idx.FindKey(VarArrayOf([ABillsID, AGLID]));
+end;
+
+procedure TDetailGLData.Open(AConnection: TADOConnection);
+begin
+  sdpDetailGL.Connection := AConnection;
+  sddDetailGL.Open;
+end;
+
+procedure TDetailGLData.Save;
+begin
+  sddDetailGL.Save;
+end;
+
+procedure TDetailGLData.LoadDetailGLs(ABillsID: Integer; AGLs: TList);
+var
+  idx: TsdIndex;
+  iRec, iFirst, iLast: Integer;
+begin
+  idx := sddDetailGL.FindIndex('idxBillsID');
+  iFirst := idx.FindKeyIndex(ABillsID);
+  iLast := idx.FindKeyLastIndex(ABillsID);
+  for iRec := iFirst to iLast do
+    AGLs.Add(idx.Records[iRec]);
+end;
+
+end.

+ 205 - 0
DataModules/PriceMarginBillsDm.dfm

@@ -0,0 +1,205 @@
+object PriceMarginBillsData: TPriceMarginBillsData
+  OldCreateOrder = False
+  Left = 736
+  Top = 541
+  Height = 227
+  Width = 354
+  object sdmpGclBills: TsdMemoryProvider
+    Left = 64
+    Top = 16
+  end
+  object sddGclBills: TsdDataSet
+    Active = False
+    Provider = sdmpGclBills
+    Left = 64
+    Top = 80
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D65090001044E616D650606425F436F6465094669656C644E616D65
+      0606425F436F64650844617461547970650218084461746153697A6502320549
+      734B6579080F4E65656450726F636573734E616D65090001044E616D65060949
+      6E646578436F6465094669656C644E616D650609496E646578436F6465084461
+      7461547970650218084461746153697A6502320549734B6579080F4E65656450
+      726F636573734E616D65090001044E616D6506044E616D65094669656C644E61
+      6D6506044E616D650844617461547970650218084461746153697A6503FF0005
+      49734B6579080F4E65656450726F636573734E616D65090001044E616D650605
+      556E697473094669656C644E616D650605556E69747308446174615479706502
+      18084461746153697A6502140549734B6579080F4E65656450726F636573734E
+      616D65090001044E616D6506055072696365094669656C644E616D6506055072
+      6963650844617461547970650206084461746153697A6502080549734B657908
+      0F4E65656450726F636573734E616D65090001044E616D65060F437572446561
+      6C5175616E74697479094669656C644E616D65060F4375724465616C5175616E
+      746974790844617461547970650206084461746153697A6502080549734B6579
+      080F4E65656450726F636573734E616D65090001044E616D65060D4375725163
+      5175616E74697479094669656C644E616D65060D43757251635175616E746974
+      790844617461547970650206084461746153697A6502080549734B6579080F4E
+      65656450726F636573734E616D65090001044E616D6506114375724761746865
+      725175616E74697479094669656C644E616D6506114375724761746865725175
+      616E746974790844617461547970650206084461746153697A6502080549734B
+      6579080F4E65656450726F636573734E616D65090000}
+  end
+  object sdmpDetailGclBills: TsdMemoryProvider
+    Left = 160
+    Top = 16
+  end
+  object sddDetailGclBills: TsdDataSet
+    Active = False
+    Provider = sdmpDetailGclBills
+    Left = 160
+    Top = 80
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D65090001044E616D65060742696C6C734944094669656C644E616D
+      65060742696C6C7349440844617461547970650203084461746153697A650204
+      0549734B6579080F4E65656450726F636573734E616D65090001044E616D6506
+      0C5472656553657269616C4E6F094669656C644E616D65060C54726565536572
+      69616C4E6F0844617461547970650203084461746153697A6502040549734B65
+      79080F4E65656450726F636573734E616D65090001044E616D65060B52656C61
+      42696C6C734944094669656C644E616D65060B52656C6142696C6C7349440844
+      617461547970650203084461746153697A6502040549734B6579080F4E656564
+      50726F636573734E616D65090001044E616D6506094C656166586D6A49440946
+      69656C644E616D6506094C656166586D6A494408446174615479706502030844
+      61746153697A6502040549734B6579080F4E65656450726F636573734E616D65
+      090001044E616D650607586D6A436F6465094669656C644E616D650607586D6A
+      436F64650844617461547970650218084461746153697A6502320549734B6579
+      080F4E65656450726F636573734E616D65090001044E616D650607586D6A4E61
+      6D65094669656C644E616D650607586D6A4E616D650844617461547970650218
+      084461746153697A6503C8000549734B6579080F4E65656450726F636573734E
+      616D65090001044E616D650608586D6A556E697473094669656C644E616D6506
+      08586D6A556E6974730844617461547970650218084461746153697A65021405
+      49734B6579080F4E65656450726F636573734E616D65080001044E616D65060A
+      4E616D6544616E576569094669656C644E616D65060A4E616D6544616E576569
+      0844617461547970650218084461746153697A6503C8000549734B6579080F4E
+      65656450726F636573734E616D65090001044E616D6506094E616D6546656E42
+      75094669656C644E616D6506094E616D6546656E427508446174615479706502
+      18084461746153697A6503C8000549734B6579080F4E65656450726F63657373
+      4E616D65090001044E616D65060C4E616D6546656E5869616E67094669656C64
+      4E616D65060C4E616D6546656E5869616E670844617461547970650218084461
+      746153697A6503C8000549734B6579080F4E65656450726F636573734E616D65
+      090001044E616D6506084E616D65556E6974094669656C644E616D6506084E61
+      6D65556E69740844617461547970650218084461746153697A6503C800054973
+      4B6579080F4E65656450726F636573734E616D65090001044E616D6506035065
+      67094669656C644E616D65060350656708446174615479706502180844617461
+      53697A6503C8000549734B6579080F4E65656450726F636573734E616D650900
+      01044E616D65060F4375724465616C5175616E74697479094669656C644E616D
+      65060F4375724465616C5175616E746974790844617461547970650206084461
+      746153697A6502080549734B6579080F4E65656450726F636573734E616D6509
+      0001044E616D65060D43757251635175616E74697479094669656C644E616D65
+      060D43757251635175616E746974790844617461547970650206084461746153
+      697A6502080549734B6579080F4E65656450726F636573734E616D6509000104
+      4E616D6506114375724761746865725175616E74697479094669656C644E616D
+      6506114375724761746865725175616E74697479084461746154797065020608
+      4461746153697A6502080549734B6579080F4E65656450726F636573734E616D
+      65090000}
+  end
+  object sdvGclBills: TsdDataView
+    Active = False
+    DataSet = sddGclBills
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'B_Code'
+      end
+      item
+        FieldName = 'Name'
+      end
+      item
+        FieldName = 'Units'
+      end
+      item
+        FieldName = 'Price'
+      end
+      item
+        FieldName = 'CurDealQuantity'
+      end
+      item
+        FieldName = 'CurGatherQuantity'
+      end
+      item
+        FieldName = 'CurQcQuantity'
+      end>
+    OnCurrentChanged = sdvGclBillsCurrentChanged
+    Left = 64
+    Top = 136
+  end
+  object sdvDetailGclBills: TsdDataView
+    Active = False
+    DataSet = sddDetailGclBills
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'XmjCode'
+      end
+      item
+        FieldName = 'XmjName'
+      end
+      item
+        FieldName = 'XmjUnits'
+      end
+      item
+        FieldName = 'NameDanWei'
+      end
+      item
+        FieldName = 'NameFenBu'
+      end
+      item
+        FieldName = 'NameFenXiang'
+      end
+      item
+        FieldName = 'NameUnit'
+      end
+      item
+        FieldName = 'Peg'
+      end
+      item
+        FieldName = 'CurDealQuantity'
+      end
+      item
+        FieldName = 'CurGatherQuantity'
+      end
+      item
+        FieldName = 'CurQcQuantity'
+      end>
+    OnFilterRecord = sdvDetailGclBillsFilterRecord
+    OnCurrentChanged = sdvDetailGclBillsCurrentChanged
+    Left = 160
+    Top = 136
+  end
+  object sdvDetailGL: TsdDataView
+    Active = False
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'Code'
+      end
+      item
+        FieldName = 'Name'
+        KeyFields = 'GLID'
+        LookupKeyFields = 'ID'
+        LookupResultField = 'Name'
+      end
+      item
+        FieldName = 'Units'
+        KeyFields = 'GLID'
+        LookupKeyFields = 'ID'
+        LookupResultField = 'Units'
+      end
+      item
+        FieldName = 'Quantity'
+      end
+      item
+        FieldName = 'PM_PreTotalPrice'
+      end
+      item
+        FieldName = 'PM_CurTotalPrice'
+      end
+      item
+        FieldName = 'PM_EndTotalPrice'
+      end>
+    OnFilterRecord = sdvDetailGLFilterRecord
+    Left = 264
+    Top = 136
+  end
+end

+ 234 - 0
DataModules/PriceMarginBillsDm.pas

@@ -0,0 +1,234 @@
+unit PriceMarginBillsDm;
+
+interface
+
+uses
+  SysUtils, Classes, sdDB, sdProvider, BillsTree, mDataRecord,
+  GclBillsGatherModel;
+
+type
+  TPriceMarginBillsData = class(TDataModule)
+    sdmpGclBills: TsdMemoryProvider;
+    sddGclBills: TsdDataSet;
+    sdmpDetailGclBills: TsdMemoryProvider;
+    sddDetailGclBills: TsdDataSet;
+    sdvGclBills: TsdDataView;
+    sdvDetailGclBills: TsdDataView;
+    sdvDetailGL: TsdDataView;
+    procedure sdvGclBillsCurrentChanged(ARecord: TsdDataRecord);
+    procedure sdvDetailGclBillsFilterRecord(ARecord: TsdDataRecord;
+      var Allow: Boolean);
+    procedure sdvDetailGLFilterRecord(ARecord: TsdDataRecord;
+      var Allow: Boolean);
+    procedure sdvDetailGclBillsCurrentChanged(ARecord: TsdDataRecord);
+  private
+    FProjectData: TObject;
+    procedure WriteGclBillsData(AGcls: TList);
+    function GetMainBillsTree: TBillsIDTree;
+  public
+    constructor Create(AProjectData: TObject);
+    destructor Destroy; override;
+
+    procedure RefreshBills;
+    procedure AddDetailGLs(AGls: TList);
+
+    property ProjectData: TObject read FProjectData;
+    property MainBillsTree: TBillsIDTree read GetMainBillsTree;
+  end;
+
+implementation
+
+uses
+  ZhAPI, ProjectData, UtilMethods;
+
+{$R *.dfm}
+
+{ TPriceMarginBillsData }
+
+constructor TPriceMarginBillsData.Create(AProjectData: TObject);
+begin
+  inherited Create(nil);
+  FProjectData := AProjectData;
+
+  sddGclBills.Open;
+  if not Assigned(sddGclBills.FindIndex('idxIndexCode')) then
+    sddGclBills.AddIndex('idxIndexCode', 'IndexCode');
+  sdvGclBills.Open;
+  sdvGclBills.IndexName := 'idxIndexCode';
+
+  sddDetailGclBills.Open;
+  if not Assigned(sddDetailGclBills.FindIndex('idxSerialNo')) then
+    sddDetailGclBills.AddIndex('idxSerialNo', 'BillsID;TreeSerialNo');
+  sdvDetailGclBills.Open;
+  sdvDetailGclBills.IndexName := 'idxSerialNo';
+
+  sdvDetailGL.DataSet := TProjectData(FProjectData).DetailGLData.sddDetailGL;
+  sdvDetailGL.IndexName := 'idxView';
+  sdvDetailGL.Columns.FindColumn('Name').LookupDataSet := TProjectData(FProjectData).ProjectGLData.sddProjectGL;
+  sdvDetailGL.Columns.FindColumn('Units').LookupDataSet := TProjectData(FProjectData).ProjectGLData.sddProjectGL;
+end;
+
+destructor TPriceMarginBillsData.Destroy;
+begin
+  inherited;
+end;
+
+procedure TPriceMarginBillsData.RefreshBills;
+var
+  vGather: TGclGatherModel;
+begin
+  vGather := TGclGatherModel.Create(FProjectData);
+  try
+    vGather.WriteGatherData := WriteGclBillsData;
+    vGather.Execute;
+  finally
+    vGather.Free;
+  end;
+end;
+
+procedure TPriceMarginBillsData.WriteGclBillsData(AGcls: TList);
+
+  procedure BeforeWrite;
+  begin
+    sdvDetailGclBills.Filtered := False;
+    sdvDetailGL.Filtered := False;
+
+    sddGclBills.DisableControls;
+    sddGclBills.BeginUpdate;
+    sddGclBills.DeleteAll;
+
+    sddDetailGclBills.DisableControls;
+    sddDetailGclBills.BeginUpdate;
+    sddDetailGclBills.DeleteAll;
+  end;
+
+  procedure AfterWrite;
+  var
+    idx: TsdIndex;
+  begin
+    sddDetailGclBills.EndUpdate;
+    sddDetailGclBills.EnableControls;
+
+    sddGclBills.EndUpdate;
+    sddGclBills.EnableControls;
+
+    if not sdvDetailGL.Active then
+      sdvDetailGL.Open;
+
+    idx := sddGclBills.FindIndex('idxIndexCode');
+    sdvGclBills.LocateInControl(sdvGclBills.Records[0]);
+    sdvDetailGclBills.Filtered := True;
+    sdvDetailGclBills.LocateInControl(sdvDetailGclBills.Records[0]);
+    sdvDetailGL.Filtered := True;
+
+    sdvDetailGclBills.LocateInControl(sdvDetailGclBills.Records[0]);
+  end;
+
+  procedure WriteDetailGclNode(AGclNode: TGclNode);
+  var
+    iDetailGcl: Integer;
+    vDetailGcl: TDetailGclNode;
+    Rec: TsdDataRecord;
+  begin
+    for iDetailGcl := 0 to AGclNode.DetailGclCount -1 do
+    begin
+      vDetailGcl := AGclNode.DetailGcl[iDetailGcl];
+      Rec := sddDetailGclBills.Add;
+      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;
+
+      Rec.ValueByName('CurDealQuantity').AsFloat := vDetailGcl.CurDealQuantity;
+      Rec.ValueByName('CurQcQuantity').AsFloat := vDetailGcl.CurQcQuantity;
+      Rec.ValueByName('CurGatherQuantity').AsFloat := vDetailGcl.CurGatherQuantity;
+    end;
+  end;
+
+  procedure WriteGclNode(AGclNode: TGclNode);
+  var
+    Rec: TsdDataRecord;
+  begin
+    Rec := sddGclBills.Add;
+    Rec.ValueByName('ID').AsInteger := AGclNode.ID;
+    Rec.ValueByName('B_Code').AsString := AGclNode.B_Code;
+    Rec.ValueByName('IndexCode').AsString := AGclNode.IndexCode;
+    Rec.ValueByName('Name').AsString := AGclNode.Name;
+    Rec.ValueByName('Units').AsString := AGclNode.Units;
+    Rec.ValueByName('Price').AsFloat := AGclNode.Price;
+
+    Rec.ValueByName('CurDealQuantity').AsFloat := AGclNode.CurDealQuantity;
+    Rec.ValueByName('CurQcQuantity').AsFloat := AGclNode.CurQcQuantity;
+    Rec.ValueByName('CurGatherQuantity').AsFloat := AGclNode.CurGatherQuantity;
+    WriteDetailGclNode(AGclNode);
+  end;
+
+var
+  iGcl: Integer;
+  vGclNode: TGclNode;
+begin
+  BeforeWrite;
+  try
+    for iGcl := 0 to AGcls.Count - 1 do
+    begin
+      vGclNode := TGclNode(AGcls.Items[iGcl]);
+      WriteGclNode(vGclNode);
+    end;
+  finally
+    AfterWrite;
+  end;
+end;
+
+procedure TPriceMarginBillsData.sdvGclBillsCurrentChanged(
+  ARecord: TsdDataRecord);
+begin
+  sdvDetailGclBills.RefreshFilter;
+  sdvDetailGclBills.LocateInControl(sdvDetailGclBills.Records[0]);
+end;
+
+procedure TPriceMarginBillsData.sdvDetailGclBillsFilterRecord(
+  ARecord: TsdDataRecord; var Allow: Boolean);
+begin
+  if Assigned(sdvGclBills.Current) and Assigned(ARecord) then
+    Allow := ARecord.ValueByName('BillsID').AsInteger = sdvGclBills.Current.ValueByName('ID').AsInteger
+  else
+    Allow := False;
+end;
+
+procedure TPriceMarginBillsData.sdvDetailGLFilterRecord(
+  ARecord: TsdDataRecord; var Allow: Boolean);
+begin
+  if Assigned(sdvDetailGclBills.Current) and Assigned(ARecord) then
+    Allow := ARecord.ValueByName('BillsID').AsInteger = sdvDetailGclBills.Current.ValueByName('RelaBillsID').AsInteger
+  else
+    Allow := False;
+end;
+
+function TPriceMarginBillsData.GetMainBillsTree: TBillsIDTree;
+begin
+  Result := TProjectData(FProjectData).BillsMeasureData.BillsMeasureTree;
+end;
+
+procedure TPriceMarginBillsData.AddDetailGLs(AGls: TList);
+begin
+  TProjectData(FProjectData).DetailGLData.AddDetailGLs(
+      sdvDetailGclBills.Current.ValueByName('RelaBillsID').AsInteger, AGls);
+  sdvDetailGclBills.RefreshFilter;
+end;
+
+procedure TPriceMarginBillsData.sdvDetailGclBillsCurrentChanged(
+  ARecord: TsdDataRecord);
+begin
+  sdvDetailGL.RefreshFilter;
+end;
+
+end.

+ 88 - 0
DataModules/ProjectGLDm.dfm

@@ -0,0 +1,88 @@
+object ProjectGLData: TProjectGLData
+  OldCreateOrder = False
+  Left = 562
+  Top = 408
+  Height = 252
+  Width = 171
+  object sdpProjectGL: TsdADOProvider
+    TableName = 'ProjectGL'
+    Left = 56
+    Top = 24
+  end
+  object sddProjectGL: TsdDataSet
+    Active = False
+    Provider = sdpProjectGL
+    AfterAddRecord = sddProjectGLAfterAddRecord
+    BeforeValueChange = sddProjectGLBeforeValueChange
+    Left = 57
+    Top = 80
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D65090001044E616D650604436F6465094669656C644E616D650604
+      436F64650844617461547970650203084461746153697A6502040549734B6579
+      080F4E65656450726F636573734E616D65090001044E616D6506044E616D6509
+      4669656C644E616D6506044E616D650844617461547970650218084461746153
+      697A6503C8000549734B6579080F4E65656450726F636573734E616D65090001
+      044E616D650605556E697473094669656C644E616D650605556E697473084461
+      7461547970650218084461746153697A6502140549734B6579080F4E65656450
+      726F636573734E616D65090001044E616D6506055370656373094669656C644E
+      616D65060553706563730844617461547970650218084461746153697A6503C8
+      000549734B6579080F4E65656450726F636573734E616D65090001044E616D65
+      0609426173655072696365094669656C644E616D650609426173655072696365
+      0844617461547970650206084461746153697A6502080549734B6579080F4E65
+      656450726F636573734E616D65090001044E616D6506095269736B52616E6765
+      094669656C644E616D6506095269736B52616E67650844617461547970650206
+      084461746153697A6502080549734B6579080F4E65656450726F636573734E61
+      6D65090001044E616D65060D43726561746550686173654944094669656C644E
+      616D65060D437265617465506861736549440844617461547970650203084461
+      746153697A6502040549734B6579080F4E65656450726F636573734E616D6509
+      0001044E616D65060D43726561746553746167654944094669656C644E616D65
+      060D437265617465537461676549440844617461547970650203084461746153
+      697A6502040549734B6579080F4E65656450726F636573734E616D6509000104
+      4E616D65060D4C6F636B656450686173654944094669656C644E616D65060D4C
+      6F636B6564506861736549440844617461547970650203084461746153697A65
+      02040549734B6579080F4E65656450726F636573734E616D65090001044E616D
+      65060D4C6F636B656453746167654944094669656C644E616D65060D4C6F636B
+      6564537461676549440844617461547970650203084461746153697A65020405
+      49734B6579080F4E65656450726F636573734E616D65090001044E616D650609
+      496E666F5072696365094669656C644E616D650609496E666F50726963650844
+      617461547970650206084461746153697A6502080549734B6579080F4E656564
+      50726F636573734E616D65090001044E616D650608496E666F44617465094669
+      656C644E616D650608496E666F44617465084461746154797065021808446174
+      6153697A6502140549734B6579080F4E65656450726F636573734E616D650900
+      00}
+  end
+  object sdvProjectGL: TsdDataView
+    Active = False
+    DataSet = sddProjectGL
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'Code'
+      end
+      item
+        FieldName = 'Name'
+      end
+      item
+        FieldName = 'Units'
+      end
+      item
+        FieldName = 'Specs'
+      end
+      item
+        FieldName = 'BasePrice'
+      end
+      item
+        FieldName = 'RiskRange'
+      end
+      item
+        FieldName = 'InfoPrice'
+      end
+      item
+        FieldName = 'InfoDate'
+      end>
+    Left = 56
+    Top = 136
+  end
+end

+ 182 - 0
DataModules/ProjectGLDm.pas

@@ -0,0 +1,182 @@
+unit ProjectGLDm;
+
+interface
+
+uses
+  SysUtils, Classes, sdDB, sdProvider, ADODB;
+
+type
+  TProjectGLData = class(TDataModule)
+    sdpProjectGL: TsdADOProvider;
+    sddProjectGL: TsdDataSet;
+    sdvProjectGL: TsdDataView;
+    procedure sddProjectGLAfterAddRecord(ARecord: TsdDataRecord);
+    procedure sddProjectGLBeforeValueChange(AValue: TsdValue;
+      const NewValue: Variant; var Allow: Boolean);
+  private
+    FProjectData: TObject;
+
+    function CheckSameCode(ACode: Integer): Boolean;
+
+    procedure SaveGLPrice;
+  public
+    constructor Create(AProjectData: TObject);
+    destructor Destroy; override;
+
+    procedure Open(AConnection: TADOConnection);
+    procedure Save;
+
+    procedure LoadCurPhaseInfoPrice;
+
+    property ProjectData: TObject read FProjectData write FProjectData;
+  end;
+
+implementation
+
+uses
+  ProjectData, UtilMethods, DB, Variants;
+
+{$R *.dfm}
+
+{ TProjectGLData }
+
+function TProjectGLData.CheckSameCode(ACode: Integer): Boolean;
+var
+  Rec: TsdDataRecord;
+begin
+  Rec := sddProjectGL.FindKey('idxCode', ACode);
+  Result := Assigned(Rec);
+end;
+
+constructor TProjectGLData.Create(AProjectData: TObject);
+begin
+  inherited Create(nil);
+  FProjectData := AProjectData;
+end;
+
+destructor TProjectGLData.Destroy;
+begin
+  inherited;
+end;
+
+procedure TProjectGLData.LoadCurPhaseInfoPrice;
+const
+  sSelectSql = 'Select * From GLPrice Where PhaseID = %d';
+var
+  sSql: string;
+  vQuery: TADOQuery;
+
+  procedure LoadInfoPrice;
+  var
+    Rec: TsdDataRecord;
+  begin
+    vQuery.First;
+    while not vQuery.Eof do
+    begin
+      Rec := sddProjectGL.FindKey('idxID', vQuery.FieldByName('GLID').AsInteger);
+      Rec.ValueByName('InfoPrice').AsFloat := vQuery.FieldByName('InfoPrice').AsFloat;
+      Rec.ValueByName('InfoDate').AsString := vQuery.FieldByName('InfoDate').AsVariant;
+      vQuery.Next;
+    end;
+  end;
+
+begin
+  sddProjectGL.BeginUpdate;
+  vQuery := TADOQuery.Create(nil);
+  try
+    vQuery.Connection := sdpProjectGL.Connection;
+    sSql := Format(sSql, [TProjectData(FProjectData).PhaseIndex]);
+    vQuery.SQL.Clear;
+    vQuery.SQL.Add(sSql);
+    vQuery.ExecSQL;
+    LoadInfoPrice;
+  finally
+    vQuery.Free;
+    sddProjectGL.EndUpdate;
+  end;
+end;
+
+procedure TProjectGLData.Open(AConnection: TADOConnection);
+begin
+  sdpProjectGL.Connection := AConnection;
+  sddProjectGL.Open;
+  if not Assigned(sddProjectGL.IndexList.FindByName('idxID')) then
+    sddProjectGL.AddIndex('idxID', 'ID');
+  if not Assigned(sddProjectGL.IndexList.FindByName('idxCode')) then
+    sddProjectGL.AddIndex('idxCode', 'Code');
+  sdvProjectGL.Open;
+  sdvProjectGL.IndexName := 'idxCode';
+end;
+
+procedure TProjectGLData.Save;
+begin
+  sddProjectGL.Save;
+  with TProjectData(FProjectData) do
+    if Assigned(PhaseData) and not PhaseData.StageDataReadOnly and (PhaseData.StageCount > 1) then
+      SaveGLPrice;
+end;
+
+procedure TProjectGLData.SaveGLPrice;
+const
+  sDeleteSql = 'Delete From GLPrice Where PhaseID = %d';
+const
+  sInsertSql = 'Insert Into GLPrice'+
+               '  Select ID As GLID, %d As PhaseID, InfoPrice, InfoDate' +
+               '  From ProjectGL';
+var
+  vQuery: TADOQuery;
+  iPhaseID: Integer;
+  sSql: String;
+begin
+  iPhaseID := TProjectData(FProjectData).ProjProperties.PhaseCount;
+  vQuery := TADOQuery.Create(nil);
+  try
+    vQuery.Connection := sdpProjectGL.Connection;
+    sSql := Format(sDeleteSql, [iPhaseID]);
+    vQuery.SQL.Clear;
+    vQuery.SQL.Add(sSql);
+    vQuery.ExecSQL;
+
+    sSql := Format(sInsertSql, [iPhaseID]);
+    vQuery.SQL.Clear;
+    vQuery.SQL.Add(sSql);
+    vQuery.ExecSQL;
+  finally
+    vQuery.Free;
+  end;
+end;
+
+procedure TProjectGLData.sddProjectGLAfterAddRecord(
+  ARecord: TsdDataRecord);
+begin
+  ARecord.ValueByName('ID').AsInteger := GetsdDataSetNewID(sddProjectGL, 'idxID');
+  ARecord.ValueByName('CreatePhaseID').AsInteger := TProjectData(FProjectData).ProjProperties.PhaseCount;
+  ARecord.ValueByName('CreateStageID').AsInteger := TProjectData(FProjectData).ProjProperties.AuditStatus;
+end;
+
+procedure TProjectGLData.sddProjectGLBeforeValueChange(AValue: TsdValue;
+  const NewValue: Variant; var Allow: Boolean);
+begin
+  if SameText(AValue.FieldName, 'Code') then
+  begin
+    Allow := False;
+    if VarIsNull(NewValue) then
+      ErrorMessage('编号不可为空。')
+    else if CheckSameCode(NewValue) then
+      ErrorMessage('编号不可重复。')
+    else
+      Allow := True;
+  end
+  else if not(SameText(AValue.FieldName, 'ID') or
+      SameText(AValue.FieldName, 'CreatePhaseID') or
+      SameText(AValue.FieldName, 'CreateStageID')) then
+  begin
+    Allow := False;
+    if (AValue.Owner.ValueByName('Code').AsString = '') then
+      ErrorMessage('编号不可为空,请先填写编号,再填写其他信息。')
+    else
+      Allow := True;
+  end;
+end;
+
+end.

+ 19 - 0
Forms/MainFrm.dfm

@@ -962,6 +962,25 @@ object MainForm: TMainForm
       Hint = #35774#32622#35745#25552#26399#38480
       Visible = ivAlways
     end
+    object dxbtnAddDetailGLs: TdxBarButton
+      Caption = #26032#22686#35843#24046#24037#26009
+      Category = 0
+      Hint = #26032#22686#35843#24046#24037#26009
+      Visible = ivAlways
+    end
+    object dxbtnCopyDetailGls: TdxBarButton
+      Caption = #22797#21046#35843#24046#24037#26009
+      Category = 0
+      Hint = #22797#21046#35843#24046#24037#26009
+      Visible = ivAlways
+      ImageIndex = 4
+    end
+    object dxbtnApplyToSameBills: TdxBarButton
+      Caption = #24212#29992#35843#24046#24037#26009#33267#30456#21516#28165#21333
+      Category = 0
+      Hint = #24212#29992#35843#24046#24037#26009#33267#30456#21516#28165#21333
+      Visible = ivAlways
+    end
   end
   object Images: TImageList
     DrawingStyle = dsTransparent

+ 3 - 0
Forms/MainFrm.pas

@@ -143,6 +143,9 @@ type
     dxsiExpandTo: TdxBarSubItem;
     dxbtnLocateBookmark: TdxBarButton;
     dxbtnSetDealPayPlan: TdxBarButton;
+    dxbtnAddDetailGLs: TdxBarButton;
+    dxbtnCopyDetailGls: TdxBarButton;
+    dxbtnApplyToSameBills: TdxBarButton;
     procedure FormCreate(Sender: TObject);
     procedure FormDestroy(Sender: TObject);
     procedure jtsProjectsChange(Sender: TObject; NewTab: Integer;

+ 269 - 0
Forms/SelectDetailGLsFrm.dfm

@@ -0,0 +1,269 @@
+object SelectDetailGLsForm: TSelectDetailGLsForm
+  Left = 567
+  Top = 305
+  Width = 480
+  Height = 529
+  BorderIcons = [biSystemMenu]
+  Caption = 'SelectDetailGLsForm'
+  Color = clBtnFace
+  Font.Charset = DEFAULT_CHARSET
+  Font.Color = clWindowText
+  Font.Height = -11
+  Font.Name = 'MS Sans Serif'
+  Font.Style = []
+  OldCreateOrder = False
+  DesignSize = (
+    472
+    495)
+  PixelsPerInch = 96
+  TextHeight = 13
+  object pnlData: TPanel
+    Left = 0
+    Top = 0
+    Width = 472
+    Height = 457
+    Align = alTop
+    BevelOuter = bvNone
+    TabOrder = 0
+    DesignSize = (
+      472
+      457)
+    object imgSearch: TImage
+      Left = 440
+      Top = 3
+      Width = 32
+      Height = 32
+      Anchors = [akTop, akRight]
+      AutoSize = True
+      Picture.Data = {
+        055449636F6E0000010001001818000000002000880900001600000028000000
+        1800000030000000010020000000000000120000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        000000000000000000000000000000009B9B9B1C9B9B9B709898983900000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        000000000000000000000000909090179A9A9AB39B9B9BF99B9B9BD89A9A9A3F
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000001949494269B9B9BCC9B9B9BFF9B9B9BFF9B9B9BFF9B9B9BBF
+        9999991900000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        AAAAAA039797974C9A9A9AD69B9B9BFF9B9B9BFF9B9B9BFF9B9B9BFF9B9B9BFC
+        9B9B9B7A00000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        989898579A9A9AE69B9B9BFE9B9B9BFF9B9B9BFF9B9B9BFF9B9B9BFF9B9B9BFF
+        9A9A9AD7000000000000000000000000000000007F7F7F028E8E8E1297979720
+        9A9A9A269A9A9A269999991E9292920E00000001000000000000000097979736
+        9A9A9AE29A9A9AFD9B9B9BFF9B9B9BFF9B9B9BFF9B9B9BFF9B9B9BFC9A9A9ADA
+        9A9A9A530000000000000000000000009595951898989872999999B79A9A9AE1
+        9A9A9AF39A9A9AF29A9A9ADA9A9A9AAA999999628989890DD1D1D10BCBCBCB58
+        AFAFAF609B9B9BCC9B9B9BFE9B9B9BFF9B9B9BFF9A9A9AF59B9B9B999999992D
+        0000000100000000000000009494942B9A9A9ACE9A9A9AF69A9A9AE69A9A9A97
+        9A9A9A6D97979771989898A6999999EE9A9A9AF39B9B9BB5BCBCBC54CECECEDD
+        CECECECBA9A9A9749A9A9AEE9B9B9BFF9B9B9BDB9C9C9C4B8B8B8B0B00000000
+        00000000000000019B9B9B2E9B9B9BDC9B9B9BEF9B9B9B8CB7B7B727CFCFCF45
+        CECECE74CDCDCD71CFCFCF3AA8A8A8359B9B9BAD9B9B9BF6999999B0C3C3C36A
+        CFCFCFEFCBCBCB6D999999BE9A9A9AB19D9D9D22000000000000000000000000
+        000000009999991E9A9A9AA79A9A9AF49C9C9C6CCACACA5BCECECECACFCFCFFE
+        CFCFCFFFCFCFCFFFCECECEF8CFCFCFB5C3C3C3409A9A9A869A9A9AF399999980
+        CDCDCD60CECECE1F9797973B9F9F9F0800000000000000000000000000000000
+        000000009A9A9A6F9A9A9AF59898988EC8C8C83CCECECEE7CFCFCFFECFCFCFFF
+        CFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFECFCFCFDEB6B6B6319B9B9BB39A9A9AF3
+        9595951D00000000000000000000000000000000000000000000000000000000
+        000000009A9A9AC39B9B9BEB95959529CECECEC1CFCFCFFFCFCFCFFFCFCFCFFF
+        CFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCECECEA2999999679A9A9AF6
+        9A9A9A7500000000000000000000000000000000000000000000000000000000
+        000000009B9B9BEE9B9B9BBFB9B9B937CFCFCFFCCFCFCFFFCFCFCFFFCFCFCFFF
+        CFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCECECEDDABABAB529B9B9BE6
+        9B9B9BB000000000000000000000000000000000000000000000000000000000
+        000000009A9A9AF8999999ADC1C1C153CFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFF
+        CFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCECECEE5B5B5B5569B9B9BE0
+        9A9A9AC600000000000000000000000000000000000000000000000000000000
+        000000009A9A9AF89A9A9AB9C0C0C041CFCFCFFDCFCFCFFFCFCFCFFFCFCFCFFF
+        CFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCECECEDFADADAD549B9B9BE4
+        9B9B9BB800000000000000000000000000000000000000000000000000000000
+        000000009A9A9AEC9B9B9BE09D9D9D27CDCDCDD4CFCFCFFFCFCFCFFFCFCFCFFF
+        CFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCECECEB49C9C9C5F9A9A9AF2
+        9A9A9A8300000000000000000000000000000000000000000000000000000000
+        000000009A9A9ABA9A9A9AFA97979774CECECE4FCECECEF6CFCFCFFFCFCFCFFF
+        CFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCDCDCDF5C0C0C03D9A9A9AA29B9B9BFC
+        9898982A00000000000000000000000000000000000000000000000000000000
+        000000009999994E9A9A9ABD9A9A9AF39D9D9D41CDCDCD7CCECECEE8CFCFCFFD
+        CFCFCFFFCFCFCFFFCFCFCFFBCFCFCFDECACACA52959595599A9A9AF3999999A1
+        0000000000000000000000000000000000000000000000000000000000000000
+        000000007F7F7F049C9C9C489A9A9AE4999999DD9B9B9B66C5C5C54FCDCDCD86
+        CECECEA3CECECEA1CDCDCD7CBBBBBB4B9A9A9A799A9A9AED9A9A9AC796969622
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000AAAAAA03999999469A9A9AEB9A9A9AF19A9A9AC89D9D9D7D
+        9F9F9F5D9E9E9E5F9B9B9B8A9A9A9AD19B9B9BF79A9A9AD596969633FFFFFF01
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000097979720999999A89A9A9AE29A9A9AF1
+        9B9B9BF79A9A9AF89A9A9AF09B9B9BDE9A9A9A929999990F0000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000999999059898982F98989859
+        9898986B9797976A96969653959595247F7F7F02000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        0000000000000000000000000000000000000000000000000000000000000000
+        00000000FFFFFF00FFFFFF00FFFFE300FFFFC100FFFF8100FFFF0000FFFE0100
+        F81F0300E1848F00C7E29F009811FF009009FF002005FF002004FF002004FF00
+        2004FF002004FF003009FF009819FF00CC73FF00E387FF00F00FFF00FFFFFF00
+        FFFFFF}
+    end
+    object leSearch: TLabeledEdit
+      Left = 102
+      Top = 6
+      Width = 331
+      Height = 19
+      Anchors = [akLeft, akTop, akRight]
+      Ctl3D = False
+      EditLabel.Width = 92
+      EditLabel.Height = 13
+      EditLabel.Caption = #24037#26009#32534#21495'/'#21517#31216#65306' '
+      LabelPosition = lpLeft
+      ParentCtl3D = False
+      TabOrder = 0
+    end
+    object zgGL: TZJGrid
+      Left = 6
+      Top = 32
+      Width = 460
+      Height = 425
+      Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection]
+      OptionsEx = []
+      ColCount = 6
+      ShowGridLine = False
+      DefaultColWidth = 73
+      DefaultFixedColWidth = 25
+      Selection.AlphaBlend = False
+      Selection.TransparentColor = False
+      FrozenCol = 0
+      FrozenRow = 0
+      OnGetCellText = zgGLGetCellText
+      OnSetCellText = zgGLSetCellText
+      Anchors = [akLeft, akTop, akRight, akBottom]
+    end
+  end
+  object btnOk: TButton
+    Left = 303
+    Top = 466
+    Width = 75
+    Height = 21
+    Anchors = [akRight, akBottom]
+    Caption = #30830'    '#23450
+    TabOrder = 1
+    OnClick = btnOkClick
+  end
+  object btnCancel: TButton
+    Left = 388
+    Top = 466
+    Width = 75
+    Height = 21
+    Anchors = [akRight, akBottom]
+    Caption = #21462'    '#28040
+    ModalResult = 2
+    TabOrder = 2
+  end
+  object saGL: TsdGridDBA
+    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 = taLeftJustify
+        EditType = sgeCheckBox
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        Width = 35
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #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 = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Code'
+        Width = 50
+        ReadOnly = True
+      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 = 150
+        ReadOnly = True
+      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 = 45
+        ReadOnly = True
+      end
+      item
+        Title.Caption = #35268#26684
+        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 = 'Specs'
+        Width = 120
+        ReadOnly = True
+      end>
+    Grid = zgGL
+    ExtendRowCount = 0
+    Left = 112
+    Top = 136
+  end
+end

+ 109 - 0
Forms/SelectDetailGLsFrm.pas

@@ -0,0 +1,109 @@
+unit SelectDetailGLsFrm;
+
+interface
+
+uses
+  ProjectGLDm, sdDB,
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, ExtCtrls, StdCtrls, sdGridDBA, ZJGrid;
+
+type
+  TSelectDetailGLsForm = class(TForm)
+    pnlData: TPanel;
+    btnOk: TButton;
+    btnCancel: TButton;
+    leSearch: TLabeledEdit;
+    imgSearch: TImage;
+    zgGL: TZJGrid;
+    saGL: TsdGridDBA;
+    procedure zgGLGetCellText(Sender: TObject; const ACoord: TPoint;
+      var Value: String; DisplayText: Boolean);
+    procedure zgGLSetCellText(Sender: TObject; const ACoord: TPoint;
+      var Value: String; DisplayText: Boolean);
+    procedure btnOkClick(Sender: TObject);
+  private
+    FResults: TList;
+  public
+    constructor Create(AProjectGLData: TProjectGLData);
+    destructor Destroy; override;
+
+    property Results: TList read FResults;
+  end;
+
+function SelectDetailGLs(AProjectGLData: TProjectGLData; AGLs: TList): Boolean;
+
+implementation
+
+uses
+  UtilMethods;
+
+{$R *.dfm}
+
+function SelectDetailGLs(AProjectGLData: TProjectGLData; AGLs: TList): Boolean;
+var
+  SelectForm: TSelectDetailGLsForm;
+begin
+  SelectForm := TSelectDetailGLsForm.Create(AProjectGLData);
+  try
+    Result := SelectForm.ShowModal = mrOk;
+    if Result then
+      AGLs.Assign(SelectForm.Results);
+  finally
+    SelectForm.Free;
+  end;
+end;
+
+{ TAddDetailGLsForm }
+
+constructor TSelectDetailGLsForm.Create(AProjectGLData: TProjectGLData);
+begin
+  inherited Create(nil);
+  saGL.DataView := AProjectGLData.sdvProjectGL;
+  FResults := TList.Create;
+end;
+
+destructor TSelectDetailGLsForm.Destroy;
+begin
+  FResults.Free;
+  inherited;
+end;
+
+procedure TSelectDetailGLsForm.zgGLGetCellText(Sender: TObject;
+  const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+var
+  Rec: TsdDataRecord;
+begin
+  if (ACoord.X = 1) and (ACoord.Y > 0) then
+  begin
+    Rec := saGL.DataView.Records[ACoord.Y -1];
+    if Assigned(Rec) and (FResults.IndexOf(Rec) >= 0) then
+      Value := 'True'
+    else
+      Value := 'False';
+  end;
+end;
+
+procedure TSelectDetailGLsForm.zgGLSetCellText(Sender: TObject;
+  const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+var
+  Rec: TsdDataRecord;
+begin
+  if (ACoord.X = 1) and (ACoord.Y > 0) then
+  begin
+    Rec := saGL.DataView.Records[ACoord.Y -1];
+    if Value = 'True' then
+      FResults.Add(Rec)
+    else if Value = 'False' then
+      FResults.Remove(Rec);
+  end;
+end;
+
+procedure TSelectDetailGLsForm.btnOkClick(Sender: TObject);
+begin
+  if FResults.Count > 0 then
+    ModalResult := mrOk
+  else
+    TipMessage('ûÓÐÑ¡ÔñÈκι¤ÁÏ¡£');
+end;
+
+end.

+ 721 - 0
Frames/PriceMarginBillsFme.dfm

@@ -0,0 +1,721 @@
+object PriceMarginBillsFrame: TPriceMarginBillsFrame
+  Left = 0
+  Top = 0
+  Width = 1178
+  Height = 645
+  TabOrder = 0
+  object pnlBills: TPanel
+    Left = 0
+    Top = 0
+    Width = 1178
+    Height = 645
+    Align = alClient
+    BevelOuter = bvNone
+    TabOrder = 0
+    object sprDetail: TSplitter
+      Left = 0
+      Top = 435
+      Width = 1178
+      Height = 3
+      Cursor = crVSplit
+      Align = alBottom
+    end
+    object pnlGclBills: TPanel
+      Left = 0
+      Top = 0
+      Width = 1178
+      Height = 435
+      Align = alClient
+      BevelOuter = bvNone
+      TabOrder = 0
+      object zgGclBills: TZJGrid
+        Left = 0
+        Top = 0
+        Width = 1178
+        Height = 435
+        Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection]
+        OptionsEx = []
+        ColCount = 8
+        RowCount = 6
+        FixedRowCount = 2
+        ShowGridLine = False
+        DefaultColWidth = 73
+        DefaultFixedColWidth = 25
+        Selection.AlphaBlend = False
+        Selection.TransparentColor = False
+        FrozenCol = 0
+        FrozenRow = 0
+        Align = alClient
+      end
+    end
+    object pnlDetail: TPanel
+      Left = 0
+      Top = 438
+      Width = 1178
+      Height = 207
+      Align = alBottom
+      BevelOuter = bvNone
+      TabOrder = 1
+      object sprRela: TSplitter
+        Left = 638
+        Top = 0
+        Height = 207
+        Align = alRight
+      end
+      object pnlRelaData: TPanel
+        Left = 641
+        Top = 0
+        Width = 537
+        Height = 207
+        Align = alRight
+        BevelOuter = bvNone
+        TabOrder = 0
+        object pnlRelaTop: TPanel
+          Left = 0
+          Top = 0
+          Width = 537
+          Height = 21
+          Align = alTop
+          BevelOuter = bvNone
+          TabOrder = 0
+          object tbRelaTop: TToolBar
+            Left = 0
+            Top = 0
+            Width = 134
+            Height = 21
+            Align = alLeft
+            AutoSize = True
+            ButtonHeight = 21
+            ButtonWidth = 67
+            EdgeBorders = []
+            Flat = True
+            ShowCaptions = True
+            TabOrder = 0
+            object tobtnDetailGL: TToolButton
+              Left = 0
+              Top = 0
+              Caption = '  '#35843#24046#24037#26009'  '
+              Down = True
+              ImageIndex = 2
+              Style = tbsCheck
+            end
+            object tobtnParent: TToolButton
+              Tag = 1
+              Left = 67
+              Top = 0
+              Caption = #28165#21333#29238#39033
+              ImageIndex = 0
+              Style = tbsCheck
+            end
+          end
+        end
+        object jpsRela: TJimPages
+          Left = 0
+          Top = 21
+          Width = 537
+          Height = 186
+          ActivePage = jpsRelaDetailGL
+          ActivePageIndex = 0
+          Align = alClient
+          Caption = 'jpsRela'
+          object jpsRelaDetailGL: TJimPage
+            Left = 0
+            Top = 0
+            Width = 537
+            Height = 186
+            TabName = 'DetailGL'
+            Caption = 'DetailGL'
+            object zgDetailGL: TZJGrid
+              Left = 0
+              Top = 0
+              Width = 537
+              Height = 186
+              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
+              OnMouseDown = zgDetailGLMouseDown
+              Align = alClient
+            end
+          end
+          object jpsRelaBillsParent: TJimPage
+            Left = 0
+            Top = 0
+            Width = 537
+            Height = 186
+            TabName = 'BillsParent'
+            Caption = 'BillsParent'
+          end
+        end
+      end
+      object pnlDetailBills: TPanel
+        Left = 0
+        Top = 0
+        Width = 638
+        Height = 207
+        Align = alClient
+        BevelOuter = bvNone
+        TabOrder = 1
+        object labTitle: TJimGradLabel
+          Left = 0
+          Top = 0
+          Width = 638
+          Height = 20
+          Align = alTop
+          AutoSize = False
+          ColorBegin = clGradientInactiveCaption
+          ColorEnd = clGradientInactiveCaption
+          Caption = ' '#35814#32454#28165#21333
+          Font.Charset = GB2312_CHARSET
+          Font.Color = clWindowText
+          Font.Height = -12
+          Font.Name = #23435#20307
+          Font.Style = [fsBold]
+          ParentFont = False
+          Layout = tlCenter
+        end
+        object zgDetailGclBills: TZJGrid
+          Left = 0
+          Top = 20
+          Width = 638
+          Height = 187
+          Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection]
+          OptionsEx = []
+          ColCount = 12
+          RowCount = 6
+          FixedRowCount = 2
+          ShowGridLine = False
+          DefaultColWidth = 73
+          DefaultFixedColWidth = 25
+          Selection.AlphaBlend = False
+          Selection.TransparentColor = False
+          FrozenCol = 0
+          FrozenRow = 0
+          OnMouseDown = zgDetailGclBillsMouseDown
+          Align = alClient
+        end
+      end
+    end
+  end
+  object saGclBills: TsdGridDBA
+    Columns = <
+      item
+        Title.Caption = #28165#21333#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 = 'B_Code'
+        ReadOnly = True
+      end
+      item
+        Title.Caption = #21517#31216
+        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 = 'Name'
+        Width = 180
+        ReadOnly = True
+      end
+      item
+        Title.Caption = #21333#20301
+        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 = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Units'
+        Width = 45
+        ReadOnly = True
+      end
+      item
+        Title.Caption = #21333#20215
+        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 = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Price'
+        Width = 60
+        ReadOnly = True
+      end
+      item
+        Title.Caption = #26412#26399#35745#37327#25968#37327'|'#21512#21516
+        Title.CaptionAcrossCols = '3'
+        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 = 'CurDealQuantity'
+        Width = 65
+        ReadOnly = True
+      end
+      item
+        Title.Caption = '|'#25968#37327#21464#26356
+        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 = 'CurQcQuantity'
+        Width = 65
+        ReadOnly = True
+      end
+      item
+        Title.Caption = '|'#23567#35745
+        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 = 'CurGatherQuantity'
+        Width = 65
+        ReadOnly = True
+      end>
+    Grid = zgGclBills
+    ExtendRowCount = 3
+    Left = 112
+    Top = 96
+  end
+  object saDetailGclBills: TsdGridDBA
+    Columns = <
+      item
+        Title.Caption = #25152#23646#39033#30446#33410'|'#32534#21495
+        Title.CaptionAcrossCols = '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 = 'XmjCode'
+        Width = 80
+        ReadOnly = True
+      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 = 'XmjName'
+        ReadOnly = True
+      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 = 'XmjUnits'
+        Width = 45
+        ReadOnly = True
+      end
+      item
+        Title.Caption = #37096#20301#20449#24687'|'#26729#21495
+        Title.CaptionAcrossCols = '5'
+        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 = 'Peg'
+        Width = 80
+        ReadOnly = True
+      end
+      item
+        Title.Caption = '|'#21333#20301#24037#31243
+        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 = 'NameDanWei'
+        Width = 80
+        ReadOnly = True
+      end
+      item
+        Title.Caption = '|'#20998#37096#24037#31243
+        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 = 'NameFenBu'
+        Width = 80
+        ReadOnly = True
+      end
+      item
+        Title.Caption = '|'#20998#39033#24037#31243
+        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 = 'NameFenXiang'
+        Width = 80
+        ReadOnly = True
+      end
+      item
+        Title.Caption = '|'#35745#37327#21333#20803
+        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 = 'NameUnit'
+        Width = 80
+        ReadOnly = True
+      end
+      item
+        Title.Caption = #26412#26399#35745#37327#25968#37327'|'#21512#21516
+        Title.CaptionAcrossCols = '3'
+        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 = 'CurDealQuantity'
+        Width = 60
+        ReadOnly = True
+      end
+      item
+        Title.Caption = '|'#25968#37327#21464#26356
+        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 = 'CurQcQuantity'
+        Width = 60
+        ReadOnly = True
+      end
+      item
+        Title.Caption = '|'#23567#35745
+        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 = 'CurGatherQuantity'
+        Width = 60
+        ReadOnly = True
+      end>
+    Grid = zgDetailGclBills
+    ExtendRowCount = 3
+    Left = 96
+    Top = 496
+  end
+  object saDetailGL: TsdGridDBA
+    Columns = <
+      item
+        Title.Caption = #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 = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Code'
+        Width = 50
+        ReadOnly = True
+      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 = 120
+        ReadOnly = True
+      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 = 45
+        ReadOnly = True
+      end
+      item
+        Title.Caption = #25968#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 = 'Quantity'
+        Width = 60
+        ReadOnly = False
+      end>
+    Grid = zgDetailGL
+    ExtendRowCount = 3
+    Left = 728
+    Top = 504
+  end
+  object dxpmDetailGL: TdxBarPopupMenu
+    BarManager = MainForm.dxBarManager
+    ItemLinks = <
+      item
+        Item = MainForm.dxbtnAddDetailGLs
+        Visible = True
+      end
+      item
+        Item = MainForm.dxbtnDelete
+        Visible = True
+      end>
+    UseOwnFont = False
+    OnPopup = dxpmDetailGLPopup
+    Left = 768
+    Top = 504
+  end
+  object actnPriceMarginBills: TActionList
+    Images = MainForm.Images
+    Left = 160
+    Top = 96
+    object actnAddDetailGLs: TAction
+      Caption = #26032#22686#35843#24046#24037#26009
+      ImageIndex = 2
+      OnExecute = actnAddDetailGLsExecute
+    end
+    object actnCopyDetailGLs: TAction
+      Caption = #22797#21046#35843#24046#24037#26009
+      ImageIndex = 4
+    end
+    object actnApplyToSameBills: TAction
+      Caption = #24212#29992#35843#24046#24037#26009#33267#30456#21516#28165#21333
+      OnExecute = actnApplyToSameBillsExecute
+    end
+  end
+  object dxpmDetailGclBills: TdxBarPopupMenu
+    BarManager = MainForm.dxBarManager
+    ItemLinks = <
+      item
+        Item = MainForm.dxbtnApplyToSameBills
+        Visible = True
+      end
+      item
+        BeginGroup = True
+        Item = MainForm.dxbtnCopyDetailGls
+        Visible = True
+      end
+      item
+        Item = MainForm.dxbtnPaste
+        Visible = True
+      end>
+    UseOwnFont = False
+    OnPopup = dxpmDetailGclBillsPopup
+    Left = 136
+    Top = 496
+  end
+  object xpm: TXPMenu
+    DimLevel = 30
+    GrayLevel = 10
+    Font.Charset = DEFAULT_CHARSET
+    Font.Color = clMenuText
+    Font.Height = -12
+    Font.Name = #23435#20307
+    Font.Style = []
+    Color = clBtnFace
+    IconBackColor = clBtnFace
+    MenuBarColor = clBtnFace
+    SelectColor = 38640
+    SelectBorderColor = clHighlight
+    SelectFontColor = clMenuText
+    DisabledColor = clInactiveCaption
+    SeparatorColor = clBtnFace
+    CheckedColor = clHighlight
+    IconWidth = 24
+    DrawSelect = True
+    UseSystemColors = False
+    OverrideOwnerDraw = False
+    Gradient = False
+    FlatMenu = False
+    AutoDetect = True
+    XPControls = [xcToolbar]
+    Active = True
+    ControlUseTrueXPStyle = True
+    BtnRoundArc = 5
+    BtnOutLineBorderColor = 7552000
+    BtnInnerBorderMoveColor = 3257087
+    BtnInnerBorderFocusColor = 15183500
+    BtnSurfaceNormalColor = 16251903
+    BtnSurfaceDownColor = 14608359
+    BtnSurfaceBottomLineColor = 14608359
+    BtnSurfaceDownBottomLineColor = 15199215
+    RdoChkControlChkColor = 41472
+    ComboBoxChkColor = 9201994
+    ComboboxSurfaceMoveColor = 16771030
+    ControlDisabledBorderColor = 11913158
+    Left = 207
+    Top = 96
+  end
+end

+ 163 - 0
Frames/PriceMarginBillsFme.pas

@@ -0,0 +1,163 @@
+unit PriceMarginBillsFme;
+
+interface
+
+uses
+  SelectDetailGLsFrm,
+  PriceMarginBillsDm, ProjectGLDm, DetailGLDm, sdDB,
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, sdGridDBA, ZJGrid, ExtCtrls, StdCtrls, JimLabels, dxBar,
+  JimPages, ComCtrls, ToolWin, ActnList, XPMenu;
+
+type
+  TPriceMarginBillsFrame = class(TFrame)
+    pnlGclBills: TPanel;
+    pnlDetail: TPanel;
+    sprDetail: TSplitter;
+    zgGclBills: TZJGrid;
+    saGclBills: TsdGridDBA;
+    pnlRelaData: TPanel;
+    sprRela: TSplitter;
+    pnlDetailBills: TPanel;
+    labTitle: TJimGradLabel;
+    zgDetailGclBills: TZJGrid;
+    saDetailGclBills: TsdGridDBA;
+    pnlRelaTop: TPanel;
+    tbRelaTop: TToolBar;
+    tobtnDetailGL: TToolButton;
+    tobtnParent: TToolButton;
+    jpsRela: TJimPages;
+    jpsRelaDetailGL: TJimPage;
+    jpsRelaBillsParent: TJimPage;
+    zgDetailGL: TZJGrid;
+    saDetailGL: TsdGridDBA;
+    dxpmDetailGL: TdxBarPopupMenu;
+    pnlBills: TPanel;
+    actnPriceMarginBills: TActionList;
+    actnAddDetailGLs: TAction;
+    dxpmDetailGclBills: TdxBarPopupMenu;
+    actnCopyDetailGLs: TAction;
+    xpm: TXPMenu;
+    actnApplyToSameBills: TAction;
+    procedure zgDetailGLMouseDown(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: Integer);
+    procedure dxpmDetailGLPopup(Sender: TObject);
+    procedure actnAddDetailGLsExecute(Sender: TObject);
+    procedure dxpmDetailGclBillsPopup(Sender: TObject);
+    procedure actnApplyToSameBillsExecute(Sender: TObject);
+    procedure zgDetailGclBillsMouseDown(Sender: TObject;
+      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+  private
+    FPriceMarginBillsData: TPriceMarginBillsData;
+    FProjectGLData: TProjectGLData;
+    FDetailGLData: TDetailGLData;
+
+    procedure AddDetailGLs;
+  public
+    constructor Create(APriceMarginBillsData: TPriceMarginBillsData);
+    destructor Destroy; override;
+  end;
+
+implementation
+
+uses
+  UtilMethods, MainFrm, BillsTree, ProjectData;
+
+{$R *.dfm}
+
+{ TPriceMarginBillsFrame }
+
+constructor TPriceMarginBillsFrame.Create(
+  APriceMarginBillsData: TPriceMarginBillsData);
+begin
+  inherited Create(nil);
+  FPriceMarginBillsData := APriceMarginBillsData;
+  FProjectGLData := TProjectData(FPriceMarginBillsData.ProjectData).ProjectGLData;
+  FDetailGLData := TProjectData(FPriceMarginBillsData.ProjectData).DetailGLData;
+
+  saGclBills.DataView := APriceMarginBillsData.sdvGclBills;
+  saDetailGclBills.DataView := APriceMarginBillsData.sdvDetailGclBills;
+  saDetailGL.DataView := APriceMarginBillsData.sdvDetailGL;
+end;
+
+destructor TPriceMarginBillsFrame.Destroy;
+begin
+  inherited;
+end;
+
+procedure TPriceMarginBillsFrame.zgDetailGLMouseDown(Sender: TObject;
+  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+begin
+  if Button = mbRight then
+    dxpmDetailGL.PopupFromCursorPos;
+end;
+
+procedure TPriceMarginBillsFrame.dxpmDetailGLPopup(Sender: TObject);
+begin
+  SetDxBtnAction(actnAddDetailGLs, MainForm.dxbtnAddDetailGLs);
+end;
+
+procedure TPriceMarginBillsFrame.actnAddDetailGLsExecute(Sender: TObject);
+var
+  iID: Integer;
+  vNode: TBillsIDTreeNode;
+begin
+  iID := saDetailGclBills.DataView.Current.ValueByName('RelaBillsID').AsInteger;
+  vNode := TBillsIDTreeNode(FPriceMarginBillsData.MainBillsTree.FindNode(iID));
+  if not vNode.HasPriceMargin then
+    AddDetailGLs
+  else
+    ErrorMessage('当前清单已进行材料调差,不可再添加调差工料。');
+end;
+
+procedure TPriceMarginBillsFrame.AddDetailGLs;
+var
+  DetailGLs: TList;
+begin
+  DetailGLs := TList.Create;
+  try
+    if SelectDetailGLs(FProjectGLData, DetailGLs) then
+      FPriceMarginBillsData.AddDetailGLs(DetailGLs);
+  finally
+    DetailGLs.Free;
+  end;
+end;
+
+procedure TPriceMarginBillsFrame.dxpmDetailGclBillsPopup(Sender: TObject);
+begin
+  SetDxBtnAction(actnApplyToSameBills, MainForm.dxbtnApplyToSameBills);
+  SetDxBtnAction(actnCopyDetailGLs, MainForm.dxbtnCopyDetailGls);
+end;
+
+procedure TPriceMarginBillsFrame.actnApplyToSameBillsExecute(
+  Sender: TObject);
+var
+  CurRec, Rec: TsdDataRecord;
+  vGLs: TList;
+  iRec: Integer;
+begin
+  if saDetailGclBills.DataView.RecordCount = 1 then Exit;
+
+  vGLs := TList.Create;
+  try
+    CurRec := saDetailGclBills.DataView.Current;
+    FDetailGLData.LoadDetailGLs(CurRec.ValueByName('RelaBillsID').AsInteger, vGLs);
+    for iRec := 0 to saDetailGclBills.DataView.RecordCount - 1 do
+    begin
+      Rec := saDetailGclBills.DataView.Records[iRec];
+      if Rec <> CurRec then
+        FDetailGLData.ResetDetailGLs(Rec.ValueByName('RelaBillsID').AsInteger, vGLs);
+    end;
+  finally
+    vGLs.Free;
+  end;
+end;
+
+procedure TPriceMarginBillsFrame.zgDetailGclBillsMouseDown(Sender: TObject;
+  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+begin
+  if Button = mbRight then
+    dxpmDetailGclBills.PopupFromCursorPos;
+end;
+
+end.

+ 115 - 0
Frames/PriceMarginFme.dfm

@@ -0,0 +1,115 @@
+object PriceMarginFrame: TPriceMarginFrame
+  Left = 0
+  Top = 0
+  Width = 1109
+  Height = 591
+  TabOrder = 0
+  object pnlTopTag: TPanel
+    Left = 0
+    Top = 0
+    Width = 1109
+    Height = 21
+    Align = alTop
+    BevelOuter = bvNone
+    TabOrder = 0
+    object tbTopTag: TToolBar
+      Left = 0
+      Top = 0
+      Width = 134
+      Height = 21
+      Align = alLeft
+      AutoSize = True
+      ButtonHeight = 21
+      ButtonWidth = 67
+      EdgeBorders = []
+      Flat = True
+      ShowCaptions = True
+      TabOrder = 0
+      object tobtnGL: TToolButton
+        Left = 0
+        Top = 0
+        Caption = '  '#35843#24046#24037#26009'  '
+        Down = True
+        ImageIndex = 2
+        Style = tbsCheck
+        OnClick = tobtnBillsClick
+      end
+      object tobtnBills: TToolButton
+        Tag = 1
+        Left = 67
+        Top = 0
+        Caption = ' '#28165#21333#27719#24635' '
+        ImageIndex = 0
+        Style = tbsCheck
+        OnClick = tobtnBillsClick
+      end
+    end
+  end
+  object jpsPriceMargin: TJimPages
+    Left = 0
+    Top = 21
+    Width = 1109
+    Height = 570
+    ActivePage = jpsPriceMarginGL
+    ActivePageIndex = 0
+    Align = alClient
+    object jpsPriceMarginGL: TJimPage
+      Left = 0
+      Top = 0
+      Width = 1109
+      Height = 570
+      TabName = 'GL'
+      Caption = 'GL'
+    end
+    object jpsPriceMarginBills: TJimPage
+      Left = 0
+      Top = 0
+      Width = 1109
+      Height = 570
+      TabName = 'Bills'
+      Caption = 'Bills'
+    end
+  end
+  object xpm: TXPMenu
+    DimLevel = 30
+    GrayLevel = 10
+    Font.Charset = DEFAULT_CHARSET
+    Font.Color = clMenuText
+    Font.Height = -12
+    Font.Name = #23435#20307
+    Font.Style = []
+    Color = clBtnFace
+    IconBackColor = clBtnFace
+    MenuBarColor = clBtnFace
+    SelectColor = 38640
+    SelectBorderColor = clHighlight
+    SelectFontColor = clMenuText
+    DisabledColor = clInactiveCaption
+    SeparatorColor = clBtnFace
+    CheckedColor = clHighlight
+    IconWidth = 24
+    DrawSelect = True
+    UseSystemColors = False
+    OverrideOwnerDraw = False
+    Gradient = False
+    FlatMenu = False
+    AutoDetect = True
+    XPControls = [xcToolbar]
+    Active = True
+    ControlUseTrueXPStyle = True
+    BtnRoundArc = 5
+    BtnOutLineBorderColor = 7552000
+    BtnInnerBorderMoveColor = 3257087
+    BtnInnerBorderFocusColor = 15183500
+    BtnSurfaceNormalColor = 16251903
+    BtnSurfaceDownColor = 14608359
+    BtnSurfaceBottomLineColor = 14608359
+    BtnSurfaceDownBottomLineColor = 15199215
+    RdoChkControlChkColor = 41472
+    ComboBoxChkColor = 9201994
+    ComboboxSurfaceMoveColor = 16771030
+    ControlDisabledBorderColor = 11913158
+    Left = 279
+    Top = 56
+  end
+end

+ 74 - 0
Frames/PriceMarginFme.pas

@@ -0,0 +1,74 @@
+unit PriceMarginFme;
+
+interface
+
+uses
+  ProjectGLFme, PriceMarginBillsFme,
+  ProjectData,
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, ExtCtrls, JimPages, ComCtrls, ToolWin, XPMenu;
+
+type
+  TPriceMarginFrame = class(TFrame)
+    pnlTopTag: TPanel;
+    tbTopTag: TToolBar;
+    tobtnBills: TToolButton;
+    tobtnGL: TToolButton;
+    jpsPriceMargin: TJimPages;
+    jpsPriceMarginBills: TJimPage;
+    jpsPriceMarginGL: TJimPage;
+    xpm: TXPMenu;
+    procedure tobtnBillsClick(Sender: TObject);
+  private
+    FProjectData: TProjectData;
+
+    FProjectGLFrame: TProjectGLFrame;
+    FPriceMarginBillsFrame: TPriceMarginBillsFrame;
+  public
+    constructor Create(AProjectData: TProjectData);
+    destructor Destroy; override;
+
+    procedure RefreshBills;
+  end;
+
+implementation
+
+uses
+  UtilMethods;
+
+{$R *.dfm}
+
+{ TPriceMarginFrame }
+
+constructor TPriceMarginFrame.Create(AProjectData: TProjectData);
+begin
+  inherited Create(nil);
+  FProjectData := AProjectData;
+
+  FProjectGLFrame := TProjectGLFrame.Create(FProjectData.ProjectGLData);
+  AlignControl(FProjectGLFrame, jpsPriceMarginGL, alClient);
+
+  FPriceMarginBillsFrame := TPriceMarginBillsFrame.Create(FProjectData.PriceMarginBillsData);
+  AlignControl(FPriceMarginBillsFrame, jpsPriceMarginBills, alClient);
+end;
+
+destructor TPriceMarginFrame.Destroy;
+begin
+  FPriceMarginBillsFrame.Free;
+  FProjectGLFrame.Free;
+  inherited;
+end;
+
+procedure TPriceMarginFrame.RefreshBills;
+begin
+  FProjectData.PriceMarginBillsData.RefreshBills;
+end;
+
+procedure TPriceMarginFrame.tobtnBillsClick(Sender: TObject);
+begin
+  tobtnGL.Down := tobtnGL.Tag = TToolButton(Sender).Tag;
+  tobtnBills.Down := tobtnBills.Tag = TToolButton(Sender).Tag;
+  jpsPriceMargin.ActivePageIndex := TToolButton(Sender).Tag;
+end;
+
+end.

+ 35 - 8
Frames/ProjectFme.dfm

@@ -67,24 +67,33 @@ object ProjectFrame: TProjectFrame
               Tag = 2
             end
             item
+              Caption = #26448#26009#35843#24046
+              Index = 3
+              IsDefault = False
+              LargeImage = 4
+              SmallImage = 4
+              StoredItem = xbiPriceMargin
+              Tag = 3
+            end
+            item
               Caption = #23457#26680#27604#36739
               Hint = #23457#26680#27604#36739
-              Index = 3
+              Index = 4
               IsDefault = False
               LargeImage = 3
               SmallImage = 3
               StoredItem = xbiStageCompare
-              Tag = 3
+              Tag = 4
             end
             item
               Caption = #25253#34920
               Hint = #25253#34920
-              Index = 4
+              Index = 5
               IsDefault = False
               LargeImage = 6
               SmallImage = 6
               StoredItem = xbiReport
-              Tag = 4
+              Tag = 5
             end>
         end>
       ActiveGroupIndex = 0
@@ -2831,6 +2840,15 @@ object ProjectFrame: TProjectFrame
         TabName = 'BillsGather'
         Caption = 'PhaseCompare'
       end
+      object jpsMainPriceMargin: TJimPage
+        Tag = -1
+        Left = 0
+        Top = 0
+        Width = 903
+        Height = 415
+        TabName = 'PriceMargin'
+        Caption = 'PriceMargin'
+      end
       object jpsMainStageCompare: TJimPage
         Tag = -1
         Left = 0
@@ -3110,6 +3128,7 @@ object ProjectFrame: TProjectFrame
       #35745#37327#21488#36134
       #28165#21333#27719#24635
       #23457#26680#27604#36739
+      #26448#26009#35843#24046
       #24418#35937#36827#24230
       #25253#34920)
     DefaultLargeImage = -1
@@ -3136,7 +3155,7 @@ object ProjectFrame: TProjectFrame
       SmallImage = 2
     end
     object xbiStageCompare: TdxStoredSideItem
-      Tag = 3
+      Tag = 4
       Caption = #23457#26680#27604#36739
       Category = 3
       Enabled = True
@@ -3147,16 +3166,16 @@ object ProjectFrame: TProjectFrame
     object xbiCompleteDegree: TdxStoredSideItem
       Tag = -1
       Caption = #24418#35937#36827#24230
-      Category = 4
+      Category = 5
       Enabled = True
       Hint = #24418#35937#36827#24230
       LargeImage = 5
       SmallImage = 5
     end
     object xbiReport: TdxStoredSideItem
-      Tag = 4
+      Tag = 5
       Caption = #25253#34920
-      Category = 5
+      Category = 6
       Enabled = True
       Hint = #25253#34920
       LargeImage = 6
@@ -3170,6 +3189,14 @@ object ProjectFrame: TProjectFrame
       LargeImage = 1
       SmallImage = 1
     end
+    object xbiPriceMargin: TdxStoredSideItem
+      Tag = 3
+      Caption = #26448#26009#35843#24046
+      Category = 4
+      Enabled = True
+      LargeImage = 4
+      SmallImage = 4
+    end
   end
   object ilstLarge: TImageList
     Height = 32

+ 28 - 10
Frames/ProjectFme.pas

@@ -6,6 +6,7 @@ uses
   BillsCompileFme, BillsMeasureFme, PhaseCompareFme, DealPaymentFme,
   BillsGatherFme, ZJJLFme, BGLFme, ReportsFrm, SearchFme, BookmarkFme,
   ProjectData, UtilMethods, Globals, mEncryptEditions, DealBillsFme,
+  PriceMarginFme,
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, ImgList, XPMenu, Buttons, ComCtrls, ToolWin, ExtCtrls, JimPages,
   StdCtrls, JimCombos, dxsbar, ActnList, dxBar, OrderCheckerFme, CheckerFme,
@@ -77,6 +78,8 @@ type
     tobtnUpFile: TToolButton;
     jpsAssistantDealBills: TJimPage;
     tobtnDealBills: TToolButton;
+    jpsMainPriceMargin: TJimPage;
+    xbiPriceMargin: TdxStoredSideItem;
     procedure tobtnStandardBillsClick(Sender: TObject);
     procedure jcbPhaseChanged(Sender: TObject);
     procedure sbtnExpendClick(Sender: TObject);
@@ -99,8 +102,9 @@ type
 
     FBillsCompileFrame: TBillsCompileFrame;
     FBillsMeasureFrame: TBillsMeasureFrame;
-    FPhaseCompareFrame: TPhaseCompareFrame;
     FBillsGatherFrame: TBillsGatherFrame;
+    FPriceMarginFrame: TPriceMarginFrame;
+    FPhaseCompareFrame: TPhaseCompareFrame;
     FCheckerFrame: TCheckerFrame;
 
     FDealPaymentFrame: TDealPaymentFrame;
@@ -114,6 +118,7 @@ type
     procedure CreateBillsFrame;
     procedure CreateDealPaymentFrame;
     procedure CreateBillsGatherFrame;
+    procedure CreatePriceMarginFrame;
     procedure CreateCheckerFrame;
     procedure CreateUpFile;
     procedure CreateFrames;
@@ -171,6 +176,7 @@ type
     property BillsCompileFrame: TBillsCompileFrame read FBillsCompileFrame;
     property BillsMeasureFrame: TBillsMeasureFrame read FBillsMeasureFrame;
     property BillsGatherFrame: TBillsGatherFrame read FBillsGatherFrame;
+    property PriceMarginFrame: TPriceMarginFrame read FPriceMarginFrame;
 
     property CheckerFrame: TCheckerFrame read FCheckerFrame;
     property UpFileManageView: TUpFileManageView read FUpFileManageView write SetUpFileManageView;
@@ -480,6 +486,8 @@ procedure TProjectFrame.dxsbViewControlItemClick(Sender: TObject;
                           or (Item.Tag = xbiBillsMeasure.Tag);
     tobtnBGL.Visible := Item.Tag = xbiBillsMeasure.Tag;
     tobtnZJJL.Visible := Item.Tag = xbiBillsMeasure.Tag;
+    // 控制整个按钮工具栏显示,
+    pnlToolBar.Visible := pnlPhaseSelect.Visible or tbExpand.Visible or tbToolsButton.Visible;
     // 根据当前View控制右侧按钮是否按下,右侧工具窗是否弹开
     jpsAssistant.ActivePageIndex := jpsMain.ActivePage.Tag;
     sbtnExpend.Tag := jpsMain.ActivePage.Tag;
@@ -499,14 +507,17 @@ procedure TProjectFrame.dxsbViewControlItemClick(Sender: TObject;
     // 切换至清单汇总,须重新汇总
     if Item.Tag = xbiBillsGather.Tag then
       BillsGatherFrame.RefreshBills;
+    // 切换至材料调差,须重新汇总展示调差清单
+    if Item.Tag = xbiPriceMargin.Tag then
+      PriceMarginFrame.RefreshBills;
 
     if G_IsCloud then
       if (Item.Tag = xbiBillsCompile.Tag) or (Item.Tag = xbiBillsMeasure.Tag) then
         CheckUpFile;
 
-      tobtnUpFile.Enabled := Item.Tag = xbiBillsMeasure.Tag;
-      if (tobtnUpFile.Enabled = False) and (jpsAssistant.ActivePage = jpsAssistantUpFile) then
-        jpsAssistant.ActivePage := jpsAssistantStandardBills;
+    tobtnUpFile.Enabled := Item.Tag = xbiBillsMeasure.Tag;
+    if (tobtnUpFile.Enabled = False) and (jpsAssistant.ActivePage = jpsAssistantUpFile) then
+      jpsAssistant.ActivePage := jpsAssistantStandardBills;
   end;
 
   procedure ChangeView;
@@ -514,7 +525,7 @@ procedure TProjectFrame.dxsbViewControlItemClick(Sender: TObject;
     BeforeChangeView;
     case Item.Tag of
       0, 2: jpsMain.ActivePageIndex := Item.Tag;
-      1: if CheckMeasureEdition then jpsMain.ActivePageIndex := Item.Tag;
+      1, 3: if CheckMeasureEdition then jpsMain.ActivePageIndex := Item.Tag;
       //2: if CheckPlanEdition then jpsMain.ActivePageIndex := Item.Tag;
     end;
     AfterChangeView;
@@ -558,13 +569,13 @@ procedure TProjectFrame.dxsbViewControlItemClick(Sender: TObject;
 begin
   if Item.Tag = jpsMain.ActivePageIndex then Exit;
 
-  if (Item.Tag in [0..2]) and (jpsMain.ActivePageIndex = 3) then
+  if (Item.Tag in [0..3]) and (jpsMain.ActivePageIndex = 4) then
     CloseCompare;
-    
+
   case Item.Tag of
-    0..2: ChangeView;
-    3: DisplayCompare;
-    4: DisplayReports;
+    0..3: ChangeView;
+    4: DisplayCompare;
+    5: DisplayReports;
   end;
 end;
 
@@ -1080,6 +1091,7 @@ begin
   UpdateSysProgress(140, '正在解析数据');
   CreateBillsGatherFrame;
   UpdateSysProgress(150, '正在解析数据');
+  CreatePriceMarginFrame;
 
   FZJJLFrame := TZJJLFrame.Create(Self, FProjectData.PhaseData.ZJJLData);
   FZJJLFrame.DataReadOnly := FProjectData.PhaseData.StageDataReadOnly;
@@ -1339,4 +1351,10 @@ begin
   end;
 end;
 
+procedure TProjectFrame.CreatePriceMarginFrame;
+begin
+  FPriceMarginFrame := TPriceMarginFrame.Create(FProjectData);
+  AlignControl(FPriceMarginFrame, jpsMainPriceMargin, alClient);
+end;
+
 end.

+ 203 - 0
Frames/ProjectGLFme.dfm

@@ -0,0 +1,203 @@
+object ProjectGLFrame: TProjectGLFrame
+  Left = 0
+  Top = 0
+  Width = 665
+  Height = 313
+  TabOrder = 0
+  object zgProjectGL: TZJGrid
+    Left = 0
+    Top = 0
+    Width = 665
+    Height = 313
+    Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection]
+    OptionsEx = []
+    ColCount = 9
+    RowCount = 6
+    FixedRowCount = 2
+    ShowGridLine = False
+    DefaultColWidth = 73
+    DefaultFixedColWidth = 25
+    Selection.AlphaBlend = False
+    Selection.TransparentColor = False
+    FrozenCol = 0
+    FrozenRow = 0
+    OnMouseDown = zgProjectGLMouseDown
+    Align = alClient
+  end
+  object saProjectGL: TsdGridDBA
+    Columns = <
+      item
+        Title.Caption = #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 = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Code'
+        Width = 60
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21517#31216
+        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 = 'Name'
+        Width = 150
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21333#20301
+        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 = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Units'
+        Width = 45
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #35268#26684
+        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 = 'Specs'
+        Width = 60
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #22522#20934#20215
+        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 = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'BasePrice'
+        Width = 60
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #39118#38505#24133#24230
+        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 = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'RiskRange'
+        Width = 60
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #26412#26399#20449#24687#20215'|'#20215#26684
+        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 = 'InfoPrice'
+        Width = 60
+        ReadOnly = False
+      end
+      item
+        Title.Caption = '|'#26102#38388
+        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 = 'InfoDate'
+        ReadOnly = False
+      end>
+    Grid = zgProjectGL
+    ExtendRowCount = 3
+    Left = 96
+    Top = 88
+  end
+  object dxpmProjectGL: TdxBarPopupMenu
+    BarManager = MainForm.dxBarManager
+    ItemLinks = <
+      item
+        Item = MainForm.dxbtnCopy
+        Visible = True
+      end
+      item
+        Item = MainForm.dxbtnPaste
+        Visible = True
+      end
+      item
+        BeginGroup = True
+        Item = MainForm.dxbtnDelete
+        Visible = True
+      end>
+    UseOwnFont = False
+    Left = 152
+    Top = 88
+  end
+end

+ 49 - 0
Frames/ProjectGLFme.pas

@@ -0,0 +1,49 @@
+unit ProjectGLFme;
+
+interface
+
+uses
+  ProjectGLDm,
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
+  Dialogs, sdGridDBA, ZJGrid, dxBar;
+
+type
+  TProjectGLFrame = class(TFrame)
+    zgProjectGL: TZJGrid;
+    saProjectGL: TsdGridDBA;
+    dxpmProjectGL: TdxBarPopupMenu;
+    procedure zgProjectGLMouseDown(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: Integer);
+  private
+    FProjectGLData: TProjectGLData;
+  public
+    constructor Create(AProjectGLData: TProjectGLData);
+    destructor Destroy; override;
+  end;
+
+implementation
+
+{$R *.dfm}
+
+{ TProjectGLFrame }
+
+constructor TProjectGLFrame.Create(AProjectGLData: TProjectGLData);
+begin
+  inherited Create(nil);
+  FProjectGLData := AProjectGLData;
+  saProjectGL.DataView := FProjectGLData.sdvProjectGL;
+end;
+
+destructor TProjectGLFrame.Destroy;
+begin
+  inherited;
+end;
+
+procedure TProjectGLFrame.zgProjectGLMouseDown(Sender: TObject;
+  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+begin
+  if Button = mbRight then
+    dxpmProjectGL.PopupFromCursorPos;
+end;
+
+end.

+ 68 - 2
Units/DataBaseTables.pas

@@ -399,6 +399,70 @@ const
     (FieldName: 'TotalPrice'; FieldType: ftDouble; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
   );
 
+  {调差工料}
+  SProjectGL = 'ProjectGL';
+  tdProjectGL: array [0..12] of TScFieldDef =(
+    (FieldName: 'ID'; FieldType: ftInteger; Size: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
+    // 工料机编号
+    (FieldName: 'Code'; FieldType: ftInteger; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 名称
+    (FieldName: 'Name'; FieldType: ftString; Size: 200; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 单位
+    (FieldName: 'Units'; FieldType: ftString; Size: 20; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 规格
+    (FieldName: 'Specs'; FieldType: ftString; Size: 200; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 基准价
+    (FieldName: 'BasePrice'; FieldType: ftDouble; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 风险幅度
+    (FieldName: 'RiskRange'; FieldType: ftDouble; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 锁定期号: 取值范围0~50, 0表示未锁定, 1~50表示在第1~50期锁定
+    (FieldName: 'LockedPhaseID'; FieldType: ftInteger; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 锁定阶段号: 取值范围-1~14, -1表示未锁定, 0表示原报锁定, 1~14表示在1~14审锁定
+    (FieldName: 'LockedStageID'; FieldType: ftInteger; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 创建期号: 取值范围0~50, 0
+    (FieldName: 'CreatePhaseID'; FieldType: ftInteger; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'CreateStageID'; FieldType: ftInteger; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 当期信息价
+    (FieldName: 'InfoPrice'; FieldType: ftDouble; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 当期信息价--时间
+    (FieldName: 'InfoDate'; FieldType: ftString; Size: 20; NotNull: False; PrimaryKey: False; ForceUpdate: False)
+  );
+
+  {调差工料--信息价}
+  SGLPrice = 'GLPrice';
+  tdGLPrice: array [0..3] of TScFieldDef =(
+    // 工料ID
+    (FieldName: 'GLID'; FieldType: ftInteger; Size: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
+    // 期号
+    (FieldName: 'PhaseID'; FieldType: ftInteger; Size: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
+    // 信息价
+    (FieldName: 'InfoPrice'; FieldType: ftDouble; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 信息价--时间
+    (FieldName: 'InfoDate'; FieldType: ftString; Size: 20; NotNull: False; PrimaryKey: False; ForceUpdate: False)
+  );
+
+  {清单使用的工料}
+  SDetailGL = 'DetailGL';
+  tdDetailGL: array [0..9] of TScFieldDef =(
+    (FieldName: 'ID'; FieldType: ftInteger; Size: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
+    // 清单ID
+    (FieldName: 'BillsID'; FieldType: ftInteger; Size: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False),
+    // 工料ID
+    (FieldName: 'GLID'; FieldType: ftInteger; Size: 0; NotNull: True; PrimaryKey: False; ForceUpdate: False),
+    // 工料机编号
+    (FieldName: 'Code'; FieldType: ftInteger; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 消耗量
+    (FieldName: 'Quantity'; FieldType: ftDouble; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 创建期号
+    (FieldName: 'CreatePhaseID'; FieldType: ftInteger; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 创建阶段
+    (FieldName: 'CreateStageID'; FieldType: ftInteger; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // ------ Cache Data
+    (FieldName: 'PM_PreTotalPrice'; FieldType: ftDouble; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'PM_CurTotalPrice'; FieldType: ftDouble; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'PM_EndTotalPrice'; FieldType: ftDouble; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
+  );
+
   {各期总数据 -- 为更新项目管理而储存的缓存数据}
   SMainDataList = 'MainDataList';
   tdMainDataList: array [0..15] of TScFieldDef =(
@@ -445,7 +509,7 @@ const
   // ......
   SRefer = 'Refer';
   SAudit = 'Audit';
-  tdRefer_Audit: array [0..44] of TScFieldDef = (
+  tdRefer_Audit: array [0..45] of TScFieldDef = (
     (FieldName: 'BillsID'; FieldType: ftInteger; Size: 0; NotNull: True; PrimaryKey: True; ForceUpdate: False),
     //------------------   本期合同计量  ----------------
     // 数量
@@ -549,7 +613,9 @@ const
     // 附件 暂时不用,用台帐的
 //    (FieldName: 'HasAttachment'; FieldType: ftBoolean; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
     // 书签批注
-    (FieldName: 'MarkMemo'; FieldType: ftString; Size: 255; NotNull: False; PrimaryKey: False; ForceUpdate: False)
+    (FieldName: 'MarkMemo'; FieldType: ftString; Size: 255; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    // 本期材料调差
+    (FieldName: 'PriceMarginTotalPrice'; FieldType: ftDouble; Size: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
   );
 
   // 计量期合同支付

+ 776 - 0
Units/GclBillsGatherModel.pas

@@ -0,0 +1,776 @@
+unit GclBillsGatherModel;
+// 单项目的工程量清单汇总
+
+interface
+
+uses
+  Classes, mDataRecord, BillsTree;
+
+type
+  TGatherDataWriteEvent = procedure (AGLJs: TList) of object;
+
+  TDetailGclNode = class
+  private
+    FID: Integer;
+    FBillsID: Integer;
+    FTreeSerialNo: Integer;
+
+    FLeafXmjID: Integer;
+    FXmjCode: string;
+    FXmjName: string;
+    FXmjUnits: string;
+    FPeg: string;
+    FNameDanWei: string;
+    FNameFenBu: string;
+    FNameFenXiang: string;
+    FNameUnit: string;
+    FPosition: string;
+    FDrawingCode: string;
+
+    FQuantity: Double;
+    FTotalPrice: Double;
+
+    FCurDealQuantity: Double;
+    FCurDealTotalPrice: Double;
+    FCurQcQuantity: Double;
+    FCurQcTotalPrice: Double;
+    FCurGatherQuantity: Double;
+    FCurGatherTotalPrice: Double;
+
+    FPreDealQuantity: Double;
+    FPreDealTotalPrice: Double;
+    FPreQcQuantity: Double;
+    FPreQcTotalPrice: Double;
+    FPreGatherQuantity: Double;
+    FPreGatherTotalPrice: Double;
+  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 Quantity: Double read FQuantity write FQuantity;
+    property TotalPrice: Double read FTotalPrice write FTotalPrice;
+
+    property CurDealQuantity: Double read FCurDealQuantity write FCurDealQuantity;
+    property CurDealTotalPrice: Double read FCurDealTotalPrice write FCurDealTotalPrice;
+    property CurQcQuantity: Double read FCurQcQuantity write FCurQcQuantity;
+    property CurQcTotalPrice: Double read FCurQcTotalPrice write FCurQcTotalPrice;
+    property CurGatherQuantity: Double read FCurGatherQuantity write FCurGatherQuantity;
+    property CurGatherTotalPrice: Double read FCurGatherTotalPrice write FCurGatherTotalPrice;
+
+    property PreDealQuantity: Double read FPreDealQuantity write FPreDealQuantity;
+    property PreDealTotalPrice: Double read FPreGatherTotalPrice write FPreGatherTotalPrice;
+    property PreQcQuantity: Double read FPreQcQuantity write FPreQcQuantity;
+    property PreQcTotalPrice: Double read FPreQcTotalPrice write FPreQcTotalPrice;
+    property PreGatherQuantity: Double read FPreGatherQuantity write FPreGatherQuantity;
+    property PreGatherTotalPrice: Double read FPreGatherTotalPrice write FPreGatherTotalPrice;
+  end;
+
+  TDetailDealNode = class
+  private
+    FID: Integer;
+    FDealID: Integer;
+
+    FQuantity: Double;
+    FTotalPrice: Double;
+  public
+    constructor Create(AID: Integer);
+
+    property ID: Integer read FID;
+    property DealID: Integer read FDealID write FDealID;
+
+    property Quantity: Double read FQuantity write FQuantity;
+    property TotalPrice: Double read FTotalPrice write FTotalPrice;
+  end;
+
+  TDetailBGLNode = class
+  private
+    FID: Integer;
+    FBGLID: Integer;
+
+    FQuantity: Double;
+    FTotalPrice: Double;
+  public
+    constructor Create(AID: Integer);
+
+    property ID: Integer read FID;
+    property BGLID: Integer read FBGLID;
+
+    property Quantity: Double read FQuantity write FQuantity;
+    property TotalPrice: Double read FTotalPrice write FTotalPrice;
+  end;
+
+  TGclNode = class
+  private
+    FDetailGcls: TList;
+    FDetailDeals: TList;
+    FDetailBGLs: TList;
+
+    FID: Integer;
+
+    FB_Code: string;
+    FIndexCode: string;
+    FName: string;
+    FUnits: string;
+    FPrice: Double;
+
+    FQuantity: Double;
+    FTotalPrice: Double;
+
+    FCurDealQuantity: Double;
+    FCurDealTotalPrice: Double;
+    FCurQcQuantity: Double;
+    FCurQcTotalPrice: Double;
+    FCurGatherQuantity: Double;
+    FCurGatherTotalPrice: Double;
+
+    FPreDealQuantity: Double;
+    FPreDealTotalPrice: Double;
+    FPreQcQuantity: Double;
+    FPreQcTotalPrice: Double;
+    FPreGatherQuantity: Double;
+    FPreGatherTotalPrice: Double;
+
+    FDealQuantity: Double;
+    FDealTotalPrice: Double;
+
+    FBGLQuantity: Double;
+    FBGLTotalPrice: Double;
+
+    procedure InitCalculate;
+    procedure GatherDetailGcl;
+    procedure GatherDetailDeal;
+    procedure GatherDetailBGL;
+
+    procedure SetB_Code(const Value: string);
+    function GetDetailBGL(AIndex: Integer): TDetailBGLNode;
+    function GetDetailBGLCount: Integer;
+    function GetDetailDeal(AIndex: Integer): TDetailDealNode;
+    function GetDetailDealCount: Integer;
+    function GetDetailGcl(AIndex: Integer): TDetailGclNode;
+    function GetDetailGclCount: Integer;
+  public
+    constructor Create(AID: Integer);
+    destructor Destroy; override;
+
+    function AddDetailGcl(AID: Integer): TDetailGclNode;
+    function AddDetailDeal(AID: Integer): TDetailDealNode;
+    function AddDetailBGL(AID: Integer): TDetailBGLNode;
+
+    procedure Calculate;
+
+    property ID: Integer read FID;
+
+    property B_Code: string read FB_Code write SetB_Code;
+    property IndexCode: string read FIndexCode;
+    property Name: string read FName write FName;
+    property Units: string read FUnits write FUnits;
+    property Price: Double read FPrice write FPrice;
+
+    property Quantity: Double read FQuantity write FQuantity;
+    property TotalPrice: Double read FTotalPrice write FTotalPrice;
+
+    property CurDealQuantity: Double read FCurDealQuantity write FCurDealQuantity;
+    property CurDealTotalPrice: Double read FCurDealTotalPrice write FCurDealTotalPrice;
+    property CurQcQuantity: Double read FCurQcQuantity write FCurQcQuantity;
+    property CurQcTotalPrice: Double read FCurQcTotalPrice write FCurQcTotalPrice;
+    property CurGatherQuantity: Double read FCurGatherQuantity write FCurGatherQuantity;
+    property CurGatherTotalPrice: Double read FCurGatherTotalPrice write FCurGatherTotalPrice;
+
+    property PreDealQuantity: Double read FPreDealQuantity write FPreDealQuantity;
+    property PreDealTotalPrice: Double read FPreGatherTotalPrice write FPreGatherTotalPrice;
+    property PreQcQuantity: Double read FPreQcQuantity write FPreQcQuantity;
+    property PreQcTotalPrice: Double read FPreQcTotalPrice write FPreQcTotalPrice;
+    property PreGatherQuantity: Double read FPreGatherQuantity write FPreGatherQuantity;
+    property PreGatherTotalPrice: Double read FPreGatherTotalPrice write FPreGatherTotalPrice;
+
+    property DealQuantity: Double read FDealQuantity write FDealQuantity;
+    property DealTotalPrice: Double read FDealTotalPrice write FDealTotalPrice;
+
+    property BGLQuantity: Double read FBGLQuantity write FBGLQuantity;
+    property BGLTotalPrice: Double read FBGLTotalPrice write FBGLTotalPrice;
+
+    property DetailGclCount: Integer read GetDetailGclCount;
+    property DetailGcl[AIndex: Integer]: TDetailGclNode read GetDetailGcl;
+
+    property DetailDealCount: Integer read GetDetailDealCount;
+    property DetailDeal[AIndex: Integer]: TDetailDealNode read GetDetailDeal;
+
+    property DetailBGLCount: Integer read GetDetailBGLCount;
+    property DetailBGL[AIndex: Integer]: TDetailBGLNode read GetDetailBGL;
+  end;
+
+  TGclGatherModel = class
+  private
+    FProjectData: TObject;
+    FBillsTree: TBillsIDTree;
+    FGatherDeal: Boolean;
+    FGatherBGL: Boolean;
+
+    FGcls: TList;
+    FNewGclID: Integer;
+    FNewDetailGclID: Integer;
+    FNewDetailDealID: Integer;
+    FNewDetailBGLID: Integer;
+
+    FWriteGatherData: TGatherDataWriteEvent;
+
+    procedure BeginGather;
+    procedure EndGather;
+
+    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;
+    function GetGclNode(ARec: TBillsRecord): TGclNode; overload;
+
+    procedure AddBillsNode(ANode: TBillsIDTreeNode);
+    procedure GatherBillsData;
+    procedure GatherDealData;
+    procedure GatherBGLData;
+
+    procedure CalculateAll;
+
+    function GetNewDetailBGLID: Integer;
+    function GetNewDetailDealID: Integer;
+    function GetNewDetailGclID: Integer;
+  public
+    constructor Create(AProjectData: TObject);
+    destructor Destroy; override;
+
+    procedure Execute;
+
+    property GatherDeal: Boolean read FGatherDeal write FGatherDeal;
+    property GatherBGL: Boolean read FGatherBGL write FGatherBGL;
+
+    property NewDetailGclID: Integer read GetNewDetailGclID;
+    property NewDetailDealID: Integer read GetNewDetailDealID;
+    property NewDetailBGLID: Integer read GetNewDetailBGLID;
+
+    // 在使用汇总模型的数据单元创建数据库写入方法,并赋值,否则汇总数据不写入
+    property WriteGatherData: TGatherDataWriteEvent read FWriteGatherData write FWriteGatherData;
+  end;
+
+implementation
+
+uses
+  ZhAPI, SysUtils, ProjectData, UtilMethods, sdDB, sdIDTree;
+
+{ 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;
+begin
+  vGclNode := GetGclNode(ANode.Rec);
+  vDetailGclNode := vGclNode.AddDetailGcl(NewDetailGclID);
+  vDetailGclNode.BillsID := ANode.ID;
+  vDetailGclNode.TreeSerialNo := ANode.MajorIndex;
+
+  vDetailGclNode.Quantity := ANode.Rec.Quantity.AsFloat;
+  vDetailGclNode.TotalPrice := ANode.Rec.TotalPrice.AsFloat;
+
+  if Assigned(ANode.StageRec) then
+  begin
+    vDetailGclNode.CurDealQuantity := ANode.StageRec.DealQuantity.AsFloat;
+    vDetailGclNode.CurDealTotalPrice := ANode.StageRec.DealTotalPrice.AsFloat;
+    vDetailGclNode.CurQcQuantity := ANode.StageRec.QcQuantity.AsFloat;
+    vDetailGclNode.CurQcTotalPrice := ANode.StageRec.QcTotalPrice.AsFloat;
+    vDetailGclNode.CurGatherQuantity := ANode.StageRec.GatherQuantity.AsFloat;
+    vDetailGclNode.CurGatherTotalPrice := ANode.StageRec.GatherTotalPrice.AsFloat;
+
+    vDetailGclNode.PreDealQuantity := ANode.StageRec.PreDealQuantity.AsFloat;
+    vDetailGclNode.PreDealTotalPrice := ANode.StageRec.PreDealTotalPrice.AsFloat;
+    vDetailGclNode.PreQcQuantity := ANode.StageRec.PreQcQuantity.AsFloat;
+    vDetailGclNode.PreQcTotalPrice := ANode.StageRec.PreQcTotalPrice.AsFloat;
+    vDetailGclNode.PreGatherQuantity := ANode.StageRec.PreGatherQuantity.AsFloat;
+    vDetailGclNode.PreGatherTotalPrice := ANode.StageRec.PreGatherTotalPrice.AsFloat;
+  end;
+
+  vLeafXmj := GetFirstXmjParent;
+  vPeg := GetPegNode(vLeafXmj);
+  vDetailGclNode.AddPosData(vLeafXmj, vPeg);
+end;
+
+procedure TGclGatherModel.BeginGather;
+begin
+  FGcls := TList.Create;
+end;
+
+procedure TGclGatherModel.CalculateAll;
+var
+  iGcl: Integer;
+begin
+  for iGcl := 0 to FGcls.Count - 1 do
+    TGclNode(FGcls.Items[iGcl]).Calculate;
+end;
+
+constructor TGclGatherModel.Create(AProjectData: TObject);
+begin
+  FProjectData := AProjectData;
+  FBillsTree := TProjectData(FProjectData).BillsMeasureData.BillsMeasureTree;
+  FGatherDeal := False;
+  FGatherBGL := False;
+end;
+
+destructor TGclGatherModel.Destroy;
+begin
+  inherited;
+end;
+
+procedure TGclGatherModel.EndGather;
+begin
+  ClearObjects(FGcls);
+  FGcls.Free;
+end;
+
+procedure TGclGatherModel.Execute;
+begin
+  BeginGather;
+  try
+    GatherBillsData;
+    GatherDealData;
+    GatherBGLData;
+    CalculateAll;
+    if Assigned(FWriteGatherData) then
+      FWriteGatherData(FGcls);
+  finally
+    EndGather;
+  end;
+end;
+
+function TGclGatherModel.FindGclNode(const AB_Code, AName, AUnits: string;
+  APrice: Double): TGclNode;
+var
+  i: Integer;
+  vGcl: TGclNode;
+begin
+  Result := nil;
+  for i := 0 to FGcls.Count - 1 do
+  begin
+    vGcl := TGclNode(FGcls.Items[i]);
+    if SameText(vGcl.B_Code, TrimRight(AB_Code)) and
+       SameText(vGcl.Name, TrimRight(AName)) and
+       SameText(vGcl.Units, TrimRight(AUnits)) and
+       (abs(vGcl.Price - APrice) < 0.001) then
+    begin
+      Result := vGcl;
+      Break;
+    end;
+  end;
+end;
+
+procedure TGclGatherModel.GatherBGLData;
+begin
+  if not FGatherBGL then Exit;
+  // To Do
+end;
+
+procedure TGclGatherModel.GatherBillsData;
+var
+  i: Integer;
+  vNode: TBillsIDTreeNode;
+begin
+  for i := 0 to FBillsTree.Count - 1 do
+  begin
+    vNode := TBillsIDTreeNode(FBillsTree.Items[i]);
+    if not vNode.HasChildren and (vNode.Rec.B_Code.AsString <> '') then
+      AddBillsNode(vNode);
+  end;
+end;
+
+procedure TGclGatherModel.GatherDealData;
+var
+  vGclNode: TGclNode;
+  vDetailDeal: TDetailDealNode;
+  iDeal: Integer;
+  Rec: TsdDataRecord;
+begin
+  if not FGatherDeal then Exit;
+
+  with TProjectData(FProjectData).DealBillsData do
+    for iDeal := 0 to sddDealBills.RecordCount - 1 do
+    begin
+      Rec := sddDealBills.Records[iDeal];
+      vGclNode := GetGclNode(Rec.ValueByName('B_Code').AsString, Rec.ValueByName('Name').AsString,
+          Rec.ValueByName('Units').AsString, Rec.ValueByName('Price').AsFloat);
+      vDetailDeal := vGclNode.AddDetailDeal(NewDetailDealID);
+
+      vDetailDeal.Quantity := Rec.ValueByName('Quantity').AsFloat;
+      vDetailDeal.TotalPrice := Rec.ValueByName('TotalPrice').AsFloat;
+    end;
+end;
+
+function TGclGatherModel.GetGclNode(ARec: TBillsRecord): TGclNode;
+begin
+  Result := GetGclNode(ARec.B_Code.AsString, ARec.Name.AsString,
+      ARec.Units.AsString, ARec.Price.AsFloat);
+end;
+
+function TGclGatherModel.GetGclNode(const AB_Code, AName, AUnits: string;
+  APrice: Double): TGclNode;
+begin
+  Result := FindGclNode(AB_Code, AName, AUnits, APrice);
+  if not Assigned(Result) then
+    Result := NewGclNode(AB_Code, AName, AUnits, APrice);
+end;
+
+function TGclGatherModel.GetNewDetailBGLID: Integer;
+begin
+  Result := FNewDetailBGLID;
+  Inc(FNewDetailBGLID)
+end;
+
+function TGclGatherModel.GetNewDetailDealID: Integer;
+begin
+  Result := FNewDetailDealID;
+  Inc(FNewDetailDealID);
+end;
+
+function TGclGatherModel.GetNewDetailGclID: Integer;
+begin
+  Result := FNewDetailGclID;
+  Inc(FNewDetailGclID);
+end;
+
+function TGclGatherModel.NewGclNode(const AB_Code, AName, AUnits: string;
+  APrice: Double): TGclNode;
+begin
+  Result := TGclNode.Create(FNewGclID);
+  FGcls.Add(Result);
+  Result.B_Code := TrimRight(AB_Code);
+  Result.Name := TrimRight(AName);
+  Result.Units := TrimRight(AUnits);
+  Result.Price := APrice;
+  Inc(FNewGclID);
+end;
+
+{ TGclNode }
+
+function TGclNode.AddDetailBGL(AID: Integer): TDetailBGLNode;
+begin
+  Result := TDetailBGLNode.Create(AID);
+  FDetailBGLs.Add(Result);
+end;
+
+function TGclNode.AddDetailDeal(AID: Integer): TDetailDealNode;
+begin
+  Result := TDetailDealNode.Create(AID);
+  FDetailDeals.Add(Result);
+end;
+
+function TGclNode.AddDetailGcl(AID: Integer): TDetailGclNode;
+begin
+  Result := TDetailGclNode.Create(AID);
+  FDetailGcls.Add(Result);
+end;
+
+procedure TGclNode.Calculate;
+begin
+  InitCalculate;
+  GatherDetailGcl;
+  GatherDetailDeal;
+  GatherDetailBGL;
+end;
+
+constructor TGclNode.Create(AID: Integer);
+begin
+  FID := AID;
+  FDetailGcls := TList.Create;
+  FDetailDeals := TList.Create;
+  FDetailBGLs := TList.Create;
+end;
+
+destructor TGclNode.Destroy;
+begin
+  ClearObjects(FDetailBGLs);
+  FDetailBGLs.Free;
+  ClearObjects(FDetailDeals);
+  FDetailDeals.Free;
+  ClearObjects(FDetailGcls);
+  FDetailGcls.Free;
+  inherited;
+end;
+
+procedure TGclNode.GatherDetailBGL;
+var
+  iBGL: Integer;
+  vDetailBGL: TDetailBGLNode;
+begin
+  for iBGL := 0 to DetailBGLCount - 1 do
+  begin
+    vDetailBGL := DetailBGL[iBGL];
+    FBGLQuantity := FBGLQuantity + vDetailBGL.Quantity;
+    FBGLTotalPrice := FBGLTotalPrice + vDetailBGL.TotalPrice;
+  end;
+end;
+
+procedure TGclNode.GatherDetailDeal;
+var
+  iDeal: Integer;
+  vDetailDeal: TDetailDealNode;
+begin
+  for iDeal := 0 to DetailDealCount - 1 do
+  begin
+    vDetailDeal := DetailDeal[iDeal];
+    FDealQuantity := FDealQuantity + vDetailDeal.Quantity;
+    FDealTotalPrice := FDealTotalPrice + vDetailDeal.TotalPrice;
+  end;
+end;
+
+procedure TGclNode.GatherDetailGcl;
+var
+  iGcl: Integer;
+  vDetailGcl: TDetailGclNode;
+begin
+  for iGcl := 0 to DetailGclCount - 1 do
+  begin
+    vDetailGcl := DetailGcl[iGcl];
+    FQuantity := FQuantity + vDetailGcl.Quantity;
+    FTotalPrice := FTotalPrice + vDetailGcl.TotalPrice;
+
+    FCurDealQuantity := FCurDealQuantity + vDetailGcl.CurDealQuantity;
+    FCurDealTotalPrice := FCurDealTotalPrice + vDetailGcl.CurDealTotalPrice;
+    FCurQcQuantity := FCurQcQuantity + vDetailGcl.CurQcQuantity;
+    FCurQcTotalPrice := FCurQcTotalPrice + vDetailGcl.CurQcTotalPrice;
+    FCurGatherQuantity := FCurGatherQuantity + vDetailGcl.CurGatherQuantity;
+    FCurGatherTotalPrice := FCurGatherTotalPrice + vDetailGcl.CurGatherTotalPrice;
+
+    FPreDealQuantity := FPreDealQuantity + vDetailGcl.PreDealQuantity;
+    FPreDealTotalPrice := FPreDealTotalPrice + vDetailGcl.PreDealTotalPrice;
+    FPreQcQuantity := FPreQcQuantity + vDetailGcl.PreQcQuantity;
+    FPreQcTotalPrice := FPreQcTotalPrice + vDetailGcl.PreQcTotalPrice;
+    FPreGatherQuantity := FPreGatherQuantity + vDetailGcl.PreGatherQuantity;
+    FPreGatherTotalPrice := FPreGatherTotalPrice + vDetailGcl.PreGatherTotalPrice;
+  end;
+end;
+
+function TGclNode.GetDetailBGL(AIndex: Integer): TDetailBGLNode;
+begin
+  Result := TDetailBGLNode(FDetailBGLs.Items[AIndex]);
+end;
+
+function TGclNode.GetDetailBGLCount: Integer;
+begin
+  Result := FDetailBGLs.Count;
+end;
+
+function TGclNode.GetDetailDeal(AIndex: Integer): TDetailDealNode;
+begin
+  Result := TDetailDealNode(FDetailDeals.Items[AIndex]);
+end;
+
+function TGclNode.GetDetailDealCount: Integer;
+begin
+  Result := FDetailDeals.Count;
+end;
+
+function TGclNode.GetDetailGcl(AIndex: Integer): TDetailGclNode;
+begin
+  Result := TDetailGclNode(FDetailGcls.Items[AIndex]);
+end;
+
+function TGclNode.GetDetailGclCount: Integer;
+begin
+  Result := FDetailGcls.Count;
+end;
+
+procedure TGclNode.InitCalculate;
+begin
+  FQuantity := 0;
+  FTotalPrice := 0;
+
+  FCurDealQuantity := 0;
+  FCurDealTotalPrice := 0;
+  FCurQcQuantity := 0;
+  FCurQcTotalPrice := 0;
+  FCurGatherQuantity := 0;
+  FCurGatherTotalPrice := 0;
+
+  FPreDealQuantity := 0;
+  FPreDealTotalPrice := 0;
+  FPreQcQuantity := 0;
+  FPreQcTotalPrice := 0;
+  FPreGatherQuantity := 0;
+  FPreGatherTotalPrice := 0;
+
+  FDealQuantity := 0;
+  FDealTotalPrice := 0;
+
+  FBGLQuantity := 0;
+  FBGLTotalPrice := 0;
+end;
+
+procedure TGclNode.SetB_Code(const Value: string);
+begin
+  FB_Code := Value;
+  FIndexCode := B_CodeToIndexCode(FB_Code);
+end;
+
+{ TDetailGclNode }
+
+procedure TDetailGclNode.AddPosData(ALeafXmj, APeg: TBillsIDTreeNode);
+
+  function GetPegName: string;
+  begin
+    if Assigned(APeg) then
+      Result := APeg.Rec.Name.AsString
+    else
+      Result := '';
+  end;
+
+  // 取树结构的第ALevel层节点的名称(level从0开始)
+  function GetNameByLevel(ANode: TBillsIDTreeNode; ALevel: Integer): string;
+  begin
+    Result := '';
+    if not Assigned(ANode) then Exit;
+    if ANode.Level = ALevel then
+      Result := ANode.Rec.Name.AsString
+    else if ANode.Level > ALevel then
+      Result := GetNameByLevel(TBillsIDTreeNode(ANode.Parent), ALevel);
+  end;
+
+  function GetNameDanWei(ANode: TBillsIDTreeNode): string;
+  begin
+    // 取树结构的第二层节点的名称
+    Result := GetNameByLevel(ANode, 1);
+  end;
+
+  // ANode为计量单元节点,APegNode为桩号节点
+  function GetNameFenBu(ANode, APegNode: TBillsIDTreeNode): string;
+  var
+    vCurNode: TBillsIDTreeNode;
+  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 := TBillsIDTreeNode(vCurNode.Parent);
+      Result := vCurNode.Rec.Name.AsString;
+    end;
+  end;
+
+  // ANode为计量单元节点,APegNode为桩号节点
+  function GetNameFenXiang(ANode, APegNode: TBillsIDTreeNode): string;
+  var
+    iTopLevel: Integer;
+    vCurNode: TBillsIDTreeNode;
+  begin
+    if Assigned(APegNode) then
+    begin
+      iTopLevel := 3;
+      if APegNode.ID <> ANode.ID then
+        iTopLevel := APegNode.Level + 2;
+      Result := '';
+      vCurNode := TBillsIDTreeNode(ANode.Parent);
+      while vCurNode.Level >= iTopLevel do
+      begin
+        Result := vCurNode.Rec.Name.AsString + ';' + Result;
+        vCurNode := TBillsIDTreeNode(vCurNode.Parent);
+      end;
+    end
+    else
+      Result := GetNameByLevel(ANode, 3);
+  end;
+
+  function GetNameUnit(ANode: TBillsIDTreeNode): string;
+  begin
+    Result := ANode.Rec.Name.AsString;
+  end;
+
+  function GetDrawingCode(ANode: TBillsIDTreeNode): string;
+  begin
+    Result := '';
+    if not Assigned(ANode) then Exit;
+    Result := ANode.Rec.DrawingCode.AsString;
+    if Result = '' then
+      Result := GetDrawingCode(TBillsIDTreeNode(ANode.Parent));
+  end;
+
+  function GetPosition(ANode, APegNode: TBillsIDTreeNode): 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
+  if not Assigned(ALeafXmj) then Exit;
+
+  FLeafXmjID := ALeafXmj.ID;
+  FXmjCode := ALeafXmj.Rec.Code.AsString;
+  FXmjName := ALeafXmj.Rec.Name.AsString;
+  FXmjUnits := ALeafXmj.Rec.Units.AsString;
+  FPeg := GetPegName;
+  FNameDanWei := GetNameDanWei(ALeafXmj);
+  FNameFenBu := GetNameFenBu(ALeafXmj, APeg);
+  FNameFenXiang := GetNameFenXiang(ALeafXmj, APeg);
+  FNameUnit := GetNameUnit(ALeafXmj);
+  FPosition := GetPosition(ALeafXmj, APeg);
+  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.

+ 40 - 7
Units/ProjectData.pas

@@ -6,11 +6,12 @@ uses
   Connections, BillsDm, PhaseData, UpdateDataBase, ZhAPI, ProjectProperty,
   PhaseCompareDm, DealPaymentDm, SearchDm, DealBillsDm, MainDataListDm,
   BillsGatherDm, BGLDm, StaffDm, BillsCompileDm, BillsMeasureDm,
-  BillsBookmarkDm, UpFileManageUnit,
+  BillsBookmarkDm, UpFileManageUnit, ProjectGLDm, PriceMarginBillsDm,
+  DetailGLDm,
   Classes, SysUtils, ADODB, sdDB, Checker;
 
 type
-  
+
   TProjectData = class
   private
     // 临时文件夹,解压项目后存放文件的文件夹
@@ -40,6 +41,10 @@ type
     FSearchData: TSearchData;
     FMainListData: TMainListData;
 
+    FProjectGLData: TProjectGLData;
+    FDetailGLData: TDetailGLData;
+    FPriceMarginBillsData: TPriceMarginBillsData;
+
     FCanUnlockInfo: Boolean;
 
     FWebID: Integer;
@@ -177,6 +182,10 @@ type
     property MainListData: TMainListData read FMainListData;
     property AttachmentData: TUpFiles read FAttachmentData;   // 附件
 
+    property ProjectGLData: TProjectGLData read FProjectGLData;
+    property DetailGLData: TDetailGLData read FDetailGLData;
+    property PriceMarginBillsData: TPriceMarginBillsData read FPriceMarginBillsData;
+
     // 台账、合同支付
     property AllowInsert: Boolean read GetAllowInsert;
     property BaseDataReadOnly: Boolean read GetBaseDataReadOnly;
@@ -250,6 +259,9 @@ begin
   FStaffData := TStaffData.Create(Self);
   FSearchData := TSearchData.Create(Self);
   FMainListData := TMainListData.Create(Self);
+  FProjectGLData := TProjectGLData.Create(Self);
+  FDetailGLData := TDetailGLData.Create(Self);
+  FPriceMarginBillsData := TPriceMarginBillsData.Create(Self);
   FAttachmentData := TUpFiles.Create;
   FPhaseIndex := 0;
 end;
@@ -269,6 +281,9 @@ end;
 destructor TProjectData.Destroy;
 begin
   FCheckers.Free;
+  FPriceMarginBillsData.Free;
+  FDetailGLData.Free;
+  FProjectGLData.Free;
   FMainListData.Free;
   FSearchData.Free;
   FStaffData.Free;
@@ -376,20 +391,29 @@ begin
   FBillsCompileData.Open;
   FBillsMeasureData.Open;
   UpdateSysProgress(65, '正在读取数据');
+
   FBillsBookmarkData.Open;
+  FProjectGLData.Open(FConnection.Connection);
+  FDetailGLData.Open(FConnection.Connection);
   UpdateSysProgress(70, '正在读取数据');
+
   FDealBillsData.Open(FConnection.Connection);
   UpdateSysProgress(80, '正在读取数据');
+
   FDealPaymentData.Open(FConnection.Connection);
   if FIsNewFile then
     FDealPaymentData.Init;
   UpdateSysProgress(90, '正在读取数据');
+
   OpenLastPhaseData;
   UpdateSysProgress(140, '正在读取数据');
+
   FBGLData.Open(FConnection.Connection);
   UpdateSysProgress(160, '正在读取数据');
+
   FStaffData.Open(FConnection.Connection);
   UpdateSysProgress(180, '正在读取数据');
+
   //FBillsGatherData.RefreshBills;
   FMainListData.Open(FConnection.Connection);
   UpdateSysProgress(200, '就绪');
@@ -408,29 +432,38 @@ procedure TProjectData.Save;
 begin
   UpdateSysProgress(5, '正在保存数据');
   SaveLastestPhaseMainData;
+  UpdateSysProgress(10, '正在保存数据');
   if FPhaseData.Active then
     FPhaseData.Save;
-  UpdateSysProgress(20, '正在保存数据');
+  UpdateSysProgress(40, '正在保存数据');
   FMainListData.Save;
   FDealPaymentData.Save;
-  UpdateSysProgress(40, '正在保存数据');
-  FStaffData.Save;
   UpdateSysProgress(50, '正在保存数据');
-  FBGLData.Save;
+  FStaffData.Save;
   UpdateSysProgress(60, '正在保存数据');
+  FBGLData.Save;
+  UpdateSysProgress(70, '正在保存数据');
   FDealBillsData.Save;
   UpdateSysProgress(80, '正在保存数据');
+
+  FProjectGLData.Save;
+  FDetailGLData.Save;
+  UpdateSysProgress(100, '正在保存数据');
+
   FBillsCompileData.ReLockBaseData;
-  UpdateSysProgress(85, '正在保存数据');
+  UpdateSysProgress(110, '正在保存数据');
   FBillsData.Save;
   UpdateSysProgress(170, '正在保存数据');
+
   FProjProperties.Save;
   UpdateSysProgress(180, '正在保存数据');
   FConnection.Save;
   UpdateSysProgress(190, '正在保存数据');
+
   ZipFolder(FTempFolder, FileName);
   SaveInfoToManager;
   UpdateSysProgress(200, '就绪');
+
   ProjectManager.AddSaveTenderBackup(FProjectID);
 end;
 

+ 3 - 0
Units/UpdateDataBase.pas

@@ -86,6 +86,9 @@ begin
     Updater.AddTableDef(SStaff, @tdStaff, Length(tdStaff), False, False);
     Updater.AddTableDef(SDealBills, @tdDealBills, Length(tdDealBills), False, False);
     Updater.AddTableDef(SMainDataList, @tdMainDataList, Length(tdMainDataList), False, False);
+    Updater.AddTableDef(SProjectGL, @tdProjectGL, Length(tdProjectGL), False, False);
+    Updater.AddTableDef(SGLPrice, @tdGLPrice, Length(tdGLPrice), False, False);
+    Updater.AddTableDef(SDetailGL, @tdDetailGL, Length(tdDetailGL), False, False);
     Updater.ExcuteUpdate;
   finally
     Updater.Free;

+ 15 - 0
Units/UtilMethods.pas

@@ -18,6 +18,9 @@ type
   procedure AlignControl(AControl, AParent: TWinControl; AAlign: TAlign);
   procedure SetDxBtnAction(AAction: TAction; ADxBtn: TObject);
 
+  {DataBase Rela}
+  function GetsdDataSetNewID(ADataSet: TsdDataSet; const AIndex: string): Integer;
+
   {Message}
   procedure WarningMessage(const AMsg: string);
   procedure ErrorMessage(const AMsg: string);
@@ -158,6 +161,18 @@ begin
       TdxBarButton(ADxBtn).Action := AAction;
 end;
 
+{DataBase Rela}
+function GetsdDataSetNewID(ADataSet: TsdDataSet; const AIndex: string): Integer;
+var
+  idx: TsdIndex;
+begin
+  idx := ADataSet.FindIndex(AIndex);
+  if idx.RecordCount > 0 then
+    Result := idx.Records[idx.RecordCount - 1].ValueByName('ID').AsInteger + 1
+  else
+    Result := 1;
+end;
+
 {Message}
 procedure WarningMessage(const AMsg: string);
 begin