| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614 | unit rmGcl_XmjBillsDm;interfaceuses  SysUtils, Classes, ProjectData, DB, DBClient, sdIDTree, sdDB;type  {-----------------------------    gxtTopGcl: 汇总方式默认,写入方式:工程量清单1&其所属全部项目节, 工程量清单2&其所属全部项目节, ...;      示例: 202-1       456                   1-1  123                   1-2  333            203-1       222                   1-1  120                   1-2  102    gxtFlowGcl: 汇总方式默认,写入方式:工程量清单1所属全部项目节, 工程量清单2所属全部项目节, ...;      示例: 202-1  1-1  123            202-1  1-2  333            203-1  1-1  120            203-1  1-1  102    gxtWithoutXmj: 同gxtTopGcl,完成后过滤所有清单编号为空的节点      示例: 202-1       456            203-1       222  -----------------------------}  TGXType = (gxtTopGcl, gxtFlowGcl, gxtWithoutXmj);  TXmjNode = class  private    FCode: string;    FName: string;    FUnits: string;    FOrgQuantity: Double;    FOrgTotalPrice: Double;    FMisQuantity: Double;    FMisTotalPrice: Double;    FOthQuantity: Double;    FOthTotalPrice: Double;    FQuantity: Double;    FTotalPrice: Double;    FDrawingCode: string;    FPeg: string;    FNameDanWei: string;    FNameFenBu: string;    FNameFenXiang: string;    FNameUnit: string;    FPosition: string;  end;  TGclNode = class  private    FB_Code: string;    FIndexCode: string;    FName: string;    FUnits: string;    FPrice: Double;    FNewPrice: Double;    FDealQuantity: Double;    FDealTotalPrice: Double;    FOrgQuantity: Double;    FOrgTotalPrice: Double;    FMisQuantity: Double;    FMisTotalPrice: Double;    FOthQuantity: Double;    FOthTotalPrice: Double;    FQuantity: Double;    FTotalPrice: Double;    FXmjList: TList;    function FindXmjNode(ANode: TsdIDTreeNode): TXmjNode;    function NewXmjNode(ANode, APeg: TsdIDTreeNode): TXmjNode;    function GetXmjCount: Integer;    function GetXmjNode(AIndex: Integer): TXmjNode;  public    constructor Create;    destructor Destroy; override;    function AddXmjNode(ANode, APeg: TsdIDTreeNode): TXmjNode;    property XmjCount: Integer read GetXmjCount;    property XmjNode[AIndex: Integer]: TXmjNode read GetXmjNode;  end;  TrmGcl_XmjBillsData = class(TDataModule)    cdsGcl: TClientDataSet;    cdsGclIndexCode: TStringField;    cdsGclIndexID: TIntegerField;    cdsGclB_Code: TStringField;    cdsGclName: TWideStringField;    cdsGclCode: TStringField;    cdsGclPeg: TWideStringField;    cdsGclNameDanWei: TWideStringField;    cdsGclNameFenBu: TWideStringField;    cdsGclNameFenXiang: TWideStringField;    cdsGclNameUnit: TWideStringField;    cdsGclDrawingCode: TWideStringField;    cdsGclPrice: TFloatField;    cdsGclQuantity: TFloatField;    cdsGclTotalPrice: TFloatField;    cdsGclDealQuantity: TFloatField;    cdsGclDealTotalPrice: TFloatField;    cdsGclDifferQuantity: TFloatField;    cdsGclDifferTotalPrice: TFloatField;    cdsGclUnits: TWideStringField;    cdsGclNewPrice: TFloatField;    cdsGclPosition: TWideStringField;    cdsGclOrgQuantity: TFloatField;    cdsGclOrgTotalPrice: TFloatField;    cdsGclMisQuantity: TFloatField;    cdsGclMisTotalPrice: TFloatField;    cdsGclOthQuantity: TFloatField;    cdsGclOthTotalPrice: TFloatField;  private    FProjectData: TProjectData;    FGclList: TList;    FIndex: Integer;    FGXType: TGXType;    procedure BeforeOperation;    procedure AfterOperation;    procedure AddRelaLeafXmj(AGclNode: TGclNode; ARec: TsdDataRecord);    function GetGclNode(ARec: TsdDataRecord): TGclNode;    procedure FilterGclBills(ANode: TsdIDTreeNode);    procedure FilterBills(ANode: TsdIDTreeNode);    procedure FilterDealBills;    procedure WriteXmjNode(AGclNode: TGclNode);    procedure WriteGclNode(AGclNode: TGclNode);    procedure WriteTopGclTypeData;    procedure WriteFlowGclNode(AGclNode: TGclNode);    procedure WriteFlowGclTypeData;    procedure WriteData;  public    function AssignData(AProjectData: TProjectData; AGXType: TGXType): TDataSet;  end;implementationuses  ZhAPI, UtilMethods;{$R *.dfm}{ TGclNode }constructor TGclNode.Create;begin  FXmjList := TList.Create;end;destructor TGclNode.Destroy;begin  ClearObjects(FXmjList);  FXmjList.Free;  inherited;end;function TGclNode.FindXmjNode(ANode: TsdIDTreeNode): TXmjNode;var  i: Integer;begin  Result := nil;  for i := 0 to XmjCount - 1 do  begin    if SameText(XmjNode[i].FCode, ANode.Rec.ValueByName('Code').AsString) and       SameText(XmjNode[i].FName, ANode.Rec.ValueByName('Name').AsString) and       SameText(XmjNode[i].FUnits, ANode.Rec.ValueByName('Units').AsString) then    begin      Result := XmjNode[i];      Break;    end;  end;end;function TGclNode.AddXmjNode(  ANode, APeg: TsdIDTreeNode): TXmjNode;begin  Result := FindXmjNode(ANode);  if not Assigned(Result) then    Result := NewXmjNode(ANode, APeg);end;function TGclNode.GetXmjCount: Integer;begin  Result := FXmjList.Count;end;function TGclNode.GetXmjNode(AIndex: Integer): TXmjNode;begin  Result := TXmjNode(FXmjList.Items[AIndex]);end;function TGclNode.NewXmjNode(  ANode, APeg: TsdIDTreeNode): TXmjNode;  function GetPegName(APegNode: TsdIDTreeNode): string;  begin    if Assigned(APegNode) then      Result := APegNode.Rec.ValueByName('Name').AsString    else      Result := '';  end;  // 取树结构的第ALevel层节点的名称(level从0开始)  function GetNameByLevel(ANode: TsdIDTreeNode; ALevel: Integer): string;  begin    Result := '';    if not Assigned(ANode) then Exit;    if ANode.Level = ALevel then      Result := ANode.Rec.ValueByName('Name').AsString    else if ANode.Level > ALevel then      Result := GetNameByLevel(ANode.Parent, ALevel);  end;  function GetNameDanWei(ANode: TsdIDTreeNode): string;  begin    // 取树结构的第二层节点的名称    Result := GetNameByLevel(ANode, 1);  end;  // ANode为计量单元节点,APegNode为桩号节点  function GetNameFenBu(ANode, APegNode: TsdIDTreeNode): string;  var    vCurNode: TsdIDTreeNode;  begin    // 如果计量单元节点的名称为桩号(转化为判断计量单元节点与桩号节点为同一个)    if not Assigned(APegNode) or (ANode.ID = APegNode.ID) then      // 取树结构的第三层节点的名称      Result := GetNameByLevel(ANode, 2)    // 否则,取桩号节点的子节点的名称    else    begin      vCurNode := ANode;      while vCurNode.Level > APegNode.Level + 1 do        vCurNode := vCurNode.Parent;      Result := vCurNode.Rec.ValueByName('Name').AsString;    end;  end;  function GetNameFenXiang(ANode, APegNode: TsdIDTreeNode): string;  var    iTopLevel: Integer;    vCurNode: TsdIDTreeNode;  begin    if Assigned(APegNode) then    begin      iTopLevel := 3;      if APegNode.ID <> ANode.ID then        iTopLevel := APegNode.Level + 2;      Result := '';      vCurNode := ANode.Parent;      while vCurNode.Level >= iTopLevel do      begin        Result := vCurNode.Rec.ValueByName('Name').AsString + ';' + Result;        vCurNode := vCurNode.Parent;      end;    end    else      Result := GetNameByLevel(ANode, 3);  end;  function GetNameUnit(ANode: TsdIDTreeNode): string;  begin    Result := ANode.Rec.ValueByName('Name').AsString;  end;  function GetDrawingCode(ANode: TsdIDTreeNode): string;  begin    Result := '';    if not Assigned(ANode) then Exit;    Result := ANode.Rec.ValueByName('DrawingCode').AsString;    if Result = '' then      Result := GetDrawingCode(ANode.Parent);  end;  function GetPosition(ANode, APegNode: TsdIDTreeNode): string;  begin    // 如果计量单元节点的名称为桩号(转化为判断计量单元节点与桩号节点为同一个)    if not Assigned(APegNode) or (ANode.ID = APegNode.ID) then      // 取分部工程      Result := GetNameFenXiang(ANode, APegNode)    // 反之,取分项工程+计量单元    else      Result := GetNameFenXiang(ANode, APegNode) + GetNameUnit(ANode);  end;begin  Result := TXmjNode.Create;  FXmjList.Add(Result);  Result.FCode := ANode.Rec.ValueByName('Code').AsString;  Result.FName := ANode.Rec.ValueByName('Name').AsString;  Result.FUnits := ANode.Rec.ValueByName('Units').AsString;  Result.FPeg := GetPegName(APeg);  Result.FNameDanWei := GetNameDanWei(ANode);  Result.FNameFenBu := GetNameFenBu(ANode, APeg);  Result.FNameFenXiang := GetNameFenXiang(ANode, APeg);  Result.FNameUnit := GetNameUnit(ANode);  Result.FPosition := GetPosition(ANode, APeg);  Result.FDrawingCode := GetDrawingCode(ANode);end;{ TrmGclBillsData }procedure TrmGcl_XmjBillsData.AddRelaLeafXmj(AGclNode: TGclNode;  ARec: TsdDataRecord);  function GetFirstXmjParent(AID: Integer): TsdIDTreeNode;  begin    with TProjectData(FProjectData).BillsCompileData do      Result := BillsCompileTree.FindNode(AID);    while Assigned(Result) and (Result.Rec.ValueByName('B_Code').AsString <> '') do      Result := Result.Parent;  end;  function GetPegNode(ANode: TsdIDTreeNode): TsdIDTreeNode;  begin    Result := nil;    if not Assigned(ANode) then Exit;    if CheckPeg(ANode.Rec.ValueByName('Name').AsString) then      Result := ANode    else      Result := GetPegNode(ANode.Parent);  end;var  vNode, vPeg: TsdIDTreeNode;  XmjNode: TXmjNode;begin  vNode := GetFirstXmjParent(ARec.ValueByName('ID').AsInteger);  if not Assigned(vNode) then Exit;  vPeg := GetPegNode(vNode);  XmjNode := AGclNode.AddXmjNode(vNode, vPeg);  XmjNode.FOrgQuantity := XmjNode.FOrgQuantity + ARec.ValueByName('OrgQuantity').AsFloat;  XmjNode.FOrgTotalPrice := XmjNode.FOrgTotalPrice + ARec.ValueByName('OrgTotalPrice').AsFloat;  XmjNode.FMisQuantity := XmjNode.FMisQuantity + ARec.ValueByName('MisQuantity').AsFloat;  XmjNode.FMisTotalPrice := XmjNode.FMisTotalPrice + ARec.ValueByName('MisTotalPrice').AsFloat;  XmjNode.FOthQuantity := XmjNode.FOthQuantity + ARec.ValueByName('OthQuantity').AsFloat;  XmjNode.FOthTotalPrice := XmjNode.FOthTotalPrice + ARec.ValueByName('OthTotalPrice').AsFloat;  XmjNode.FQuantity := XmjNode.FQuantity + ARec.ValueByName('Quantity').AsFloat;  XmjNode.FTotalPrice := XmjNode.FTotalPrice + ARec.ValueByName('TotalPrice').AsFloat;end;procedure TrmGcl_XmjBillsData.AfterOperation;begin  ClearObjects(FGclList);  FGclList.Free;  if FGXType = gxtWithoutXmj then  begin    cdsGcl.Filter := 'B_Code <> ''''';    cdsGcl.Filtered := True;  end;  cdsGcl.IndexFieldNames := 'IndexCode;IndexID';end;function TrmGcl_XmjBillsData.AssignData(  AProjectData: TProjectData; AGXType: TGXType): TDataSet;begin  FGXType := AGXType;  BeforeOperation;  try    FProjectData := AProjectData;    FilterBills(AProjectData.BillsCompileData.BillsCompileTree.FirstNode);    FilterDealBills;    WriteData;  finally    AfterOperation;    Result := cdsGcl;  end;end;procedure TrmGcl_XmjBillsData.BeforeOperation;begin  FGclList := TList.Create;  cdsGcl.Active := True;  cdsGcl.Filtered := False;  cdsGcl.EmptyDataSet;end;procedure TrmGcl_XmjBillsData.FilterBills(ANode: TsdIDTreeNode);begin  if not Assigned(ANode) then Exit;  if ANode.HasChildren then    FilterBills(ANode.FirstChild)  else    FilterGclBills(ANode);  FilterBills(ANode.NextSibling);end;procedure TrmGcl_XmjBillsData.FilterDealBills;var  iIndex: Integer;  Rec: TsdDataRecord;  GclNode: TGclNode;begin  with FProjectData.DealBillsData do    for iIndex := 0 to sddDealBills.RecordCount - 1 do    begin      Rec := sddDealBills.Records[iIndex];      GclNode := GetGclNode(Rec);      GclNode.FDealQuantity := GclNode.FDealQuantity + Rec.ValueByName('Quantity').AsFloat;      GclNode.FDealTotalPrice := GclNode.FDealTotalPrice + Rec.ValueByName('TotalPrice').AsFloat;    end;end;procedure TrmGcl_XmjBillsData.FilterGclBills(ANode: TsdIDTreeNode);var  Rec: TsdDataRecord;  GclNode: TGclNode;begin  if not Assigned(ANode) then Exit;  Rec := ANode.Rec;  if Rec.ValueByName('B_Code').AsString = '' then Exit;  GclNode := GetGclNode(Rec);  GclNode.FOrgQuantity := GclNode.FOrgQuantity + Rec.ValueByName('OrgQuantity').AsFloat;  GclNode.FOrgTotalPrice := GclNode.FOrgTotalPrice + Rec.ValueByName('OrgTotalPrice').AsFloat;  GclNode.FMisQuantity := GclNode.FMisQuantity + Rec.ValueByName('MisQuantity').AsFloat;  GclNode.FMisTotalPrice := GclNode.FMisTotalPrice + Rec.ValueByName('MisTotalPrice').AsFloat;  GclNode.FOthQuantity := GclNode.FOthQuantity + Rec.ValueByName('OthQuantity').AsFloat;  GclNode.FOthTotalPrice := GclNode.FOthTotalPrice + Rec.ValueByName('OthTotalPrice').AsFloat;  GclNode.FQuantity := GclNode.FQuantity + Rec.ValueByName('Quantity').AsFloat;  GclNode.FTotalPrice := GclNode.FTotalPrice + Rec.ValueByName('TotalPrice').AsFloat;  AddRelaLeafXmj(GclNode, Rec);end;function TrmGcl_XmjBillsData.GetGclNode(ARec: TsdDataRecord): TGclNode;  function CreateGclNode: TGclNode;  begin    Result := TGclNode.Create;    FGclList.Add(Result);    Result.FB_Code := ARec.ValueByName('B_Code').AsString;    Result.FIndexCode := B_CodeToIndexCode(ARec.ValueByName('B_Code').AsString);    Result.FName := Trim(ARec.ValueByName('Name').AsString);    Result.FUnits := ARec.ValueByName('Units').AsString;    Result.FPrice := ARec.ValueByName('Price').AsFloat;    if Assigned(ARec.ValueByName('NewPrice')) then      Result.FNewPrice := ARec.ValueByName('NewPrice').AsFloat    else      Result.FNewPrice := 0;  end;var  I: Integer;  GclNode: TGclNode;begin  Result := nil;  for I := 0 to FGclList.Count - 1 do  begin    GclNode := TGclNode(FGclList.Items[I]);    if SameText(GclNode.FB_Code, ARec.ValueByName('B_Code').AsString) and        SameText(GclNode.FName, Trim(ARec.ValueByName('Name').AsString)) and        SameText(GclNode.FUnits, ARec.ValueByName('Units').AsString) and        (GclNode.FPrice = ARec.ValueByName('Price').AsFloat) then    begin      Result := GclNode;      Break;    end;  end;  if not Assigned(Result) then    Result := CreateGclNode;end;procedure TrmGcl_XmjBillsData.WriteData;begin  case FGXType of    gxtTopGcl, gxtWithoutXmj: WriteTopGclTypeData;    gxtFlowGcl: WriteFlowGclTypeData;  end;end;procedure TrmGcl_XmjBillsData.WriteFlowGclNode(AGclNode: TGclNode);var  i: Integer;  XmjNode: TXmjNode;begin  for i := 0 to AGclNode.XmjCount - 1 do  begin    XmjNode := AGclNode.XmjNode[i];    cdsGcl.Append;    cdsGclIndexCode.AsString := AGclNode.FIndexCode;    cdsGclIndexID.AsInteger := i+1;    cdsGclB_Code.AsString := AGclNode.FB_Code;    cdsGclName.AsString := AGclNode.FName;    cdsGclUnits.AsString := AGclNode.FUnits;    cdsGclPrice.AsFloat := AGclNode.FPrice;    cdsGclNewPrice.AsFloat := AGclNode.FNewPrice;    cdsGclCode.AsString := XmjNode.FCode;    cdsGclPeg.AsString := XmjNode.FPeg;    cdsGclNameDanWei.AsString := XmjNode.FNameDanWei;    cdsGclNameFenBu.AsString := XmjNode.FNameFenBu;    cdsGclNameFenXiang.AsString := XmjNode.FNameFenXiang;    cdsGclNameUnit.AsString := XmjNode.FNameUnit;    cdsGclDrawingCode.AsString := XmjNode.FDrawingCode;    cdsGclPosition.AsString := XmjNode.FPosition;    cdsGclOrgQuantity.AsFloat := XmjNode.FOrgQuantity;    cdsGclOrgTotalPrice.AsFloat := XmjNode.FOrgTotalPrice;    cdsGclMisQuantity.AsFloat := XmjNode.FMisQuantity;    cdsGclMisTotalPrice.AsFloat := XmjNode.FMisTotalPrice;    cdsGclOthQuantity.AsFloat := XmjNode.FOthQuantity;    cdsGclOthTotalPrice.AsFloat := XmjNode.FOthTotalPrice;    cdsGclQuantity.AsFloat := XmjNode.FQuantity;    cdsGclTotalPrice.AsFloat := XmjNode.FTotalPrice;    cdsGcl.Post;  end;end;procedure TrmGcl_XmjBillsData.WriteFlowGclTypeData;var  i: Integer;begin  FIndex := 0;  for i := 0 to FGclList.Count - 1 do    WriteFlowGclNode(TGclNode(FGclList.Items[i]));end;procedure TrmGcl_XmjBillsData.WriteGclNode(  AGclNode: TGclNode);var  i: Integer;begin  cdsGcl.Append;  cdsGclIndexCode.AsString := AGclNode.FIndexCode;  cdsGclIndexID.AsInteger := 0;  cdsGclB_Code.AsString := AGclNode.FB_Code;  cdsGclName.AsString := AGclNode.FName;  cdsGclUnits.AsString := AGclNode.FUnits;  cdsGclPrice.AsFloat := AGclNode.FPrice;  cdsGclNewPrice.AsFloat := AGclNode.FNewPrice;  cdsGclQuantity.AsFloat := AGclNode.FQuantity;  cdsGclTotalPrice.AsFloat := AGclNode.FTotalPrice;  cdsGclDealQuantity.AsFloat := AGclNode.FDealQuantity;  cdsGclDealTotalPrice.AsFloat := AGclNode.FDealTotalPrice;  cdsGclDifferQuantity.AsFloat := AGclNode.FDealQuantity - AGclNode.FQuantity;  cdsGclDifferTotalPrice.AsFloat := AGclNode.FDealTotalPrice - AGclNode.FTotalPrice;  cdsGclOrgQuantity.AsFloat := AGclNode.FOrgQuantity;  cdsGclOrgTotalPrice.AsFloat := AGclNode.FOrgTotalPrice;  cdsGclMisQuantity.AsFloat := AGclNode.FMisQuantity;  cdsGclMisTotalPrice.AsFloat := AGclNode.FMisTotalPrice;  cdsGclOthQuantity.AsFloat := AGclNode.FOthQuantity;  cdsGclOthTotalPrice.AsFloat := AGclNode.FOthTotalPrice;  cdsGcl.Post;  WriteXmjNode(AGclNode);end;procedure TrmGcl_XmjBillsData.WriteTopGclTypeData;var  i: Integer;begin  FIndex := 0;  for i := 0 to FGclList.Count - 1 do    WriteGclNode(TGclNode(FGclList.Items[i]));end;procedure TrmGcl_XmjBillsData.WriteXmjNode(  AGclNode: TGclNode);var  i: Integer;  XmjNode: TXmjNode;begin  for i := 0 to AGclNode.XmjCount - 1 do  begin    XmjNode := AGclNode.XmjNode[i];    cdsGcl.Append;    cdsGclIndexCode.AsString := AGclNode.FIndexCode;    cdsGclIndexID.AsInteger := FIndex;    cdsGclCode.AsString := XmjNode.FCode;    cdsGclPeg.AsString := XmjNode.FPeg;    cdsGclNameDanWei.AsString := XmjNode.FNameDanWei;    cdsGclNameFenBu.AsString := XmjNode.FNameFenBu;    cdsGclNameFenXiang.AsString := XmjNode.FNameFenXiang;    cdsGclNameUnit.AsString := XmjNode.FNameUnit;    cdsGclPosition.AsString := XmjNode.FPosition;    cdsGclDrawingCode.AsString := XmjNode.FDrawingCode;    cdsGclOrgQuantity.AsFloat := XmjNode.FOrgQuantity;    cdsGclOrgTotalPrice.AsFloat := XmjNode.FOrgTotalPrice;    cdsGclMisQuantity.AsFloat := XmjNode.FMisQuantity;    cdsGclMisTotalPrice.AsFloat := XmjNode.FMisTotalPrice;    cdsGclOthQuantity.AsFloat := XmjNode.FOthQuantity;    cdsGclOthTotalPrice.AsFloat := XmjNode.FOthTotalPrice;    cdsGclQuantity.AsFloat := XmjNode.FQuantity;    cdsGclTotalPrice.AsFloat := XmjNode.FTotalPrice;    cdsGcl.Post;    Inc(FIndex);  end;end;end.
 |