123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- unit ExcelImport_Bills;
- // 导入0号台账/分项清单
- interface
- uses
- DetailExcelImport, Classes, MCacheTree, sdDB, ProjectData, OExport;
- type
- Tdei_CustomBills = class(TDetailExcelImport)
- private
- FCacheTree: TBillsCacheTree;
- FCurRow: Integer;
- FIsFirstPart: Boolean;
- FWithLevelCode: Boolean;
- FWithoutGclBills: Boolean;
- FBaseTree: TBillsCacheTree;
- FFixedIDNodes: TList;
- FCodeCol: Integer;
- FB_CodeCol: Integer;
- FNameCol: Integer;
- FUnitsCol: Integer;
- FPriceCol: Integer;
- FOrgQuantityCol: Integer;
- FMisQuantityCol: Integer;
- FOthQuantityCol: Integer;
- FDgnQuantity1Col: Integer;
- FDgnQuantity2Col: Integer;
- FDrawingCol: Integer;
- FMemoCol: Integer;
- FLevelCol: Integer;
- protected
- procedure BeginImport; override;
- procedure EndImport; override;
- function GetFixedIDNode(AID: Integer): TBillsCacheNode;
- function GetFixedID(ACode, AName: string): Integer;
- procedure CheckFixedIDNodes;
- procedure LoadColumnsFromHead(ASheet: TExportWorkSheet);
- procedure LoadBaseTree(ATree: TBillsCacheTree);
- procedure LoadNode(ARow: TExportRow);
- procedure LoadNodes(ASheet: TExportWorkSheet);
- procedure WriteNode(ADataSet: TsdDataSet; ANode: TBillsCacheNode);
- procedure WriteNodes(ADataSet: TsdDataSet);
- procedure Import; override;
- public
- procedure ImportFile(const AFileName: string; AWithLevelCode, AWithoutGclBills: Boolean); overload;
- end;
- implementation
- uses
- Forms, Controls, ProgressHintFrm, ConstUnit, UtilMethods, ExcelImport,
- SysUtils, mDataRecord, XLSAdapter;
- { Tdei_CustomBills }
- procedure Tdei_CustomBills.BeginImport;
- begin
- Screen.Cursor := crHourGlass;
- ShowProgressHint('导入Excel数据', 100, '读取Excel数据', 100);
- FCurRow := 0;
- FIsFirstPart := True;
- FCacheTree := TBillsCacheTree.Create;
- FCacheTree.NewNodeID := 101;
- // 以层次编号为依据,分隔用'.',以项目节、清单编号为依据,分隔用'-'
- if FWithLevelCode then
- FCacheTree.SeparateChar := '.'
- else
- FCacheTree.SeparateChar := '-';
- FCacheTree.AutoSort := True;
- ProjectData.DisConnectTree;
- ProjectData.BillsData.DisableEvents;
- FBaseTree := TBillsCacheTree.Create;
- FBaseTree.NewNodeID := 101;
- FBaseTree.SeparateChar := '.';
- FFixedIDNodes := TList.Create;
- end;
- procedure Tdei_CustomBills.CheckFixedIDNodes;
- function GetHintStr(ANode: TBillsCacheNode): string;
- begin
- Result := '';
- if ANode.Code <> '' then
- Result := Result + '编号:' + ANode.Code + ';';
- if ANode.Name <> '' then
- Result := Result + '名称:' + ANode.Name + ';';
- end;
- function GetInvalidModel(ANoPM: Boolean; ACount: Integer): string;
- begin
- if ANoPM then
- begin
- if ACount > 1 then
- Result := '价差功能,部分报表'
- else
- Result := '价差功能'
- end
- else
- Result := '部分报表';
- Result := Result + '将不可使用' + #13#10 + '如有疑问,请联系纵横客服,企业QQ:800003850 电话:(0756)3850888';
- end;
- var
- sgs: TStrings;
- iBase: Integer;
- vBase, vImport: TBillsCacheNode;
- sHint: string;
- bNoPM: Boolean;
- begin
- bNoPM := False;
- sgs := TStringList.Create;
- try
- sgs.Add('缺少如下固定清单节点:');
- for iBase := 0 to FBaseTree.FixedIDNodes.Count - 1 do
- begin
- vBase := TBillsCacheNode(FBaseTree.FixedIDNodes.Items[iBase]);
- vImport := FCacheTree.FindFixedIDNode(vBase.ID);
- if not Assigned(vImport) then
- begin
- sgs.Add(GetHintStr(vBase));
- if vBase.ID = iPriceMarginID then
- bNoPM := True;
- end;
- end;
- finally
- if sgs.Count > 1 then
- begin
- sgs.Add(GetInvalidModel(bNoPM, sgs.Count - 1));
- WarningMessage(sgs.Text);
- end;
- sgs.Free;
- end;
- end;
- procedure Tdei_CustomBills.EndImport;
- begin
- {if FWithLevelCode then
- CheckFixedIDNodes;}
- FFixedIDNodes.Free;
- FBaseTree.Free;
- ProjectData.BillsData.EnableEvents;
- ProjectData.ReConnectTree;
- FCacheTree.Free;
- ProjectData.BillsCompileData.CalculateAll;
- CloseProgressHint;
- Screen.Cursor := crDefault;
- end;
- function Tdei_CustomBills.GetFixedID(ACode, AName: string): Integer;
- var
- i: Integer;
- Node: TBillsCacheNode;
- begin
- Result := -1;
- for i := 0 to FBaseTree.CacheNodes.Count - 1 do
- begin
- Node := TBillsCacheNode(FBaseTree.CacheNodes.Items[i]);
- if (Node.Code = ACode) and (Node.Name = AName) then
- begin
- if Node.ID < 100 then
- Result := Node.ID;
- Break;
- end;
- end;
- end;
- function Tdei_CustomBills.GetFixedIDNode(AID: Integer): TBillsCacheNode;
- var
- i: Integer;
- Node: TBillsCacheNode;
- begin
- Result := nil;
- for i := 0 to FFixedIDNodes.Count - 1 do
- begin
- Node := TBillsCacheNode(FFixedIDNodes.Items[i]);
- if (AID = Node.ID) then
- begin
- Result := Node;
- Break;
- end;
- end;
- end;
- procedure Tdei_CustomBills.Import;
- begin
- if FWithLevelCode then
- LoadBaseTree(FBaseTree)
- else
- LoadBaseTree(FCacheTree);
- LoadColumnsFromHead(OExport.OpenWorkSheet);
- LoadNodes(OExport.OpenWorkSheet);
- WriteNodes(ProjectData.BillsData.sddBills);
- end;
- procedure Tdei_CustomBills.ImportFile(const AFileName: string;
- AWithLevelCode, AWithoutGclBills: Boolean);
- begin
- FWithLevelCode := AWithLevelCode;
- FWithoutGclBills := AWithoutGclBills;
- ImportFile(AFileName);
- end;
- procedure Tdei_CustomBills.LoadBaseTree(ATree: TBillsCacheTree);
- var
- BaseImportor: TBillsExcelImport;
- begin
- BaseImportor := TBillsExcelImport.Create(nil);
- try
- BaseImportor.ImportToTree(ATree, GetTemplateBillsFileName);
- finally
- BaseImportor.Free;
- end;
- end;
- procedure Tdei_CustomBills.LoadColumnsFromHead(ASheet: TExportWorkSheet);
- var
- vRow: TExportRow;
- iCol: Integer;
- sColName: string;
- begin
- FCodeCol := -1;
- FB_CodeCol := -1;
- FNameCol := -1;
- FUnitsCol := -1;
- FPriceCol := -1;
- FOrgQuantityCol := -1;
- FMisQuantityCol := -1;
- FOthQuantityCol := -1;
- FDgnQuantity1Col := -1;
- FDgnQuantity2Col := -1;
- FDrawingCol := -1;
- FMemoCol := -1;
- FLevelCol := -1;
- vRow := ASheet.Rows[FCurRow];
- for iCol := 0 to vRow.Cells.Count - 1 do
- begin
- sColName := GetCellTrimStr(vRow, iCol);
- if Pos('项目节', sColName) > 0 then
- FCodeCol := iCol
- else if (sColName = '清单编号') or (Pos('子目号', sColName) > 0) then
- FB_CodeCol := iCol
- else if sColName = '名称' then
- FNameCol := iCol
- else if sColName = '单位' then
- FUnitsCol := iCol
- else if sColName = '单价' then
- FPriceCol := iCol
- else if (sColName = '清单数量') or (sColName = '工程量') or (sColName = '数量') or (sColName = '施工图数量') then
- FOrgQuantityCol := iCol
- else if (sColName = '设计错漏数量') then
- FMisQuantityCol := iCol
- else if (sColName = '其他错漏数量') then
- FOthQuantityCol := iCol
- else if (sColName = '设计数量1') or (sColName = '数量1') then
- FDgnQuantity1Col := iCol
- else if (sColName = '设计数量2') or (sColName = '数量2') then
- FDgnQuantity2Col := iCol
- else if sColName = '图号' then
- FDrawingCol := iCol
- else if sColName = '备注' then
- FMemoCol := iCol
- else if sColName = '层次编号' then
- FLevelCol := iCol;
- end;
- Inc(FCurRow);
- end;
- procedure Tdei_CustomBills.LoadNode(ARow: TExportRow);
- var
- sLevelCode, sCode, sB_Code, sName: string;
- Node: TBillsCacheNode;
- vValue: Variant;
- iFixedID: Integer;
- begin
- sLevelCode := GetCellTrimStr(ARow, FLevelCol);
- sCode := GetCellTrimStr(ARow, FCodeCol);
- sB_Code := GetCellTrimStr(ARow, FB_CodeCol);
- sName := GetCellTrimStr(ARow, FNameCol);
- // 含层次编号时,层次编号为空不导入
- // 不含层次编号时,仅导入第一部分,且项目节编号、清单编号均未空时不导入
- if FWithLevelCode then
- begin
- if sLevelCode = '' then Exit;
- end;
- (*
- else
- begin
- if ((sCode = '') and (sB_Code = '')) or SameText(sCode, '2') or
- (Pos('第二部分', sName) > 0) then
- begin
- FIsFirstPart := False;
- Exit;
- end;
- end;
- *)
- if (sCode = '') and FWithoutGclBills then Exit;
- // 含层次编号时,以层次编号为依据新增节点;反之以项目节编号为依据新增节点
- if not FWithLevelCode then
- begin
- if (sB_Code = '') then
- Node := FCacheTree.AddNodeByCodeName(sCode, sName)
- else
- Node := FCacheTree.AddLeafBillsNode(sB_Code);
- end
- else
- begin
- // 1. 从模板树中查询当前节点是否为固定ID,否则为-1
- iFixedID := GetFixedID(sCode, sName);
- // 2. 从导入树中查询是否添加过该固定ID,防止存在两个固定ID节点主键冲突
- // 如果已添加过固定ID节点,则其他节点未非固定ID节点
- Node := GetFixedIDNode(iFixedID);
- if Assigned(Node) then
- iFixedID := -1;
- // 3. 添加当前节点
- Node := FCacheTree.AddNodeByCode(sLevelCode, iFixedID);
- // 4. 如果当前添加的节点为固定ID节点,则添加到List中便于2快速查找
- if Node.ID < 100 then
- FFixedIDNodes.Add(Node);
- end;
- Node.Code := sCode;
- Node.B_Code := sB_Code;
- Node.Name := sName;
- Node.Units := GetCellTrimStr(ARow, FUnitsCol);
- Node.Price := GetCellFloat(ARow, FPriceCol);
- Node.OrgQuantity := GetCellFloat(ARow, FOrgQuantityCol);
- Node.MisQuantity := GetCellFloat(ARow, FMisQuantityCol);
- Node.OthQuantity := GetCellFloat(ARow, FOthQuantityCol);
- Node.DgnQuantity1 := GetCellFloat(ARow, FDgnQuantity1Col);
- Node.DgnQuantity2 := GetCellFloat(ARow, FDgnQuantity2Col);
- Node.DrawingCode := GetCellTrimStr(ARow, FDrawingCol);
- Node.MemoStr := GetCellTrimStr(ARow, FMemoCol);
- end;
- procedure Tdei_CustomBills.LoadNodes(ASheet: TExportWorkSheet);
- var
- iPos, iSubPos: Integer;
- begin
- while (FCurRow < ASheet.Rows.Count){ and FIsFirstPart }do
- begin
- LoadNode(ASheet.Rows[FCurRow]);
- Inc(FCurRow);
- iSubPos := (FCurRow + 1) * 100 div ASheet.Rows.Count;
- iPos := iSubPos div 2;
- UpdateProgressPosition(iPos, iSubPos);
- end;
- end;
- procedure Tdei_CustomBills.WriteNode(ADataSet: TsdDataSet;
- ANode: TBillsCacheNode);
- var
- Rec: TBillsRecord;
- begin
- if ANode.Code <> '' then
- UpdateProgressHint('写入读取的Excel数据 ' + ANode.Code)
- else if ANode.B_Code <> '' then
- UpdateProgressHint('写入读取的Excel数据 ' + ANode.B_Code)
- else
- UpdateProgressHint('写入读取的Excel数据 ' + ANode.Name);
- Rec := TBillsRecord(ADataSet.Add);
- Rec.ID.AsInteger := ANode.ID;
- Rec.ParentID.AsInteger := ANode.ParentID;
- Rec.NextSiblingID.AsInteger := ANode.NextSiblingID;
- Rec.Code.AsString := ANode.Code;
- Rec.B_Code.AsString := ANode.B_Code;
- Rec.Name.AsString := ANode.Name;
- Rec.Units.AsString := ANode.Units;
- Rec.Price.AsFloat := PriceRoundTo(ANode.Price);
- Rec.OrgQuantity.AsFloat := QuantityRoundTo(ANode.OrgQuantity);
- Rec.MisQuantity.AsFloat := QuantityRoundTo(ANode.MisQuantity);
- Rec.OthQuantity.AsFloat := QuantityRoundTo(ANode.OthQuantity);
- Rec.DgnQuantity1.AsFloat := QuantityRoundTo(ANode.DgnQuantity1);
- Rec.DgnQuantity2.AsFloat := QuantityRoundTo(ANode.DgnQuantity2);
- Rec.DrawingCode.AsString := ANode.DrawingCode;
- Rec.MemoStr.AsString := ANode.MemoStr;
- end;
- procedure Tdei_CustomBills.WriteNodes(ADataSet: TsdDataSet);
- var
- i, iPos, iSubPos: Integer;
- begin
- UpdateProgressHint('写入读取的Excel数据', True);
- UpdateProgressPosition(50, 0);
- ADataSet.DeleteAll;
- for i := 0 to FCacheTree.CacheNodes.Count - 1 do
- begin
- WriteNode(ADataSet, TBillsCacheNode(FCacheTree.CacheNodes[i]));
- iSubPos := i*100 div FCacheTree.CacheNodes.Count;
- iPos := 50 + iSubPos div 2;
- UpdateProgressPosition(iPos, iSubPos);
- end;
- UpdateProgressPosition(100, 100);
- end;
- end.
|