我有一个具有以下结构的 CSV:
ID290;ID11;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300254\T30_1300254_69402_accuse reception courrier.pdf;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300254\T30_1300254_69402_accuse reception courrier.pdf;Item;T30_1300254_69402_accuse reception courrier.pdf
ID293;ID11;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300254\T30_1300254_69417_accuse reception courrier.pdf;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300254\T30_1300254_69417_accuse reception courrier.pdf;Item;T30_1300254_69417_accuse reception courrier.pdf
ID11;ID10;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300254;;RecordGrp;Dossier n° 1300254
ID333;ID294;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_53417_accuse reception courrier.pdf;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_53417_accuse reception courrier.pdf;Item;T30_1300826_53417_accuse reception courrier.pdf
ID336;ID294;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_59180_accuse mise a disposition courrier.pdf;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_59180_accuse mise a disposition courrier.pdf;Item;T30_1300826_59180_accuse mise a disposition courrier.pdf
ID339;ID294;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_59390_accuse reception courrier.pdf;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_59390_accuse reception courrier.pdf;Item;T30_1300826_59390_accuse reception courrier.pdf
ID294;ID10;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826;;RecordGrp;Dossier n° 1300826
ID400;ID340;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300897\T30_1300897_69841_accuse mise a disposition courrier.pdf;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300897\T30_1300897_69841_accuse mise a disposition courrier.pdf;Item;T30_1300897_69841_accuse mise a disposition courrier.pdf
ID403;ID340;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300897\T30_1300897_69858_accuse reception courrier.pdf;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300897\T30_1300897_69858_accuse reception courrier.pdf;Item;T30_1300897_69858_accuse reception courrier.pdf
ID340;ID10;..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300897;;RecordGrp;Dossier n° 1300897
行对应于树结构,其中 Id 和 ParentId 包含父节点和子节点。 我想在 H 列中生成一个标识符,该标识符考虑以下约束:只要行包含“RecordGrp”,我就创建一个模式为“2022-54-”的 id。然后,我逐步创建父节点的行。
这是我使用的宏:
Dim oSheet As Object
Dim oCursor As Object
Dim lastRow As Long
Dim currentId As String
Dim counter As Long
Dim parentMap As Object
Dim row As Long
' Initialiser la feuille active et les variables
oSheet = ThisComponent.CurrentController.ActiveSheet
oCursor = oSheet.createCursor()
oCursor.gotoEndOfUsedArea(True)
lastRow = oCursor.RangeAddress.EndRow
Set parentMap = CreateObject("Scripting.Dictionary")
counter = 1
currentId = "2022-54-"
' Parcourir les lignes
For row = 1 To lastRow
Dim title As String
Dim descriptionLevel As String
Dim parentId As String
Dim id As String
Dim newId As String
title = oSheet.getCellByPosition(5, row).String ' Colonne F : Content.Title
descriptionLevel = oSheet.getCellByPosition(4, row).String ' Colonne E : Content.DescriptionLevel
id = oSheet.getCellByPosition(0, row).String ' Colonne A : Id
parentId = oSheet.getCellByPosition(1, row).String ' Colonne B : ParentId
If descriptionLevel = "RecordGrp" Then
' Nouvel identifiant pour les "RecordGrp"
newId = currentId & counter
parentMap.Add id, newId
oSheet.getCellByPosition(7, row).String = newId ' Colonne H pour l'ID
counter = counter + 1
ElseIf parentMap.exists(parentId) Then
' Utiliser l'identifiant du parent pour les enfants
newId = currentId & counter
oSheet.getCellByPosition(7, row).String = newId ' Colonne H pour l'ID
counter = counter + 1
Else
' Si aucun parent trouvé, signaler une erreur
oSheet.getCellByPosition(7, row).String = "Erreur : Parent introuvable"
End If
Next row
MsgBox "Identifiants générés avec succès dans la colonne H !"
End Sub
子节点的行不生成Id。 我想要以下结果:
ID290,ID11,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300254\T30_1300254_69402_accuse reception courrier.pdf,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300254\T30_1300254_69402_accuse reception courrier.pdf,Item,T30_1300254_69402_accuse reception courrier.pdf,,2022-54-2
ID293,ID11,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300254\T30_1300254_69417_accuse reception courrier.pdf,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300254\T30_1300254_69417_accuse reception courrier.pdf,Item,T30_1300254_69417_accuse reception courrier.pdf,,2022-54-3
ID11,ID10,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300254,,RecordGrp,Dossier n° 1300254,,2022-54-1
ID333,ID294,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_53417_accuse reception courrier.pdf,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_53417_accuse reception courrier.pdf,Item,T30_1300826_53417_accuse reception courrier.pdf,,2022-54-5
ID336,ID294,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_59180_accuse mise a disposition courrier.pdf,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_59180_accuse mise a disposition courrier.pdf,Item,T30_1300826_59180_accuse mise a disposition courrier.pdf,,2022-54-6
ID339,ID294,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_59390_accuse reception courrier.pdf,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826\T30_1300826_59390_accuse reception courrier.pdf,Item,T30_1300826_59390_accuse reception courrier.pdf,,2022-54-7
ID294,ID10,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300826,,RecordGrp,Dossier n° 1300826,,2022-54-4
ID400,ID340,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300897\T30_1300897_69841_accuse mise a disposition courrier.pdf,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300897\T30_1300897_69841_accuse mise a disposition courrier.pdf,Item,T30_1300897_69841_accuse mise a disposition courrier.pdf,,2022-54-9
ID403,ID340,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300897\T30_1300897_69858_accuse reception courrier.pdf,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300897\T30_1300897_69858_accuse reception courrier.pdf,Item,T30_1300897_69858_accuse reception courrier.pdf,,2022-54-10
ID340,ID10,..\Phase2-fusionner_dossiers\Dossiers\TA30\Dossier n° 1300897,,RecordGrp,Dossier n° 1300897,,2022-54-8
既然你问的是树遍历,那么如果没有递归算法就很难做到。一种可能的解决方案如下所示。
第一次遍历所有数据以选择标记为“RecordGrp”的行时,您将检查数据的有效性。如果记录ID小于或等于父记录ID,那么这是一条坏记录,处理这一行很可能会导致程序循环。
在第二遍中,您迭代所有找到的根记录并递归地查找其所有后代,并放置索引。
您可以将未处理的行保留为空索引。或者您可以在另一个循环中编写一条有关此记录缺少父 ID 的警告:
Option Explicit
Dim counter As Long
Dim aData As Variant
Dim lastRow As Long
Dim lastColumn As Long
Const prefixId = "2022-54-"
Sub renumItems
Dim oSheet As Object
Dim oCursor As Object
Dim oRange As Object
Dim oService As Object
Dim aRoots As Variant
Dim i As Long
Dim curID As Long, parID As Long
' Initialiser la feuille active et les variables
oSheet = ThisComponent.CurrentController.ActiveSheet
oCursor = oSheet.createCursor()
oCursor.gotoEndOfUsedArea(True)
lastColumn = oCursor.RangeAddress.EndColumn+2
lastRow = oCursor.RangeAddress.EndRow
oRange = oSheet.getCellRangeByPosition(0, 0, lastColumn, lastRow)
aData = oRange.getDataArray()
aRoots = Array()
Set oService = CreateUnoService("com.sun.star.sheet.FunctionAccess")
counter = -1
' Parcourir les lignes
For i = 1 To lastRow
curID = CLng(oService.callFunction("REGEX", Array(aData(i)(0), "\D","","g")))
parID = CLng(oService.callFunction("REGEX", Array(aData(i)(1), "\D","","g")))
If (curID < parID) Then
aData(i)(lastColumn) = "Erreur : Parent introuvable"
ElseIf aData(i)(4) = "RecordGrp" Then
counter = counter + 1
ReDim Preserve aRoots(counter)
aRoots(counter) = Array(aData(i)(0),i)
EndIf
Next i
' Liste tous les parents
counter = 0
For i = LBound(aRoots) To UBound(aRoots)
counter = counter + 1
aData(aRoots(i)(1))(lastColumn) = prefixId & counter
' Trouver tous les enfants pour cet identifiant
renumChilds(aRoots(i)(0))
Next i
For i = 1 To lastRow
If Trim(aData(i)(lastColumn)) = "" Then
aData(i)(lastColumn) = "Aucun parent trouvé pour cette entrée"
EndIf
Next i
oRange.setDataArray(aData)
MsgBox "Identifiants générés avec succès dans la colonne H !"
End Sub
Sub renumChilds(parentID As String)
Dim i As Long
For i = 1 To lastRow
If Trim(aData(i)(lastColumn)) = "" Then
If aData(i)(1) = parentID Then
counter = counter + 1
aData(i)(lastColumn) = prefixId & counter
renumChilds(aData(i)(0))
EndIf
EndIf
Next i
End Sub
是的,我看到在您提供的数据样本中只有两层嵌套,在这种情况下,可以使用两个嵌套循环而无需递归。