Pārlūkot izejas kodu

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

MaiXinRong 9 gadi atpakaļ
vecāks
revīzija
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
       Hint = #35774#32622#35745#25552#26399#38480
       Visible = ivAlways
       Visible = ivAlways
     end
     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
   end
   object Images: TImageList
   object Images: TImageList
     DrawingStyle = dsTransparent
     DrawingStyle = dsTransparent

+ 3 - 0
Forms/MainFrm.pas

@@ -143,6 +143,9 @@ type
     dxsiExpandTo: TdxBarSubItem;
     dxsiExpandTo: TdxBarSubItem;
     dxbtnLocateBookmark: TdxBarButton;
     dxbtnLocateBookmark: TdxBarButton;
     dxbtnSetDealPayPlan: TdxBarButton;
     dxbtnSetDealPayPlan: TdxBarButton;
+    dxbtnAddDetailGLs: TdxBarButton;
+    dxbtnCopyDetailGls: TdxBarButton;
+    dxbtnApplyToSameBills: TdxBarButton;
     procedure FormCreate(Sender: TObject);
     procedure FormCreate(Sender: TObject);
     procedure FormDestroy(Sender: TObject);
     procedure FormDestroy(Sender: TObject);
     procedure jtsProjectsChange(Sender: TObject; NewTab: Integer;
     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
               Tag = 2
             end
             end
             item
             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
               Caption = #23457#26680#27604#36739
               Hint = #23457#26680#27604#36739
               Hint = #23457#26680#27604#36739
-              Index = 3
+              Index = 4
               IsDefault = False
               IsDefault = False
               LargeImage = 3
               LargeImage = 3
               SmallImage = 3
               SmallImage = 3
               StoredItem = xbiStageCompare
               StoredItem = xbiStageCompare
-              Tag = 3
+              Tag = 4
             end
             end
             item
             item
               Caption = #25253#34920
               Caption = #25253#34920
               Hint = #25253#34920
               Hint = #25253#34920
-              Index = 4
+              Index = 5
               IsDefault = False
               IsDefault = False
               LargeImage = 6
               LargeImage = 6
               SmallImage = 6
               SmallImage = 6
               StoredItem = xbiReport
               StoredItem = xbiReport
-              Tag = 4
+              Tag = 5
             end>
             end>
         end>
         end>
       ActiveGroupIndex = 0
       ActiveGroupIndex = 0
@@ -2831,6 +2840,15 @@ object ProjectFrame: TProjectFrame
         TabName = 'BillsGather'
         TabName = 'BillsGather'
         Caption = 'PhaseCompare'
         Caption = 'PhaseCompare'
       end
       end
+      object jpsMainPriceMargin: TJimPage
+        Tag = -1
+        Left = 0
+        Top = 0
+        Width = 903
+        Height = 415
+        TabName = 'PriceMargin'
+        Caption = 'PriceMargin'
+      end
       object jpsMainStageCompare: TJimPage
       object jpsMainStageCompare: TJimPage
         Tag = -1
         Tag = -1
         Left = 0
         Left = 0
@@ -3110,6 +3128,7 @@ object ProjectFrame: TProjectFrame
       #35745#37327#21488#36134
       #35745#37327#21488#36134
       #28165#21333#27719#24635
       #28165#21333#27719#24635
       #23457#26680#27604#36739
       #23457#26680#27604#36739
+      #26448#26009#35843#24046
       #24418#35937#36827#24230
       #24418#35937#36827#24230
       #25253#34920)
       #25253#34920)
     DefaultLargeImage = -1
     DefaultLargeImage = -1
@@ -3136,7 +3155,7 @@ object ProjectFrame: TProjectFrame
       SmallImage = 2
       SmallImage = 2
     end
     end
     object xbiStageCompare: TdxStoredSideItem
     object xbiStageCompare: TdxStoredSideItem
-      Tag = 3
+      Tag = 4
       Caption = #23457#26680#27604#36739
       Caption = #23457#26680#27604#36739
       Category = 3
       Category = 3
       Enabled = True
       Enabled = True
@@ -3147,16 +3166,16 @@ object ProjectFrame: TProjectFrame
     object xbiCompleteDegree: TdxStoredSideItem
     object xbiCompleteDegree: TdxStoredSideItem
       Tag = -1
       Tag = -1
       Caption = #24418#35937#36827#24230
       Caption = #24418#35937#36827#24230
-      Category = 4
+      Category = 5
       Enabled = True
       Enabled = True
       Hint = #24418#35937#36827#24230
       Hint = #24418#35937#36827#24230
       LargeImage = 5
       LargeImage = 5
       SmallImage = 5
       SmallImage = 5
     end
     end
     object xbiReport: TdxStoredSideItem
     object xbiReport: TdxStoredSideItem
-      Tag = 4
+      Tag = 5
       Caption = #25253#34920
       Caption = #25253#34920
-      Category = 5
+      Category = 6
       Enabled = True
       Enabled = True
       Hint = #25253#34920
       Hint = #25253#34920
       LargeImage = 6
       LargeImage = 6
@@ -3170,6 +3189,14 @@ object ProjectFrame: TProjectFrame
       LargeImage = 1
       LargeImage = 1
       SmallImage = 1
       SmallImage = 1
     end
     end
+    object xbiPriceMargin: TdxStoredSideItem
+      Tag = 3
+      Caption = #26448#26009#35843#24046
+      Category = 4
+      Enabled = True
+      LargeImage = 4
+      SmallImage = 4
+    end
   end
   end
   object ilstLarge: TImageList
   object ilstLarge: TImageList
     Height = 32
     Height = 32

+ 28 - 10
Frames/ProjectFme.pas

@@ -6,6 +6,7 @@ uses
   BillsCompileFme, BillsMeasureFme, PhaseCompareFme, DealPaymentFme,
   BillsCompileFme, BillsMeasureFme, PhaseCompareFme, DealPaymentFme,
   BillsGatherFme, ZJJLFme, BGLFme, ReportsFrm, SearchFme, BookmarkFme,
   BillsGatherFme, ZJJLFme, BGLFme, ReportsFrm, SearchFme, BookmarkFme,
   ProjectData, UtilMethods, Globals, mEncryptEditions, DealBillsFme,
   ProjectData, UtilMethods, Globals, mEncryptEditions, DealBillsFme,
+  PriceMarginFme,
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, ImgList, XPMenu, Buttons, ComCtrls, ToolWin, ExtCtrls, JimPages,
   Dialogs, ImgList, XPMenu, Buttons, ComCtrls, ToolWin, ExtCtrls, JimPages,
   StdCtrls, JimCombos, dxsbar, ActnList, dxBar, OrderCheckerFme, CheckerFme,
   StdCtrls, JimCombos, dxsbar, ActnList, dxBar, OrderCheckerFme, CheckerFme,
@@ -77,6 +78,8 @@ type
     tobtnUpFile: TToolButton;
     tobtnUpFile: TToolButton;
     jpsAssistantDealBills: TJimPage;
     jpsAssistantDealBills: TJimPage;
     tobtnDealBills: TToolButton;
     tobtnDealBills: TToolButton;
+    jpsMainPriceMargin: TJimPage;
+    xbiPriceMargin: TdxStoredSideItem;
     procedure tobtnStandardBillsClick(Sender: TObject);
     procedure tobtnStandardBillsClick(Sender: TObject);
     procedure jcbPhaseChanged(Sender: TObject);
     procedure jcbPhaseChanged(Sender: TObject);
     procedure sbtnExpendClick(Sender: TObject);
     procedure sbtnExpendClick(Sender: TObject);
@@ -99,8 +102,9 @@ type
 
 
     FBillsCompileFrame: TBillsCompileFrame;
     FBillsCompileFrame: TBillsCompileFrame;
     FBillsMeasureFrame: TBillsMeasureFrame;
     FBillsMeasureFrame: TBillsMeasureFrame;
-    FPhaseCompareFrame: TPhaseCompareFrame;
     FBillsGatherFrame: TBillsGatherFrame;
     FBillsGatherFrame: TBillsGatherFrame;
+    FPriceMarginFrame: TPriceMarginFrame;
+    FPhaseCompareFrame: TPhaseCompareFrame;
     FCheckerFrame: TCheckerFrame;
     FCheckerFrame: TCheckerFrame;
 
 
     FDealPaymentFrame: TDealPaymentFrame;
     FDealPaymentFrame: TDealPaymentFrame;
@@ -114,6 +118,7 @@ type
     procedure CreateBillsFrame;
     procedure CreateBillsFrame;
     procedure CreateDealPaymentFrame;
     procedure CreateDealPaymentFrame;
     procedure CreateBillsGatherFrame;
     procedure CreateBillsGatherFrame;
+    procedure CreatePriceMarginFrame;
     procedure CreateCheckerFrame;
     procedure CreateCheckerFrame;
     procedure CreateUpFile;
     procedure CreateUpFile;
     procedure CreateFrames;
     procedure CreateFrames;
@@ -171,6 +176,7 @@ type
     property BillsCompileFrame: TBillsCompileFrame read FBillsCompileFrame;
     property BillsCompileFrame: TBillsCompileFrame read FBillsCompileFrame;
     property BillsMeasureFrame: TBillsMeasureFrame read FBillsMeasureFrame;
     property BillsMeasureFrame: TBillsMeasureFrame read FBillsMeasureFrame;
     property BillsGatherFrame: TBillsGatherFrame read FBillsGatherFrame;
     property BillsGatherFrame: TBillsGatherFrame read FBillsGatherFrame;
+    property PriceMarginFrame: TPriceMarginFrame read FPriceMarginFrame;
 
 
     property CheckerFrame: TCheckerFrame read FCheckerFrame;
     property CheckerFrame: TCheckerFrame read FCheckerFrame;
     property UpFileManageView: TUpFileManageView read FUpFileManageView write SetUpFileManageView;
     property UpFileManageView: TUpFileManageView read FUpFileManageView write SetUpFileManageView;
@@ -480,6 +486,8 @@ procedure TProjectFrame.dxsbViewControlItemClick(Sender: TObject;
                           or (Item.Tag = xbiBillsMeasure.Tag);
                           or (Item.Tag = xbiBillsMeasure.Tag);
     tobtnBGL.Visible := Item.Tag = xbiBillsMeasure.Tag;
     tobtnBGL.Visible := Item.Tag = xbiBillsMeasure.Tag;
     tobtnZJJL.Visible := Item.Tag = xbiBillsMeasure.Tag;
     tobtnZJJL.Visible := Item.Tag = xbiBillsMeasure.Tag;
+    // 控制整个按钮工具栏显示,
+    pnlToolBar.Visible := pnlPhaseSelect.Visible or tbExpand.Visible or tbToolsButton.Visible;
     // 根据当前View控制右侧按钮是否按下,右侧工具窗是否弹开
     // 根据当前View控制右侧按钮是否按下,右侧工具窗是否弹开
     jpsAssistant.ActivePageIndex := jpsMain.ActivePage.Tag;
     jpsAssistant.ActivePageIndex := jpsMain.ActivePage.Tag;
     sbtnExpend.Tag := jpsMain.ActivePage.Tag;
     sbtnExpend.Tag := jpsMain.ActivePage.Tag;
@@ -499,14 +507,17 @@ procedure TProjectFrame.dxsbViewControlItemClick(Sender: TObject;
     // 切换至清单汇总,须重新汇总
     // 切换至清单汇总,须重新汇总
     if Item.Tag = xbiBillsGather.Tag then
     if Item.Tag = xbiBillsGather.Tag then
       BillsGatherFrame.RefreshBills;
       BillsGatherFrame.RefreshBills;
+    // 切换至材料调差,须重新汇总展示调差清单
+    if Item.Tag = xbiPriceMargin.Tag then
+      PriceMarginFrame.RefreshBills;
 
 
     if G_IsCloud then
     if G_IsCloud then
       if (Item.Tag = xbiBillsCompile.Tag) or (Item.Tag = xbiBillsMeasure.Tag) then
       if (Item.Tag = xbiBillsCompile.Tag) or (Item.Tag = xbiBillsMeasure.Tag) then
         CheckUpFile;
         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;
   end;
 
 
   procedure ChangeView;
   procedure ChangeView;
@@ -514,7 +525,7 @@ procedure TProjectFrame.dxsbViewControlItemClick(Sender: TObject;
     BeforeChangeView;
     BeforeChangeView;
     case Item.Tag of
     case Item.Tag of
       0, 2: jpsMain.ActivePageIndex := Item.Tag;
       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;
       //2: if CheckPlanEdition then jpsMain.ActivePageIndex := Item.Tag;
     end;
     end;
     AfterChangeView;
     AfterChangeView;
@@ -558,13 +569,13 @@ procedure TProjectFrame.dxsbViewControlItemClick(Sender: TObject;
 begin
 begin
   if Item.Tag = jpsMain.ActivePageIndex then Exit;
   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;
     CloseCompare;
-    
+
   case Item.Tag of
   case Item.Tag of
-    0..2: ChangeView;
-    3: DisplayCompare;
-    4: DisplayReports;
+    0..3: ChangeView;
+    4: DisplayCompare;
+    5: DisplayReports;
   end;
   end;
 end;
 end;
 
 
@@ -1080,6 +1091,7 @@ begin
   UpdateSysProgress(140, '正在解析数据');
   UpdateSysProgress(140, '正在解析数据');
   CreateBillsGatherFrame;
   CreateBillsGatherFrame;
   UpdateSysProgress(150, '正在解析数据');
   UpdateSysProgress(150, '正在解析数据');
+  CreatePriceMarginFrame;
 
 
   FZJJLFrame := TZJJLFrame.Create(Self, FProjectData.PhaseData.ZJJLData);
   FZJJLFrame := TZJJLFrame.Create(Self, FProjectData.PhaseData.ZJJLData);
   FZJJLFrame.DataReadOnly := FProjectData.PhaseData.StageDataReadOnly;
   FZJJLFrame.DataReadOnly := FProjectData.PhaseData.StageDataReadOnly;
@@ -1339,4 +1351,10 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TProjectFrame.CreatePriceMarginFrame;
+begin
+  FPriceMarginFrame := TPriceMarginFrame.Create(FProjectData);
+  AlignControl(FPriceMarginFrame, jpsMainPriceMargin, alClient);
+end;
+
 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)
     (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';
   SMainDataList = 'MainDataList';
   tdMainDataList: array [0..15] of TScFieldDef =(
   tdMainDataList: array [0..15] of TScFieldDef =(
@@ -445,7 +509,7 @@ const
   // ......
   // ......
   SRefer = 'Refer';
   SRefer = 'Refer';
   SAudit = 'Audit';
   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),
     (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: '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,
   Connections, BillsDm, PhaseData, UpdateDataBase, ZhAPI, ProjectProperty,
   PhaseCompareDm, DealPaymentDm, SearchDm, DealBillsDm, MainDataListDm,
   PhaseCompareDm, DealPaymentDm, SearchDm, DealBillsDm, MainDataListDm,
   BillsGatherDm, BGLDm, StaffDm, BillsCompileDm, BillsMeasureDm,
   BillsGatherDm, BGLDm, StaffDm, BillsCompileDm, BillsMeasureDm,
-  BillsBookmarkDm, UpFileManageUnit,
+  BillsBookmarkDm, UpFileManageUnit, ProjectGLDm, PriceMarginBillsDm,
+  DetailGLDm,
   Classes, SysUtils, ADODB, sdDB, Checker;
   Classes, SysUtils, ADODB, sdDB, Checker;
 
 
 type
 type
-  
+
   TProjectData = class
   TProjectData = class
   private
   private
     // 临时文件夹,解压项目后存放文件的文件夹
     // 临时文件夹,解压项目后存放文件的文件夹
@@ -40,6 +41,10 @@ type
     FSearchData: TSearchData;
     FSearchData: TSearchData;
     FMainListData: TMainListData;
     FMainListData: TMainListData;
 
 
+    FProjectGLData: TProjectGLData;
+    FDetailGLData: TDetailGLData;
+    FPriceMarginBillsData: TPriceMarginBillsData;
+
     FCanUnlockInfo: Boolean;
     FCanUnlockInfo: Boolean;
 
 
     FWebID: Integer;
     FWebID: Integer;
@@ -177,6 +182,10 @@ type
     property MainListData: TMainListData read FMainListData;
     property MainListData: TMainListData read FMainListData;
     property AttachmentData: TUpFiles read FAttachmentData;   // 附件
     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 AllowInsert: Boolean read GetAllowInsert;
     property BaseDataReadOnly: Boolean read GetBaseDataReadOnly;
     property BaseDataReadOnly: Boolean read GetBaseDataReadOnly;
@@ -250,6 +259,9 @@ begin
   FStaffData := TStaffData.Create(Self);
   FStaffData := TStaffData.Create(Self);
   FSearchData := TSearchData.Create(Self);
   FSearchData := TSearchData.Create(Self);
   FMainListData := TMainListData.Create(Self);
   FMainListData := TMainListData.Create(Self);
+  FProjectGLData := TProjectGLData.Create(Self);
+  FDetailGLData := TDetailGLData.Create(Self);
+  FPriceMarginBillsData := TPriceMarginBillsData.Create(Self);
   FAttachmentData := TUpFiles.Create;
   FAttachmentData := TUpFiles.Create;
   FPhaseIndex := 0;
   FPhaseIndex := 0;
 end;
 end;
@@ -269,6 +281,9 @@ end;
 destructor TProjectData.Destroy;
 destructor TProjectData.Destroy;
 begin
 begin
   FCheckers.Free;
   FCheckers.Free;
+  FPriceMarginBillsData.Free;
+  FDetailGLData.Free;
+  FProjectGLData.Free;
   FMainListData.Free;
   FMainListData.Free;
   FSearchData.Free;
   FSearchData.Free;
   FStaffData.Free;
   FStaffData.Free;
@@ -376,20 +391,29 @@ begin
   FBillsCompileData.Open;
   FBillsCompileData.Open;
   FBillsMeasureData.Open;
   FBillsMeasureData.Open;
   UpdateSysProgress(65, '正在读取数据');
   UpdateSysProgress(65, '正在读取数据');
+
   FBillsBookmarkData.Open;
   FBillsBookmarkData.Open;
+  FProjectGLData.Open(FConnection.Connection);
+  FDetailGLData.Open(FConnection.Connection);
   UpdateSysProgress(70, '正在读取数据');
   UpdateSysProgress(70, '正在读取数据');
+
   FDealBillsData.Open(FConnection.Connection);
   FDealBillsData.Open(FConnection.Connection);
   UpdateSysProgress(80, '正在读取数据');
   UpdateSysProgress(80, '正在读取数据');
+
   FDealPaymentData.Open(FConnection.Connection);
   FDealPaymentData.Open(FConnection.Connection);
   if FIsNewFile then
   if FIsNewFile then
     FDealPaymentData.Init;
     FDealPaymentData.Init;
   UpdateSysProgress(90, '正在读取数据');
   UpdateSysProgress(90, '正在读取数据');
+
   OpenLastPhaseData;
   OpenLastPhaseData;
   UpdateSysProgress(140, '正在读取数据');
   UpdateSysProgress(140, '正在读取数据');
+
   FBGLData.Open(FConnection.Connection);
   FBGLData.Open(FConnection.Connection);
   UpdateSysProgress(160, '正在读取数据');
   UpdateSysProgress(160, '正在读取数据');
+
   FStaffData.Open(FConnection.Connection);
   FStaffData.Open(FConnection.Connection);
   UpdateSysProgress(180, '正在读取数据');
   UpdateSysProgress(180, '正在读取数据');
+
   //FBillsGatherData.RefreshBills;
   //FBillsGatherData.RefreshBills;
   FMainListData.Open(FConnection.Connection);
   FMainListData.Open(FConnection.Connection);
   UpdateSysProgress(200, '就绪');
   UpdateSysProgress(200, '就绪');
@@ -408,29 +432,38 @@ procedure TProjectData.Save;
 begin
 begin
   UpdateSysProgress(5, '正在保存数据');
   UpdateSysProgress(5, '正在保存数据');
   SaveLastestPhaseMainData;
   SaveLastestPhaseMainData;
+  UpdateSysProgress(10, '正在保存数据');
   if FPhaseData.Active then
   if FPhaseData.Active then
     FPhaseData.Save;
     FPhaseData.Save;
-  UpdateSysProgress(20, '正在保存数据');
+  UpdateSysProgress(40, '正在保存数据');
   FMainListData.Save;
   FMainListData.Save;
   FDealPaymentData.Save;
   FDealPaymentData.Save;
-  UpdateSysProgress(40, '正在保存数据');
-  FStaffData.Save;
   UpdateSysProgress(50, '正在保存数据');
   UpdateSysProgress(50, '正在保存数据');
-  FBGLData.Save;
+  FStaffData.Save;
   UpdateSysProgress(60, '正在保存数据');
   UpdateSysProgress(60, '正在保存数据');
+  FBGLData.Save;
+  UpdateSysProgress(70, '正在保存数据');
   FDealBillsData.Save;
   FDealBillsData.Save;
   UpdateSysProgress(80, '正在保存数据');
   UpdateSysProgress(80, '正在保存数据');
+
+  FProjectGLData.Save;
+  FDetailGLData.Save;
+  UpdateSysProgress(100, '正在保存数据');
+
   FBillsCompileData.ReLockBaseData;
   FBillsCompileData.ReLockBaseData;
-  UpdateSysProgress(85, '正在保存数据');
+  UpdateSysProgress(110, '正在保存数据');
   FBillsData.Save;
   FBillsData.Save;
   UpdateSysProgress(170, '正在保存数据');
   UpdateSysProgress(170, '正在保存数据');
+
   FProjProperties.Save;
   FProjProperties.Save;
   UpdateSysProgress(180, '正在保存数据');
   UpdateSysProgress(180, '正在保存数据');
   FConnection.Save;
   FConnection.Save;
   UpdateSysProgress(190, '正在保存数据');
   UpdateSysProgress(190, '正在保存数据');
+
   ZipFolder(FTempFolder, FileName);
   ZipFolder(FTempFolder, FileName);
   SaveInfoToManager;
   SaveInfoToManager;
   UpdateSysProgress(200, '就绪');
   UpdateSysProgress(200, '就绪');
+
   ProjectManager.AddSaveTenderBackup(FProjectID);
   ProjectManager.AddSaveTenderBackup(FProjectID);
 end;
 end;
 
 

+ 3 - 0
Units/UpdateDataBase.pas

@@ -86,6 +86,9 @@ begin
     Updater.AddTableDef(SStaff, @tdStaff, Length(tdStaff), False, False);
     Updater.AddTableDef(SStaff, @tdStaff, Length(tdStaff), False, False);
     Updater.AddTableDef(SDealBills, @tdDealBills, Length(tdDealBills), False, False);
     Updater.AddTableDef(SDealBills, @tdDealBills, Length(tdDealBills), False, False);
     Updater.AddTableDef(SMainDataList, @tdMainDataList, Length(tdMainDataList), 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;
     Updater.ExcuteUpdate;
   finally
   finally
     Updater.Free;
     Updater.Free;

+ 15 - 0
Units/UtilMethods.pas

@@ -18,6 +18,9 @@ type
   procedure AlignControl(AControl, AParent: TWinControl; AAlign: TAlign);
   procedure AlignControl(AControl, AParent: TWinControl; AAlign: TAlign);
   procedure SetDxBtnAction(AAction: TAction; ADxBtn: TObject);
   procedure SetDxBtnAction(AAction: TAction; ADxBtn: TObject);
 
 
+  {DataBase Rela}
+  function GetsdDataSetNewID(ADataSet: TsdDataSet; const AIndex: string): Integer;
+
   {Message}
   {Message}
   procedure WarningMessage(const AMsg: string);
   procedure WarningMessage(const AMsg: string);
   procedure ErrorMessage(const AMsg: string);
   procedure ErrorMessage(const AMsg: string);
@@ -158,6 +161,18 @@ begin
       TdxBarButton(ADxBtn).Action := AAction;
       TdxBarButton(ADxBtn).Action := AAction;
 end;
 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}
 {Message}
 procedure WarningMessage(const AMsg: string);
 procedure WarningMessage(const AMsg: string);
 begin
 begin