ソースを参照

调整导入分项清单Excel:
1. 识别部分固定项
2. 调整无编号项目节导入策略
3. 调整工程量清单导入策略

MaiXinRong 6 年 前
コミット
e2e403e229
2 ファイル変更139 行追加7 行削除
  1. 5 3
      Units/ExcelImport_Bills.pas
  2. 134 4
      Units/MCacheTree.pas

+ 5 - 3
Units/ExcelImport_Bills.pas

@@ -301,7 +301,8 @@ begin
   if FWithLevelCode then
   begin
     if sLevelCode = '' then Exit;
-  end
+  end;
+  (*
   else
   begin
     if ((sCode = '') and (sB_Code = '')) or SameText(sCode, '2') or
@@ -311,14 +312,15 @@ begin
       Exit;
     end;
   end;
+  *)
 
   if (sCode = '') and FWithoutGclBills then Exit;
 
   // 含层次编号时,以层次编号为依据新增节点;反之以项目节编号为依据新增节点
   if not FWithLevelCode then
   begin
-    if (sCode <> '') then
-      Node := FCacheTree.AddNodeByCode(sCode, -1)
+    if (sB_Code = '') then
+      Node := FCacheTree.AddNodeByCodeName(sCode, sName)
     else
       Node := FCacheTree.AddLeafBillsNode(sB_Code);
   end

+ 134 - 4
Units/MCacheTree.pas

@@ -44,6 +44,7 @@ type
   TBillsCacheTree = class(TCacheTree)
   private
     FLastNode: TCacheNode;
+    FLastBlankNode: TCacheNode;
     FSeparateChar: Char;
     FAutoSort: Boolean;
 
@@ -52,6 +53,8 @@ type
 
     function FindNode(const ACode: string): TBillsCacheNode; overload;
     function FindNode(AParent: TBillsCacheNode; const ACode: string): TBillsCacheNode; overload;
+    function FindFxNode(const ACode, AName: string): TBillsCacheNode; overload;
+    function FindFxNode(AParent: TBillsCacheNode; const ACode, AName: string): TBillsCacheNode; overload;
     function FindParent(const ACode: string): TBillsCacheNode;
     function FindNextSibling(const ACode: string): TBillsCacheNode;
 
@@ -62,6 +65,7 @@ type
 
     function AddNode(AParent: TCacheNode; ANextSibling: TCacheNode = nil; AFixedID: Integer = -1): TBillsCacheNode;
     function AddNodeByCode(const ACode: string; AFixedID: Integer = -1): TBillsCacheNode;
+    function AddNodeByCodeName(const ACode, AName: string): TBillsCacheNode;
     function AddLeafBillsNode(const AB_Code: string): TBillsCacheNode;
 
     function FindXmjChild(AParent: TBillsCacheNode; const ACode, AName: string): TBillsCacheNode;
@@ -334,8 +338,11 @@ var
   Parent, NextSibling: TBillsCacheNode;
 begin
   Result := FindNode(ACode);
-  FLastNode := Result;
-  if Assigned(Result) then Exit;
+  if Assigned(Result) then
+  begin                     
+    FLastNode := Result;
+    Exit;
+  end;
 
   Parent := FindParent(ACode);
   if AutoSort then
@@ -436,15 +443,72 @@ function TBillsCacheTree.AddLeafBillsNode(const AB_Code: string): TBillsCacheNod
   function GetLastXmjParent: TBillsCacheNode;
   begin
     Result := TBillsCacheNode(FLastNode);
-    while Assigned(Result) and (Result.B_Code <> '') do
+    while Assigned(Result) and Assigned(Result.Parent) and (Result.B_Code <> '') do
       Result := TBillsCacheNode(Result.Parent);
   end;
 
+  function FindParent(AParent: TBillsCacheNode;
+    const ACode: string): TBillsCacheNode;
+  var
+    i: Integer;
+    sCode: string;
+  begin
+    Result := AParent;
+    sCode := GetPrefixOfCode(ACode, SeparateChar);
+    while (sCode <> '') do
+    begin
+      for i:= 0 to AParent.Children.Count - 1 do
+      begin
+        if TBillsCacheNode(AParent.Children.Items[i]).B_Code = ACode then
+        begin
+          Result := TBillsCacheNode(AParent.Children.Items[i]);
+          Break;
+        end;
+      end;
+      sCode := GetPrefixOfCode(sCode, SeparateChar);
+    end;
+  end;
+
+  function FindNextSibling(AParent: TBillsCacheNode;
+    const ACode: string): TBillsCacheNode;
+  var
+    Node: TBillsCacheNode;
+    sCodeID, sCodeID2: string;
+  begin
+    Node := TBillsCacheNode(AParent.FirstChild);
+    Result := nil;
+    sCodeID := ConvertDigitCode(ACode, 3, '-');
+    while Assigned(Node) do
+    begin
+      sCodeID2 := ConvertDigitCode(Node.LevelCode, 3, SeparateChar);
+      if sCodeID < sCodeID2 then
+      begin
+        Result := Node;
+        Break;
+      end;
+      Node := TBillsCacheNode(Node.NextSibling);
+    end;
+  end;
+
+  function AddNodeByParent(AParent: TBillsCacheNode;
+    const ACode: string): TBillsCacheNode;
+  var
+    Parent, NextSibling: TBillsCacheNode;
+  begin
+    Parent := FindParent(AParent, ACode);
+    if AutoSort then
+      NextSibling := FindNextSibling(AParent, ACode)
+    else
+      NextSibling := nil;
+    Result := AddNode(Parent, NextSibling);
+    Result.FLevelCode := ACode;
+  end;
+
 var
   Parent: TBillsCacheNode;
 begin
   Parent := GetLastXmjParent;
-  Result := AddNodeByCode(Parent.Code + '-' + AB_Code, -1);
+  Result := AddNodeByParent(Parent, AB_Code);
 end;
 
 procedure TBillsCacheTree.SetSeparateChar(const Value: Char);
@@ -552,6 +616,72 @@ begin
   end;
 end;
 
+function TBillsCacheTree.AddNodeByCodeName(const ACode, AName: string): TBillsCacheNode;
+var
+  Parent, NextSibling: TBillsCacheNode;
+begin
+  Result := FindFxNode(ACode, AName);
+  if Assigned(Result) then
+  begin
+    FLastNode := Result;
+    if (ACode = '') then FLastBlankNode := Result;
+    Exit;
+  end;
+
+  NextSibling := nil;
+  if Pos('-', ACode) > 0 then
+  begin
+    Parent := FindParent(ACode);
+    if AutoSort then
+      NextSibling := FindNextSibling(ACode);
+  end
+  else if (AName = '其他费用项目') or (AName = '建设期贷款利息') or (Pos('公路功能以外的工程费用', AName) >= 0) then
+    Parent := TBillsCacheNode(Root)
+  else
+    Parent := TBillsCacheNode(FLastBlankNode);
+  Result := AddNode(Parent, NextSibling);
+  Result.FLevelCode := ACode;
+  FLastNode := Result;
+  if (ACode = '') then FLastBlankNode := Result;
+end;
+
+function TBillsCacheTree.FindFxNode(const ACode,
+  AName: string): TBillsCacheNode;
+var
+  i: Integer;
+begin
+  if (ACode = '') then
+  begin
+    for i := 0 to CacheNodes.Count - 1 do
+    begin
+      Result := TBillsCacheNode(CacheNodes.Items[i]);
+      if (Result.Code = ACode) And (Result.Name = AName) then
+        Exit;
+    end;
+    Result := nil;
+  end
+  else
+    Result := FindFxNode(TBillsCacheNode(Root), ACode, AName);
+end;
+
+function TBillsCacheTree.FindFxNode(AParent: TBillsCacheNode; const ACode,
+  AName: string): TBillsCacheNode;
+begin
+  Result := TBillsCacheNode(AParent.FirstChild);
+  while Assigned(Result) do
+  begin
+    if (Result.Code = ACode) And (Result.Name = AName) then
+      Break
+    else if Pos(Result.LevelCode + SeparateChar, ACode) = 1 then
+    begin
+      Result := FindNode(Result, ACode);
+      Break;
+    end
+    else
+      Result := TBillsCacheNode(Result.NextSibling);
+  end;
+end;
+
 { TReportCacheNode }
 
 constructor TReportCacheNode.Create(ACacheTree: TCacheTree; AID,