12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004 |
- unit ExcelImport;
- interface
- uses
- Classes, SMXLS, SMCells, ProjectData, MCacheTree, ZhAPI, sdDB,
- Forms, Controls, ProgressHintFrm, mDataRecord;
- type
- TExcelImport = class
- private
- FMSExcel: TMSExcel;
- FProjectData: TProjectData;
- FProgresssHintFrom: TProgressHintForm;
- procedure BeginImport; virtual; abstract;
- procedure EndImport; virtual; abstract;
- procedure Import; virtual; abstract;
- function GetCellValue(ASheet: TSpreadSheet; ACol, ARow: Integer): Variant;
- function GetCellTrimText(ASheet: TSpreadSheet; ACol, ARow: Integer): string;
- public
- constructor Create(AProjectData: TProjectData);
- destructor Destroy; override;
- procedure ImportFile(const AExcelFile: string);
- property MSExcel: TMSExcel read FMSExcel;
- end;
- TBillsExcelImport = class(TExcelImport)
- private
- FCacheTree: TBillsCacheTree;
- FCurRow: Integer;
- FLevelCol: Integer;
- FCodeCol: Integer;
- FB_CodeCol: Integer;
- FNameCol: Integer;
- FUnitsCol: Integer;
- FFixedIDCol: Integer;
- FCanDeleteCol: Integer;
- procedure BeginImport; override;
- procedure EndImport; override;
- procedure LoadColumnsFromHead(ASheet: TSpreadSheet);
- procedure LoadNodes(ASheet: TSpreadSheet);
- procedure LoadNode(ASheet: TSpreadSheet);
- procedure WriteNode(ADataSet: TsdDataSet; ANode: TBillsCacheNode);
- procedure WriteNodes(ADataSet: TsdDataSet);
- procedure Import; override;
- public
- procedure ImportToTree(ACacheTree: TBillsCacheTree; const sFileName: string);
- end;
- // 代码中注释部分为导入[无层次编号]的0号台账Excel
- TBillsEdtExcelImport = class(TExcelImport)
- 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;
- FQuantityCol: Integer;
- FDgnQuantity1Col: Integer;
- FDgnQuantity2Col: Integer;
- FDrawingCol: Integer;
- FMemoCol: Integer;
- FLevelCol: Integer;
- procedure CheckFixedIDNodes;
- procedure BeginImport; override;
- procedure EndImport; override;
- function GetFixedIDNode(AID: Integer): TBillsCacheNode;
- function GetFixedID(ACode, AName: string): Integer;
- procedure LoadBaseTree(ATree: TBillsCacheTree);
- procedure LoadColumnsFromHead(ASheet: TSpreadSheet);
- procedure LoadNodes(ASheet: TSpreadSheet);
- procedure LoadNode(ASheet: TSpreadSheet);
- procedure WriteNode(ADataSet: TsdDataSet; ANode: TBillsCacheNode);
- procedure WriteNodes(ADataSet: TsdDataSet);
- procedure Import; override;
- public
- property WithLevelCode: Boolean read FWithLevelCode write FWithLevelCode;
- property WithoutGclBills: Boolean read FWithoutGclBills write FWithoutGclBills;
- end;
- TGclBillsExcelImport = class(TExcelImport)
- private
- FParentID: Integer;
- FSelectSheets: TList;
- FCacheTree: TGclCacheTree;
- FCurRow: Integer;
- FB_CodeCol: Integer;
- FNameCol: Integer;
- FUnitsCol: Integer;
- FPriceCol: Integer;
- FQuantityCol: Integer;
- procedure BeginImport; override;
- procedure EndImport; override;
- procedure LoadNode(ASheet: TSpreadSheet);
- procedure ImportSheet(ASheet: TSpreadSheet);
- procedure WriteNode(ADataSet: TsdDataSet; ANode: TGclCacheNode);
- procedure WriteNodes(ADataSet: TsdDataSet);
- procedure Import; override;
- public
- property ParentID: Integer read FParentID write FParentID;
- end;
- // 清单单价
- TBillsPriceExcelImport = class(TExcelImport)
- private
- FCurRow: Integer;
- FB_CodeCol: Integer;
- FNameCol: Integer;
- FPriceCol: Integer;
- procedure BeginImport; override;
- procedure EndImport; override;
- procedure LoadColumnsFromHead(ASheet: TSpreadSheet);
- procedure UpdateBillsPrice(const AB_Code: string; APrice: Double);
- procedure ImportBillsPriceData(ASheet: TSpreadSheet);
- procedure Import; override;
- end;
- // 合同清单
- TDealBillsExcelImport = class(TExcelImport)
- private
- FCurRow: Integer;
- FBillsID: Integer;
- FB_CodeCol: Integer;
- FNameCol: Integer;
- FUnitsCol: Integer;
- FPriceCol: Integer;
- FQuantityCol: Integer;
- FTotalPriceCol: Integer;
- procedure BeginImport; override;
- procedure EndImport; override;
- procedure LoadColumnsFromHead(ASheet: TSpreadSheet);
- procedure LoadDealBillsData(ASheet: TSpreadSheet);
- procedure Import; override;
- end;
- implementation
- uses Variants, CacheTree, SysUtils, UtilMethods, sdDataSet, BillsDm,
- DealBillsDm, SheetSelectFrm, ADODB, Math, ConstUnit;
- { TExcelImport }
- constructor TExcelImport.Create(AProjectData: TProjectData);
- begin
- FProjectData := AProjectData;
- FMSExcel := TMSExcel.Create(nil);
- end;
- destructor TExcelImport.Destroy;
- begin
- FMSExcel.Free;
- inherited;
- end;
- function TExcelImport.GetCellTrimText(ASheet: TSpreadSheet; ACol,
- ARow: Integer): string;
- begin
- Result := Trim(VarToStrDef(GetCellValue(ASheet, ACol, ARow), ''));
- end;
- function TExcelImport.GetCellValue(ASheet: TSpreadSheet;
- ACol, ARow: Integer): Variant;
- begin
- Result := Null;
- if ACol <> -1 then
- Result := ASheet.Cells.GetValue(ACol, ARow);
- end;
- procedure TExcelImport.ImportFile(const AExcelFile: string);
- begin
- BeginImport;
- try
- FMSExcel.LoadFromFile(AExcelFile);
- Import;
- finally
- EndImport;
- end;
- end;
- { TBillsExcelImport }
- procedure TBillsExcelImport.BeginImport;
- begin
- FCurRow := 0;
- FCacheTree := TBillsCacheTree.Create;
- FCacheTree.NewNodeID := 101;
- FCacheTree.SeparateChar := '.';
- FCacheTree.AutoSort := True;
- end;
- procedure TBillsExcelImport.EndImport;
- begin
- FCacheTree.Free;
- end;
- procedure TBillsExcelImport.Import;
- begin
- LoadColumnsFromHead(FMSExcel.Sheets.Spreadsheet(0));
- LoadNodes(FMSExcel.Sheets.Spreadsheet(0));
- WriteNodes(FProjectData.BillsData.sddBills);
- end;
- procedure TBillsExcelImport.ImportToTree(ACacheTree: TBillsCacheTree;
- const sFileName: string);
- var
- sChar: Char;
- begin
- FCurRow := 0;
- FCacheTree := ACacheTree;
- sChar := FCacheTree.SeparateChar;
- FCacheTree.SeparateChar := '.';
- MSExcel.LoadFromFile(sFileName);
- LoadColumnsFromHead(FMSExcel.Sheets.Spreadsheet(0));
- LoadNodes(FMSExcel.Sheets.Spreadsheet(0));
- FCacheTree.SeparateChar := sChar;
- end;
- procedure TBillsExcelImport.LoadColumnsFromHead(ASheet: TSpreadSheet);
- var
- iCol: Integer;
- sColName: string;
- begin
- for iCol := 0 to ASheet.Cells.UsedRowCount do
- begin
- sColName := VarToStrDef(ASheet.Cells.GetValue(iCol, FCurRow), '');
- if sColName = '层次编号' then
- FLevelCol := iCol
- else if sColName = '项目节编号' then
- FCodeCol := iCol
- else if sColName = '清单子目号' then
- FB_CodeCol := iCol
- else if sColName = '名称' then
- FNameCol := iCol
- else if sColName = '单位' then
- begin
- FUnitsCol := iCol;
- FFixedIDCol := iCol + 1;
- FCanDeleteCol := iCol + 2;
- end;
- end;
- Inc(FCurRow);
- end;
- procedure TBillsExcelImport.LoadNode(ASheet: TSpreadSheet);
- var
- sLevelCode: string;
- iFixedID: Integer;
- Node: TBillsCacheNode;
- vValue: Variant;
- begin
- sLevelCode := GetCellTrimText(ASheet, FLevelCol, FCurRow);
- if sLevelCode = '' then Exit;
- iFixedID := StrToIntDef(GetCellTrimText(ASheet, FFixedIDCol, FCurRow), -1);
- Node := FCacheTree.AddNodeByCode(sLevelCode, iFixedID);
- Node.Code := GetCellTrimText(ASheet, FCodeCol, FCurRow);
- Node.B_Code := GetCellTrimText(ASheet, FB_CodeCol, FCurRow);
- Node.Name := GetCellTrimText(ASheet, FNameCol, FCurRow);
- Node.Units := GetCellTrimText(ASheet, FUnitsCol, FCurRow);
- Node.CanDelete := VarToIntDef(GetCellValue(ASheet, FCanDeleteCol, FCurRow), 0) = 0;
- end;
- procedure TBillsExcelImport.LoadNodes(ASheet: TSpreadSheet);
- begin
- while FCurRow < ASheet.Cells.UsedRowCount do
- begin
- LoadNode(ASheet);
- Inc(FCurRow);
- end;
- end;
- procedure TBillsExcelImport.WriteNode(ADataSet: TsdDataSet;
- ANode: TBillsCacheNode);
- var
- Rec: TBillsRecord;
- begin
- 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.ValueByName('LockedLevel').AsBoolean := ANode.CanDelete;
- end;
- procedure TBillsExcelImport.WriteNodes(ADataSet: TsdDataSet);
- var
- i: Integer;
- begin
- for i := 0 to FCacheTree.CacheNodes.Count - 1 do
- WriteNode(ADataSet, TBillsCacheNode(FCacheTree.CacheNodes[i]));
- end;
- { TBillsEdtExcelImport }
- procedure TBillsEdtExcelImport.BeginImport;
- begin
- Screen.Cursor := crHourGlass;
- ShowProgressHint('导入Excel数据', 100, '读取Excel数据', 100);
- FCurRow := 0;
- FIsFirstPart := True;
- FCacheTree := TBillsCacheTree.Create;
- FCacheTree.NewNodeID := 101;
- // 以层次编号为依据,分隔用'.',以项目节、清单编号为依据,分隔用'-'
- if WithLevelCode then
- FCacheTree.SeparateChar := '.'
- else
- FCacheTree.SeparateChar := '-';
- FCacheTree.AutoSort := True;
- FProjectData.DisConnectTree;
- FProjectData.BillsData.DisableEvents;
- FBaseTree := TBillsCacheTree.Create;
- FBaseTree.NewNodeID := 101;
- FBaseTree.SeparateChar := '.';
- FFixedIDNodes := TList.Create;
- end;
- procedure TBillsEdtExcelImport.EndImport;
- begin
- // For Test
- // FCacheTree.SaveTreeToFile('E:\Tree.txt');
- if FWithLevelCode then
- CheckFixedIDNodes;
- FFixedIDNodes.Free;
- FBaseTree.Free;
- FProjectData.BillsData.EnableEvents;
- FProjectData.ReConnectTree;
- FCacheTree.Free;
- FProjectData.BillsCompileData.CalculateAll;
- CloseProgressHint;
- Screen.Cursor := crDefault;
- end;
- function TBillsEdtExcelImport.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;
- function TBillsEdtExcelImport.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;
- procedure TBillsEdtExcelImport.Import;
- begin
- if WithLevelCode then
- LoadBaseTree(FBaseTree)
- else
- LoadBaseTree(FCacheTree);
- LoadColumnsFromHead(FMSExcel.Sheets.Spreadsheet(0));
- LoadNodes(FMSExcel.Sheets.Spreadsheet(0));
- WriteNodes(FProjectData.BillsData.sddBills);
- end;
- procedure TBillsEdtExcelImport.LoadBaseTree(ATree: TBillsCacheTree);
- var
- BaseImportor: TBillsExcelImport;
- begin
- BaseImportor := TBillsExcelImport.Create(nil);
- try
- BaseImportor.ImportToTree(ATree, GetTemplateBillsFileName);
- finally
- BaseImportor.Free;
- end;
- end;
- procedure TBillsEdtExcelImport.LoadColumnsFromHead(ASheet: TSpreadSheet);
- var
- iCol: Integer;
- sColName: string;
- begin
- FCodeCol := -1;
- FB_CodeCol := -1;
- FNameCol := -1;
- FUnitsCol := -1;
- FPriceCol := -1;
- FQuantityCol := -1;
- FDgnQuantity1Col := -1;
- FDgnQuantity2Col := -1;
- FDrawingCol := -1;
- FMemoCol := -1;
- for iCol := 0 to ASheet.Cells.UsedRowCount do
- begin
- sColName := VarToStrDef(ASheet.Cells.GetValue(iCol, FCurRow), '');
- if (sColName = '预算项目节') or (sColName = '项目节编号') then
- FCodeCol := iCol
- else if (sColName = '清单子目号') or (sColName = '清单编号') 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 = '数量') then
- FQuantityCol := 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 TBillsEdtExcelImport.LoadNode(ASheet: TSpreadSheet);
- var
- sLevelCode, sCode, sB_Code, sName: string;
- Node: TBillsCacheNode;
- vValue: Variant;
- iFixedID: Integer;
- begin
- sLevelCode := GetCellTrimText(ASheet, FLevelCol, FCurRow);
- sCode := GetCellTrimText(ASheet, FCodeCol, FCurRow);
- sB_Code := GetCellTrimText(ASheet, FB_CodeCol, FCurRow);
- sName := GetCellTrimText(ASheet, FNameCol, FCurRow);
- // 含层次编号时,层次编号为空不导入
- // 不含层次编号时,仅导入第一部分,且项目节编号、清单编号均未空时不导入
- if WithLevelCode 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 WithLevelCode then
- begin
- if (sCode <> '') then
- Node := FCacheTree.AddNodeByCode(sCode, -1)
- 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 := GetCellTrimText(ASheet, FUnitsCol, FCurRow);
- Node.Price := StrToFloatDef(VarToStrDef(GetCellValue(ASheet, FPriceCol, FCurRow), ''), 0);
- Node.Quantity := StrToFloatDef(VarToStrDef(GetCellValue(ASheet, FQuantityCol, FCurRow), ''), 0);
- Node.DgnQuantity1 := StrToFloatDef(VarToStrDef(GetCellValue(ASheet, FDgnQuantity1Col, FCurRow), ''), 0);
- Node.DgnQuantity2 := StrToFloatDef(VarToStrDef(GetCellValue(ASheet, FDgnQuantity2Col, FCurRow), ''), 0);
- Node.DrawingCode := GetCellTrimText(ASheet, FDrawingCol, FCurRow);
- Node.MemoStr := GetCellTrimText(ASheet, FMemoCol, FCurRow);
- end;
- procedure TBillsEdtExcelImport.LoadNodes(ASheet: TSpreadSheet);
- var
- iPos, iSubPos: Integer;
- begin
- while (FCurRow < ASheet.Cells.UsedRowCount){ and FIsFirstPart }do
- begin
- LoadNode(ASheet);
- Inc(FCurRow);
- iSubPos := FCurRow * 100 div ASheet.Cells.UsedRowCount;
- iPos := iSubPos div 2;
- UpdateProgressPosition(iPos, iSubPos);
- end;
- end;
- procedure TBillsEdtExcelImport.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.Quantity);
- Rec.DgnQuantity1.AsFloat := QuantityRoundTo(ANode.DgnQuantity1);
- Rec.DgnQuantity2.AsFloat := QuantityRoundTo(ANode.DgnQuantity2);
- Rec.DrawingCode.AsString := ANode.DrawingCode;
- Rec.MemoStr.AsString := ANode.MemoStr;
- end;
- procedure TBillsEdtExcelImport.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;
- procedure TBillsEdtExcelImport.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;
- { TBillsPriceExcelImport }
- procedure TBillsPriceExcelImport.BeginImport;
- begin
- ShowProgressHint('导入Excel清单单价', 100);
- FProjectData.BillsData.sddBills.BeginUpdate;
- end;
- procedure TBillsPriceExcelImport.EndImport;
- begin
- FProjectData.BillsData.sddBills.EndUpdate;
- UpdateProgressHint('正在计算导入后的数据');
- FProjectData.BillsCompileData.CalculateAll;
- CloseProgressHint;
- end;
- procedure TBillsPriceExcelImport.Import;
- begin
- LoadColumnsFromHead(FMSExcel.Sheets.Spreadsheet(0));
- ImportBillsPriceData(FMSExcel.Sheets.Spreadsheet(0));
- end;
- procedure TBillsPriceExcelImport.ImportBillsPriceData(ASheet: TSpreadSheet);
- function CheckIsBillsCode(ACode: string): Boolean;
- const
- FBillsCodeSet: set of char = ['0'..'9', '-', 'a'..'z', 'A'..'Z'];
- var
- I: Integer;
- begin
- Result := True;
- I := 1;
- while I < Length(ACode) do
- if ACode[I] in FBillsCodeSet then
- Inc(I)
- else
- begin
- Result := False;
- Break;
- end;
- end;
- var
- iPos: Integer;
- sB_Code: string;
- fPrice: Double;
- begin
- UpdateProgressHint('写入读取的Excel数据');
- UpdateProgressPosition(0);
- while (FCurRow < ASheet.Cells.UsedRowCount) do
- begin
- sB_Code := GetCellTrimText(ASheet, FB_CodeCol, FCurRow);
- if (sB_Code <> '') and CheckIsBillsCode(sB_Code) then
- begin
- fPrice := StrToFloatDef(VarToStrDef(ASheet.Cells.GetValue(FPriceCol, FCurRow), ''), 0);
- UpdateBillsPrice(sB_Code, fPrice);
- end;
- Inc(FCurRow);
- iPos := FCurRow * 100 div ASheet.Cells.UsedRowCount;
- UpdateProgressPosition(iPos);
- end;
- UpdateProgressPosition(100);
- end;
- procedure TBillsPriceExcelImport.LoadColumnsFromHead(ASheet: TSpreadSheet);
- var
- iCol: Integer;
- sColName: string;
- begin
- FB_CodeCol := -1;
- FNameCol := -1;
- FPriceCol := -1;
- while ((FB_CodeCol = -1) or (FPriceCol = -1)) and (FCurRow < ASheet.Cells.UsedRowCount) do
- begin
- for iCol := 0 to ASheet.Cells.UsedColCount do
- begin
- sColName := GetCellTrimText(ASheet, iCol, FCurRow);
- if SameText(sColName, '清单编号') or SameText(sColName, '子目号') then
- FB_CodeCol := iCol
- else if SameText(sColName, '名称') then
- FNameCol := iCol
- else if Pos('单价', sColName) = 1 then
- FPriceCol := iCol;
- end;
- Inc(FCurRow);
- end;
- end;
- procedure TBillsPriceExcelImport.UpdateBillsPrice(const AB_Code: string;
- APrice: Double);
- var
- iIndex: Integer;
- Rec: TBillsRecord;
- begin
- with FProjectData.BillsData do
- begin
- for iIndex := 0 to sddBills.RecordCount - 1 do
- begin
- Rec := TBillsRecord(sddBills.Records[iIndex]);
- if SameText(AB_Code, Rec.B_Code.AsString) then
- Rec.Price.AsFloat := PriceRoundTo(APrice);
- end;
- end;
- end;
- { TDealBillsExcelImport }
- procedure TDealBillsExcelImport.BeginImport;
- begin
- FProjectData.DealBillsData.sddDealBills.BeginUpdate;
- end;
- procedure TDealBillsExcelImport.EndImport;
- begin
- FProjectData.DealBillsData.sddDealBills.EndUpdate;
- end;
- procedure TDealBillsExcelImport.Import;
- begin
- LoadColumnsFromHead(FMSExcel.Sheets.Spreadsheet(0));
- FBillsID := 1;
- FProjectData.DealBillsData.Clear;
- FProjectData.DealBillsData.DisableEvent;
- LoadDealBillsData(FMSExcel.Sheets.Spreadsheet(0));
- FProjectData.DealBillsData.EnableEvent;
- end;
- procedure TDealBillsExcelImport.LoadColumnsFromHead(ASheet: TSpreadSheet);
- var
- iCol: Integer;
- sColName: string;
- begin
- FB_CodeCol := -1;
- FNameCol := 1;
- FUnitsCol := 2;
- FPriceCol := 3;
- FQuantityCol := 4;
- FTotalPriceCol := 5;
- while ((FB_CodeCol = -1) or (FPriceCol = -1)) and (FCurRow < ASheet.Cells.UsedRowCount) do
- begin
- for iCol := 0 to ASheet.Cells.UsedColCount do
- begin
- sColName := GetCellTrimText(ASheet, iCol, FCurRow);
- if SameText(sColName, '清单编号') or SameText(sColName, '子目号') then
- FB_CodeCol := iCol
- else if SameText(sColName, '名称') then
- FNameCol := iCol
- else if SameText(sColName, '单位') then
- FUnitsCol := iCol
- else if Pos('单价', sColName) = 1 then
- FPriceCol := iCol
- else if SameText(sColName, '数量') then
- FQuantityCol := iCol
- else if SameText(sColName, '金额') then
- FTotalPriceCol := iCol;
- end;
- Inc(FCurRow);
- end;
- end;
- procedure TDealBillsExcelImport.LoadDealBillsData(ASheet: TSpreadSheet);
- function CheckIsBillsCode(ACode: string): Boolean;
- const
- FBillsCodeSet: set of char = ['0'..'9', '-', 'a'..'z', 'A'..'Z'];
- var
- I: Integer;
- begin
- Result := True;
- I := 1;
- while I < Length(ACode) do
- if ACode[I] in FBillsCodeSet then
- Inc(I)
- else
- begin
- Result := False;
- Break;
- end;
- end;
- var
- sB_Code: string;
- Rec: TsdDataRecord;
- begin
- while (FCurRow < ASheet.Cells.UsedRowCount) do
- begin
- sB_Code := GetCellTrimText(ASheet, FB_CodeCol, FCurRow);
- if (sB_Code <> '') and CheckIsBillsCode(sB_Code) then
- begin
- Rec := FProjectData.DealBillsData.sddDealBills.Add;
- Rec.ValueByName('ID').AsInteger := FBillsID;
- Rec.ValueByName('B_Code').AsString := sB_Code;
- Rec.ValueByName('IndexCode').AsString := B_CodeToIndexCode(sB_Code);
- Rec.ValueByName('Name').AsString := GetCellTrimText(ASheet, FNameCol, FCurRow);
- Rec.ValueByName('Units').AsString := GetCellTrimText(ASheet, FUnitsCol, FCurRow);
- Rec.ValueByName('Price').AsFloat := PriceRoundTo(
- StrToFloatDef(GetCellTrimText(ASheet, FPriceCol, FCurRow), 0));
- Rec.ValueByName('Quantity').AsFloat := QuantityRoundTo(
- StrToFloatDef(GetCellTrimText(ASheet, FQuantityCol, FCurRow), 0));
- Rec.ValueByName('TotalPrice').AsFloat := TotalPriceRoundTo(
- StrToFloatDef(GetCellTrimText(ASheet, FTotalPriceCol, FCurRow), 0));
- Inc(FBillsID);
- end;
- Inc(FCurRow);
- end;
- end;
- { TGclBillsExcelImport }
- procedure TGclBillsExcelImport.BeginImport;
- begin
- Screen.Cursor := crHourGlass;
- ShowProgressHint('导入Excel数据', 100);
- FCacheTree := TGclCacheTree.Create;
- FCacheTree.NewNodeID := FProjectData.BillsData.GetMaxBillsID + 1;
- FProjectData.DisConnectTree;
- FProjectData.BillsData.DisableEvents;
- FSelectSheets := TList.Create;
- FB_CodeCol := 0;
- FNameCol := 1;
- FUnitsCol := 2;
- FQuantityCol := 3;
- FPriceCol := 4;
- end;
- procedure TGclBillsExcelImport.EndImport;
- var
- ParentRec: TsdDataRecord;
- begin
- FSelectSheets.Free;
- FCacheTree.Free;
- FProjectData.BillsData.EnableEvents;
- FProjectData.ReConnectTree;
- ParentRec := FProjectData.BillsData.sddBills.FindKey('idxID', ParentID);
- FProjectData.BillsCompileData.sdvBillsCompile.LocateInControl(ParentRec);
- FProjectData.BillsCompileData.CalculateAll;
- CloseProgressHint;
- Screen.Cursor := crDefault;
- end;
- procedure TGclBillsExcelImport.Import;
- var
- i: Integer;
- begin
- {if SelectSheets(FMSExcel, FSelectSheets) then
- begin
- for i := 0 to FSelectSheets.Count - 1 do
- begin
- UpdateProgressHint(Format('导入Excel数据--工作表[%s]', [FMSExcel.SheetNames.Strings[i]]));
- UpdateProgressPosition(0);
- ImportSheet(FSelectSheets.Items[i]);
- end;
- end;}
- ImportSheet(FMSExcel.Sheets.Spreadsheet(0));
- WriteNodes(FProjectData.BillsData.sddBills);
- end;
- procedure TGclBillsExcelImport.ImportSheet(ASheet: TSpreadSheet);
- var
- iPos: Integer;
- begin
- FCurRow := 1;
- while (FCurRow < ASheet.Cells.UsedRowCount) do
- begin
- LoadNode(ASheet);
- Inc(FCurRow);
- iPos := FCurRow * 100 div ASheet.Cells.UsedRowCount;
- UpdateProgressPosition(iPos);
- end;
- end;
- procedure TGclBillsExcelImport.LoadNode(ASheet: TSpreadSheet);
- var
- sB_Code, sName: string;
- Node: TGclCacheNode;
- begin
- with ASheet.Cells do
- begin
- sB_Code := Trim(VarToStrDef(GetValue(FB_CodeCol, FCurRow), ''));
- sName := Trim(VarToStrDef(GetValue(FNameCol, FCurRow), ''));
- Node := FCacheTree.AddNodeByData(sB_Code, sName);
- Node.B_Code := sB_Code;
- Node.Name := sName;
- Node.Units := Trim(VarToStrDef(GetValue(FUnitsCol, FCurRow), ''));
- Node.Price := StrToFloatDef(VarToStrDef(GetValue(FPriceCol, FCurRow), ''), 0);
- Node.Quantity := StrToFloatDef(VarToStrDef(GetValue(FQuantityCol, FCurRow), ''), 0);
- end;
- end;
- procedure TGclBillsExcelImport.WriteNodes(ADataSet: TsdDataSet);
- var
- i, iPos: Integer;
- begin
- UpdateProgressHint('写入读取的Excel数据');
- UpdateProgressPosition(0);
- for i := 0 to FCacheTree.CacheNodes.Count - 1 do
- begin
- WriteNode(ADataSet, TGclCacheNode(FCacheTree.CacheNodes[i]));
- iPos := i*100 div FCacheTree.CacheNodes.Count;
- UpdateProgressPosition(iPos);
- end;
- UpdateProgressPosition(100);
- end;
- procedure TGclBillsExcelImport.WriteNode(ADataSet: TsdDataSet;
- ANode: TGclCacheNode);
- var
- Rec: TBillsRecord;
- begin
- if ANode.B_Code <> '' then
- UpdateProgressHint('写入读取的Excel数据 ' + ANode.B_Code)
- else
- UpdateProgressHint('写入读取的Excel数据 ' + ANode.Name);
- Rec := TBillsRecord(ADataSet.Add);
- Rec.ID.AsInteger := ANode.ID;
- if ANode.ParentID = -1 then
- Rec.ParentID.AsInteger := ParentID
- else
- Rec.ParentID.AsInteger := ANode.ParentID;
- Rec.NextSiblingID.AsInteger := ANode.NextSiblingID;
- 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.Quantity);
- end;
- end.
|