在 LibreOffice 中使用宏生成 Id

问题描述 投票:0回答:1

我有一个具有以下结构的 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
tree macros libreoffice
1个回答
0
投票

既然你问的是树遍历,那么如果没有递归算法就很难做到。一种可能的解决方案如下所示。

第一次遍历所有数据以选择标记为“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

是的,我看到在您提供的数据样本中只有两层嵌套,在这种情况下,可以使用两个嵌套循环而无需递归。

© www.soinside.com 2019 - 2024. All rights reserved.