Individuazione livelli gerarchici in file excel

Anonimo
2017-12-13T14:01:08+00:00

Salve a tutti,

nella tabella che segue è riportato un esempio del problema per il quale vi chiedo aiuto.

La colonna "Livello" indica il rapporto gerarchico tra gli elementi specificati nella colonna "Identifier", in una struttura ad albero genealogico: in tale ottica ad esempio "170001", "mario" e "pluto" sono figli di "170000" e tra loro fratelli, ecc.

Io avrei la necessità di implementare una funzione o macro che in automatico popolasse la colonna "Padre", in cui viene riportato l'"Identificatore" del padre in ordine gerarchico di ogni elemento della colonna "Identifier". La mia colonna excel di partenza contiene circa 30000 elementi. 

Potete aiutarmi?

Vi ringrazio anticipatamente.

Stefano 

Livello Identifier Padre
1 170000
2 170001 170000
3 180020 170001
3 193245 170001
4 pippo 193245
4 pippo3 193245
2 mario 170000
3 124579895 mario
4 loi 124579895
2 pluto 170000
Microsoft 365 e Office | Excel | Per la casa | Windows

Domanda bloccata. Questa domanda è stata eseguita dalla community del supporto tecnico Microsoft. È possibile votare se è utile, ma non è possibile aggiungere commenti o risposte o seguire la domanda.

0 commenti Nessun commento

Risposta accettata dall'autore della domanda

Anonimo
2017-12-13T17:16:00+00:00

Ciao Stefano,

ho provato a utilizzare le funzioni che mi hai dato; le ho copiate in 3 moduli e poi avviato. Mi da errore di compilazione su XIT della funzione subtester: dice che la XIT non è definita

Credo che tu abbia copiato il codice prima che l'avevo modificato!

La label XIT avrebbe dovuto essere:

   XIT:

Corregando questa omissione, ho anche approfittato per fare un paio di picccoli migliormenti .

Potresti scaricare il mio file di prova Stefano20171213.xlsm:

https://www.dropbox.com/s/9hhq8x92clxc59d/Stefano20171213.xlsm?dl=0

===

Regards,

Norman

La risposta è stata utile?

2 persone hanno trovato utile questa risposta.
0 commenti Nessun commento

6 risposte aggiuntive

Ordina per: Più utili
  1. Anonimo
    2017-12-13T16:39:44+00:00

    Ciao Norman,

    ho provato a utilizzare le funzioni che mi hai dato; le ho copiate in 3 moduli e poi avviato. Mi da errore di compilazione su XIT della funzione subtester: dice che la XIT non è definita

    La risposta è stata utile?

    0 commenti Nessun commento
  2. Anonimo
    2017-12-13T16:10:04+00:00

    Ciao Stefano,

    l'output che vorrei ottenere è la compilazione automatica della colonna chiamata "padre" così come la vedi nella tabella di esempio che ho inserito io. Come input darò le colonne livello e identifier e come output voglio ottenere la colonna padre. 

    In un modulo standard, prova qualcosa del genere:

    '=========>>

    Option Explicit

    '--------->>

    Public Sub Tester()

        Dim WB As Workbook

        Dim SH As Worksheet

        Dim RngDati As Range, RngLivelli As Range

        Dim arrDati As Variant, arrUniqueLevels As Variant

        Dim arrLivelli() As Variant

        Dim arrOut As Variant

        Dim Res As Variant

        Dim i As Long, j As Long, k As Long

        Dim LRow As Long, UB As Long

        Const sFoglio As String = "Foglio1"        '<<=== Modifica

        Set WB = ThisWorkbook

        Set SH = WB.Sheets(sFoglio)

        With SH

            LRow = LastRow(SH, .Columns("A:A"))

            Set RngLivelli = .Range("A2:A" & LRow)

            Set RngDati = RngLivelli.Resize(, 2)

        End With

        arrDati = RngDati.Value2

        UB = UBound(arrDati)

        arrLivelli = RngLivelli.Value2

        arrUniqueLevels = SortedUniqueList(arrLivelli)

        ReDim Preserve arrLivelli(1 To UB, 1 To 2)

        ReDim arrOut(1 To UB, 1 To 1)

        For i = 1 To UB

            Res = Application.Match(arrDati(i, 1), arrUniqueLevels, 0)

            RngLivelli.Cells(i).Select

            If arrDati(i, 1) = 1 Then

                arrLivelli(i, 2) = arrDati(i, 2)

            Else

                arrLivelli(Res, 2) = arrDati(i, 2)

                arrOut(i, 1) = arrLivelli(Res - 1, 2)

            End If

        Next i

        On Error GoTo XIT

        Application.ScreenUpdating = False

        RngLivelli.Offset(, 2).Value = arrOut

    XIT:

        Application.ScreenUpdating = True

    End Sub

    '--------->>

    Public Function LastRow(SH As Worksheet, _

                            Optional Rng As Range, _

                            Optional minRow As Long = 1, _

                            Optional sPassword As String)

        Dim bProtected As Boolean

        With SH

            If Rng Is Nothing Then

                Set Rng = .Cells

            End If

            bProtected = .ProtectContents = True

            If bProtected Then

                .Unprotect Password:=sPassword

            End If

        End With

        On Error Resume Next

        LastRow = Rng.Find(What:="*", _

                           after:=Rng.Cells(1), _

                           Lookat:=xlPart, _

                           LookIn:=xlFormulas, _

                           SearchOrder:=xlByRows, _

                           SearchDirection:=xlPrevious, _

                           MatchCase:=False).Row

        On Error GoTo 0

        If LastRow < minRow Then

            LastRow = minRow

        End If

        If bProtected Then

            SH.Protect Password:=sPassword, _

                       UserInterfaceOnly:=True

        End If

    End Function

    '--------->>

    Public Function SortedUniqueList(V As Variant)

        Dim oSortedUniqueList As Object

        Dim arrOut() As Variant

        Dim vVal As Variant

        Dim i As Long

        Set oSortedUniqueList = CreateObject("System.Collections.Sortedlist")

        With oSortedUniqueList

            For i = LBound(V) To UBound(V)

                vVal = V(i, 1)

                If Not IsEmpty(vVal) Then

                    If Not .ContainsKey(vVal) Then

                        .Add Key:=vVal, Value:=i

                    End If

                End If

            Next i

            ReDim arrOut(1 To .Count)

            For i = 0 To .Count - 1

                arrOut(i + 1) = .GetKey(i)

            Next i

        End With

        SortedUniqueList = arrOut

    End Function

    '<<=========

    ===

    Regards,

    Norman

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Anonimo
    2017-12-13T14:28:33+00:00

    Ciao Norman,

    grazie per l'aiuto; l'output che vorrei ottenere è la compilazione automatica della colonna chiamata "padre" così come la vedi nella tabella di esempio che ho inserito io. Come input darò le colonne livello e identifier e come output voglio ottenere la colonna padre. 

    Apparentemente sembra una cosa inutile :)

    Grazie,

    Stefano

    La risposta è stata utile?

    0 commenti Nessun commento
  4. Anonimo
    2017-12-13T14:22:15+00:00

    Ciao Stefano,

    nella tabella che segue è riportato un esempio del problema per il quale vi chiedo aiuto.

    La colonna "Livello" indica il rapporto gerarchico tra gli elementi specificati nella colonna "Identifier", in una struttura ad albero genealogico: in tale ottica ad esempio "170001", "mario" e "pluto" sono figli di "170000" e tra loro fratelli, ecc.

    Io avrei la necessità di implementare una funzione o macro che in automatico popolasse la colonna "Padre", in cui viene riportato l'"Identificatore" del padre in ordine gerarchico di ogni elemento della colonna "Identifier". La mia colonna excel di partenza contiene circa 30000 elementi. 

    Potete aiutarmi?

    Livello Identifier Padre
    1 170000
    2 170001 170000
    3 180020 170001
    3 193245 170001
    4 pippo 193245
    4 pippo3 193245
    2 mario 170000
    3 124579895 mario
    4 loi 124579895
    2 pluto 170000

    Potresti gentilmente postare un esempio della colonna output che vorresti ottenere?

    Non credo che un elenco del seguente tipo sarebbe molto utile:

    170000

    170001

    Mario

    Pluto

    170001

    180020

    ...

    ...

    Quindi, credo di aver capito male quello che vorresto ottenere!

    ===

    Regards,

    Norman

    La risposta è stata utile?

    0 commenti Nessun commento