unit DbTreeImport; interface uses ProjectData, MCacheTree, DbTreeDm, Classes, sdIDTree; const FirstPartID = 1; type TDbTreeImport = class private FProjectData: TProjectData; FCacheTree: TBillsCacheTree; FFirstPart: TBillsCacheNode; FDefautNext: TBillsCacheNode; procedure BeginImport; procedure EndImport; procedure PrepareBaseTree; procedure LoadBaseTree; function AddDbNode(ADbNode: TsdIDTreeNode; AParent, ANextSibling: TBillsCacheNode): TBillsCacheNode; procedure LoadDbTree(const AFileName, ATable: string); procedure WriteDbTree; function DecryptFile(const AFileName: string): string; public constructor Create(AProjectData: TProjectData); destructor Destroy; override; procedure ImportDbTree(const AFileName, ATable: string); end; procedure ImportDbTreeTo(const AFileName: string; AProjectData: TProjectData); implementation uses UtilMethods, TransFile, mDataRecord, BillsDm, CacheTree, BillsTree, ExcelImport, sdDB, SysUtils; procedure ImportDbTreeTo(const AFileName: string; AProjectData: TProjectData); var vImport: TDbTreeImport; begin vImport := TDbTreeImport.Create(AProjectData); try vImport.ImportDbTree(AFileName, 'Bills'); finally vImport.Free; end; end; { TDbTreeImport } function TDbTreeImport.AddDbNode(ADbNode: TsdIDTreeNode; AParent, ANextSibling: TBillsCacheNode): TBillsCacheNode; var iChild: Integer; vChild: TsdIDTreeNode; begin if Assigned(ADbNode) and Assigned(AParent) then begin Result := FCacheTree.AddNode(AParent, ANextSibling); Result.Code := ADbNode.Rec.ValueByName('Code').AsString; Result.B_Code := ADbNode.Rec.ValueByName('B_Code').AsString; Result.Name := ADbNode.Rec.ValueByName('Name').AsString; Result.Units := ADbNode.Rec.ValueByName('Units').AsString; Result.Price := ADbNode.Rec.ValueByName('UnitPrice').AsFloat; Result.OrgQuantity := ADbNode.Rec.ValueByName('Quantity').AsFloat; Result.DgnQuantity1 := ADbNode.Rec.ValueByName('DesignQuantity').AsFloat; Result.DgnQuantity2 := ADbNode.Rec.ValueByName('DesignQuantity2').AsFloat; Result.DrawingCode := ADbNode.Rec.ValueByName('DrawingCode').AsString; for iChild := 0 to ADbNode.ChildCount - 1 do AddDbNode(ADbNode.ChildNodes[iChild], Result, nil); end; end; procedure TDbTreeImport.BeginImport; begin FCacheTree := TBillsCacheTree.Create; FProjectData.DisConnectTree; FProjectData.BillsData.DisableEvents; end; constructor TDbTreeImport.Create(AProjectData: TProjectData); begin FProjectData := AProjectData; end; function TDbTreeImport.DecryptFile(const AFileName: string): string; begin Result := GetTempFileName; AutoDecryptFile(AFileName, Result); end; destructor TDbTreeImport.Destroy; begin inherited; end; procedure TDbTreeImport.EndImport; begin FCacheTree.Free; FProjectData.BillsData.EnableEvents; FProjectData.ReConnectTree; FProjectData.BillsCompileData.CalculateAll; end; procedure TDbTreeImport.ImportDbTree(const AFileName, ATable: string); var sDecryptFile: string; begin sDecryptFile := DecryptFile(AFileName); if not FileExists(sDecryptFile) then begin ErrorMessage('无法打开文件。'); Exit; end; BeginImport; try LoadBaseTree; PrepareBaseTree; LoadDbTree(sDecryptFile, ATable); WriteDbTree; finally EndImport; end; end; procedure TDbTreeImport.LoadBaseTree; var BaseImportor: TBillsExcelImport; begin BaseImportor := TBillsExcelImport.Create(nil); try BaseImportor.ImportToTree(FCacheTree, GetTemplateBillsFileName); finally BaseImportor.Free; end; end; procedure TDbTreeImport.LoadDbTree(const AFileName, ATable: string); var vDbTreeData: TDbTreeData; vFirstPart, vChild: TsdIDTreeNode; iChild: Integer; begin try vDbTreeData := TDbTreeData.Create(AFileName, ATable); vFirstPart := vDbTreeData.DbTree.FirstNode; for iChild := 0 to vFirstPart.ChildCount - 1 do begin vChild := vFirstPart.ChildNodes[iChild]; if vChild.Rec.ValueByName('Code').AsString = '1-10' then Break; AddDbNode(vChild, FFirstPart, FDefautNext); end; finally vDbTreeData.Free; end; end; procedure TDbTreeImport.PrepareBaseTree; var vClears: TList; vChild: TBillsCacheNode; i: Integer; begin vClears := TList.Create; try FFirstPart := TBillsCacheNode(FCacheTree.FirstNode); vChild := TBillsCacheNode(FFirstPart.FirstChild); while Assigned(vChild) do begin if vChild.Code = '1-10' then begin FDefautNext := vChild; Break; end else vClears.Add(vChild); vChild := TBillsCacheNode(vChild.NextSibling); end; for i := 0 to vClears.Count - 1 do FCacheTree.DeleteNode(TBillsCacheNode(vClears.Items[i])); finally vClears.Free; end; end; procedure TDbTreeImport.WriteDbTree; var iNode: Integer; Rec: TBillsRecord; vNode: TBillsCacheNode; begin FProjectData.BillsData.sddBills.BeginUpdate; try FProjectData.BillsData.sddBills.DeleteAll; for iNode := 0 to FCacheTree.CacheNodes.Count - 1 do begin vNode := TBillsCacheNode(FCacheTree.CacheNodes.Items[iNode]); Rec := TBillsRecord(FProjectData.BillsData.sddBills.Add); Rec.ID.AsInteger := vNode.ID; Rec.ParentID.AsInteger := vNode.ParentID; Rec.NextSiblingID.AsInteger := vNode.NextSiblingID; Rec.Code.AsString := vNode.Code; Rec.B_Code.AsString := vNode.B_Code; Rec.Name.AsString := vNode.Name; Rec.Units.AsString := vNode.Units; Rec.Price.AsFloat := vNode.Price; Rec.OrgQuantity.AsFloat := vNode.OrgQuantity; Rec.DgnQuantity1.AsFloat := vNode.DgnQuantity1; Rec.DgnQuantity2.AsFloat := vNode.DgnQuantity2; Rec.DrawingCode.AsString := vNode.DrawingCode; end; finally FProjectData.BillsData.sddBills.EndUpdate; end; end; end.