Excel e gli applicativi Microsoft Office Funzione ricorsiva VBA per strutturazione file Excel

Login Registrati
Stai vedendo 25 articoli - dal 1 a 25 (di 43 totali)
  • Autore
    Articoli
  • #8561 Risposta

    Jotric
    Partecipante

      Buongiorno a tutti. Ho il seguente problema, in diversi files Excel ho la necessità di formattare i dati. In particolare ho una colonna che mi identifica il livello di nidificazione degli stessi. In pratica qualcosa di simile:

      1
       2
        3
        3
        3
       2
        3
        3
         4
         4
       2
        3
      Devo scorrere questa sequenza di numeri (ovviamente a priori non so quanto possa essere profondo il livello di nidificazione).

      Il risultato che devo ottenere è qualcosa di simile:

      A1
       B1
        C1
        C2
        C3
       B2
        D1
        D2
         E1
         E2
       B3
        F1
      Qualche idea su come possa fare?

      #8568 Risposta
      Luca73
      Luca73
      Partecipante
        4 pts

        Ciao

        Spiega la logica con cui vuoi tradurre da numeri a lettere + numero

        Non capisco la lettera D da dove arrivi.

        Cerca di speigare con parole come costruire il tuo elenco nidificato.

        Ciao

        Luca

         

         

        #8570 Risposta

        Jotric
        Partecipante

          Grazie per l'attenzione Luca. In sostanza, diciamo che le lettere e i numeri sono dei progressivi. Il primo livello (1) è sempre identificato con la lettera A e seguito da un numero che identifica il progressivo degli oggetti di livello 1. Passando ai livelli a scendere, avrò sempre una lettera ed un numero, progressivi a parità di livello, ma univoci a livello di albero...Meglio che allego un immagine...

          Alberi origine e destinazione

          Spero adesso sia più chiaro....

          #8571 Risposta

          Jotric
          Partecipante

            Questa è la rappresentazione dell'albero del primo esempio...

            Albero primo esempio

            #8578 Risposta
            Luca73
            Luca73
            Partecipante
              4 pts

              Ciao Vediamo cosa si può fare.

              Rituieni che 

              a) i numeri possano superare il 9?

              b) le lettere possano superare la Z? (nel caso AA, AB, AC...BA, BB,  BC...?)

              c) i livelli arrivano fino a 4 O puoi averne di più?

              Ciao

              Luca

              #8579 Risposta

              Jotric
              Partecipante

                Buongiorno a te 🙂

                a) I numeri che sono legati alla lettera non sono un gran problema. Nella situazione reale sono salvati in un'altra colonna e quindi alla mia lettera ci lego il numero che trovo nell'altra colonna. Ho messo i numeri negli esempi solo per chiarirmi le idee e rendere la cosa più comprensibile.

                b) In linea teorica si, le lettere possono diventare tante, ma anche li diciamo che si potrebbe risolvere con relativamente poco sforzo.

                c) I livelli anche qui, in linea teorica, possono raggiungere profondità considerevoli. Nel file che ho davanti, ci si limita a 4, ma al momento non saprei che dire e nel dubbio dico si.

                #8580 Risposta
                Luca73
                Luca73
                Partecipante
                  4 pts

                  a) I numeri che sono legati alla lettera non sono un gran problema. Nella situazione reale sono salvati in un'altra colonna e quindi alla mia lettera ci lego il numero che trovo nell'altra colonna. Ho messo i numeri negli esempi solo per chiarirmi le idee e rendere la cosa più comprensibile.

                  Cosa intendi?

                  Puoi inviare un file di esempio? Senza dati sensibili?

                  Riguardo alle domande che ti ho fatto, avere i limiti o una idea dei limiti aiuta ad impostare il programma. se devo prevedere due lettere o una, se devo prevdere una formattazione dei numeri di un certo tipo, ....

                  Ciao

                  Luca

                  #8584 Risposta

                  Jotric
                  Partecipante

                    Allora ti ho allegato il file xlsx che contiene i dati e il file .bas da associare al file.

                    Dopo l'importazione del file .bas lancia la macro "ScompattaDistinteNuovoFormato" che altro non fa che scorrere i fogli e preparare i livelli "A".Il dato numerico associato al nodo te lo trovi nella colonna B. Dopodiché,  sempre nello stesso file la macro che si chiama "GestioneSubLivello" dove ho iniziato a far qualcosa...C'è un'istruzione " For I = RangeLimitUp To RangeLimitDw" che scrolla il Range fra due livelli A.

                    Vedi se ti può essere utile.

                    Allegati:
                    You must be logged in to view attached files.
                    #8586 Risposta

                    Jotric
                    Partecipante

                      Ciao Luca...scusa per le info incomplete. Ti allego il file dati che sto usando ed un file di macro che preparano gli stessi. DOpo aver caricato il file .bas, lancia la macro "ScompattaDistinteNuovoFormato" che prepara le colonne. Nella colonna B ti troverai appunto il numero da legare alla lettera.

                      Sempre nello stesso file c'è la macro "GestioneSubLivello" in cui ho iniziato a far qualcosa. Ti troverai un ciclo che itera fra due livello A " For I = RangeLimitUp To RangeLimitDw".

                      Vedi se può esserti utile.

                      Allegati:
                      You must be logged in to view attached files.
                      #8589 Risposta

                      Jotric
                      Partecipante

                        Ho rinominato l'estensione del bas perchè non me lo lasciava caricare...

                        #8591 Risposta
                        Luca73
                        Luca73
                        Partecipante
                          4 pts

                          Ciao ci sto lavorando. Ho quasi finito spero Lunedì di ricordarmi.

                          Ciao

                          Luca

                          #8592 Risposta

                          vecchio frac
                          Moderatore
                            24 pts

                            Questo è un caso interessante e potrebbe diventare anche un articolo per il blog.

                            Magari vi potesse interessare, si accettano proposte da chiunque...

                            Scrivete le bozze degli articoli direttamente a redazione@excelvba.it

                            Non ci sono premi ma la soddisfazione di stuzzicare interesse altrui 🙂

                            #8626 Risposta
                            Luca73
                            Luca73
                            Partecipante
                              4 pts

                              Ciao Ecco una prima proposta.

                              Siccome l'ho fatta e modificata. Secondo me va migliorata e ottimizzata. infatti il vettore che prevedevo dimutilizzare in un modo el'avevo riempito con un criterio, poi l'ho modificato e in parte non serve.

                              Accetta lettere multiple (ovvero dopo Z c'è AA,...dopo AA c'è AB, dopo AZ c'è BA,...dopo ZZ c'è AAA...)

                              ATTENZIONE al momento la macro parte da A2 e prende tutto ciò che c'è sotto e poi SCRIVE NELLA COLONNA A FIANCO.

                               

                              Option Explicit
                              
                              Sub Livelli()
                              Dim Vettore()
                              Dim NumeroLivelli As Integer
                              Dim NumeroCelle As Integer
                              Dim PrimaCella As Range
                              Dim UltimaCella As Range
                              Dim Intervallo As Range
                              Dim CellaW As Range
                              Dim Index As Integer
                              Dim Index2 As Integer
                              Dim LastLetter As String
                              Dim LetterToUse As String
                              Dim MaxN As Integer
                              Dim NumZeri As String
                              
                              Set PrimaCella = Range("A2")
                              Set UltimaCella = PrimaCella.End(xlDown)
                              Set Intervallo = Range(PrimaCella, UltimaCella)
                              
                              MaxN = 1
                              LastLetter = "A"
                              
                              NumeroCelle = Intervallo.Count
                              NumeroLivelli = 0
                              For Each CellaW In Intervallo
                                  If CellaW > NumeroLivelli Then
                                      NumeroLivelli = CellaW
                                  End If
                              Next CellaW
                              ReDim Vettore(0 To NumeroLivelli, 0 To NumeroCelle, 1 To 2)
                              For Index = 1 To NumeroCelle
                                  If PrimaCella.Offset(Index - 1, 0) * 1 = 1 Then
                                      Vettore(1, 0, 1) = Vettore(1, 0, 1) + 1
                                      Vettore(1, Index, 1) = Vettore(1, 0, 1)
                                      Vettore(0, Index, 1) = "A"
                                      Vettore(0, Index, 2) = Vettore(1, 0, 1)
                                      'PrintVect (Vettore)
                                      If Vettore(1, 0, 1) > MaxN Then
                                          MaxN = Vettore(1, 0, 1)
                                      End If
                                  Else
                                      If PrimaCella.Offset(Index - 1, 0) * 1 > PrimaCella.Offset(Index - 2, 0) * 1 Then
                                          Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1) = 1
                                          Vettore(PrimaCella.Offset(Index - 1, 0), Index, 1) = 1
                                          LastLetter = LetterPlus1(LastLetter)
                                          Vettore(0, Index, 1) = LastLetter
                                          Vettore(PrimaCella.Offset(Index - 1, 0), 0, 2) = LastLetter
                                          Vettore(0, Index, 2) = 1
                                          'PrintVect (Vettore)
                                      ElseIf PrimaCella.Offset(Index - 1, 0) * 1 < PrimaCella.Offset(Index - 2, 0) * 1 Then
                                          For Index2 = (PrimaCella.Offset(Index - 1, 0) + 1) To NumeroLivelli
                                              Vettore(Index2, 0, 1) = 0
                                          Next Index2
                                          Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1) = Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1) + 1
                                          Vettore(PrimaCella.Offset(Index - 1, 0), Index, 1) = Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1)
                                          Vettore(0, Index, 2) = Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1)
                                          If Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1) = 0 Then
                                              LastLetter = LetterPlus1(LastLetter)
                                              LetterToUse = LastLetter
                                          Else
                                              LetterToUse = Vettore(PrimaCella.Offset(Index - 1, 0), 0, 2)
                                          End If
                                          
                                          Vettore(0, Index, 1) = LetterToUse
                                          Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1) = Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1) + 1
                                          If Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1) > MaxN Then
                                              MaxN = Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1)
                                          End If
                                          
                                          'PrintVect (Vettore)
                                      Else
                                          Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1) = Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1) + 1
                                          Vettore(PrimaCella.Offset(Index - 1, 0), Index, 1) = Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1)
                                          'PrintVect (Vettore)
                                          Vettore(0, Index, 1) = LastLetter
                                          Vettore(0, Index, 2) = Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1)
                                          
                                          If Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1) > MaxN Then
                                              MaxN = Vettore(PrimaCella.Offset(Index - 1, 0), 0, 1)
                                          End If
                                          
                                      End If
                                  End If
                              Next Index
                              'PrintVect (Vettore)
                              NumZeri = ""
                              For Index = 1 To Len(MaxN)
                                  NumZeri = NumZeri & "0"
                              Next Index
                              For Index = 1 To NumeroCelle
                                  PrimaCella.Offset(Index - 1, 1) = Vettore(0, Index, 1) & Format(Vettore(0, Index, 2), NumZeri)
                              Next Index
                              End Sub
                              
                              
                              Function LetterPlus1(LetteraIniziale)
                              Dim PosLet As Integer
                              Dim VettoreLet
                              ReDim VettoreLet(1 To Len(LetteraIniziale))
                              For PosLet = 1 To Len(LetteraIniziale)
                                  VettoreLet(PosLet) = Mid(LetteraIniziale, Len(LetteraIniziale) - PosLet + 1, 1)
                              Next
                              
                              PosLet = 1
                              Do
                                  If VettoreLet(PosLet) < "Z" Then
                                      VettoreLet(PosLet) = Chr(Asc(VettoreLet(PosLet)) + 1)
                                      Exit Do
                                  Else
                                      VettoreLet(PosLet) = "A"
                                      PosLet = PosLet + 1
                                  End If
                                  If PosLet > UBound(VettoreLet, 1) Then
                                      ReDim Preserve VettoreLet(1 To PosLet)
                                      VettoreLet(PosLet) = Chr(Asc("A") - 1)
                                  End If
                              Loop
                              LetterPlus1 = ""
                              For PosLet = UBound(VettoreLet, 1) To 1 Step -1
                                  LetterPlus1 = LetterPlus1 & VettoreLet(PosLet)
                              Next
                              
                              End Function

                               

                               

                               

                              #8651 Risposta

                              vecchio frac
                              Moderatore
                                24 pts

                                @Luca,

                                ho fatto girare per prova sul file Esempio-1.xlsx. Si ferma, come giusto, sul primo ciclo For, perchè "CellaW" (che punta al range in colonna A)  non contiene un numero ma un testo e non lo puoi confrontare con un numero ("NumeroLivelli"). Probabilmente, presumo, il range "Intervallo" deve puntare alla colonna B ("Level").

                                Tu su che versione del file hai lavorato?

                                #8652 Risposta

                                Jotric
                                Partecipante

                                  Buongiorno Luca. Intanto grazie per la risposta. Adesso la sto cercando di analizzare. In realtà la prima difficoltà che incontro è capire su che intervallo stai lavorando. Nel mio esempio, la colonna "A" contiene dati non preparati (ad esempio: 101 - 0.003988.E), le colonne "B" e "C"  contengono il dato scomposto. Nella colonna "D" i dati del primo livello. La colonna "E" è quella destinata a contenere il dato del livello elaborato. Nel tuo ciclo:

                                  For Each CellaW In Intervallo
                                      If CellaW > NumeroLivelli Then
                                          NumeroLivelli = CellaW
                                      End If
                                  Next CellaW

                                  in realtà non capisco su che dati tu vada ad operare...

                                   

                                  #8653 Risposta

                                  Jotric
                                  Partecipante

                                    Lavoro sulla stessa versione del file. Ma hai caricato il file .bas e lanciato la macro "ScompattaDistinteNuovoFormato"?

                                    #8654 Risposta

                                    vecchio frac
                                    Moderatore
                                      24 pts

                                      Comunque il codice non è male anche se sembra incasinato 🙂 ho fatto qualche aggiustatina perchè si arrabbiava ancora confrontando numeri con testo, e ho poi printato nell'ultima colonna anziché nella terza, ma alla fine mi sembra un risultato coerente con la richiesta iniziale. L'unica piccola pecca è che il livello zero viene indicato con "A01" (sicché alla fine ho due livelli "A01") ma penso che si possa sistemare facilmente.

                                      #8655 Risposta

                                      vecchio frac
                                      Moderatore
                                        24 pts

                                        Jotric ha scritto:

                                        Ma hai caricato il file .bas e lanciato la macro "ScompattaDistinteNuovoFormato"?

                                        No, ho lanciato "LIvelli" 😀

                                        Adesso mi guardo il codice che hai indicato.

                                        #8656 Risposta

                                        vecchio frac
                                        Moderatore
                                          24 pts

                                          Jotric ha scritto:

                                          in realtà non capisco su che dati tu vada ad operare...

                                          Nel codice originale della sub Livello, "Intervallo" punta alla colonna A. Ma ho sbagliato io e adesso vado a vedere il codice cui ti riferivi poco fa (è quello su cui Luca ha messo mano?).

                                          #8657 Risposta
                                          Luca73
                                          Luca73
                                          Partecipante
                                            4 pts

                                            Ciao

                                            Non ho lavorato sul tuo file ma su uno che mi ero creato io.

                                            Basta cambiare la riga 

                                            Set PrimaCella = Range("A2")

                                            Il mio file parte da A2 e prende tutto ciò che c'è sotto fino alla prima libera

                                            Set UltimaCella = PrimaCella.End(xlDown)
                                            #8658 Risposta

                                            vecchio frac
                                            Moderatore
                                              24 pts

                                              Jotric ha scritto:

                                              Lavoro sulla stessa versione del file. Ma hai caricato il file .bas e lanciato la macro "ScompattaDistinteNuovoFormato"?

                                              @jotric

                                              Quello è il tuo codice originale, che Luca ha probabilmente riscritto per venire incontro alla tua richiesta. Quindi non lo guardo neanche visto che lo ha già fatto l'amico Luca 🙂

                                              #8659 Risposta

                                              vecchio frac
                                              Moderatore
                                                24 pts

                                                @Luca

                                                Ho avuto difficoltà come dicevo sui test che i due Ifs fanno per controllare i valori di PrimaCella. Nel tuo codice viene confrontato un valore numerico con un valore testuale. Ho dovuto correggere così:

                                                If Val(PrimaCella.Offset(Index - 1, 0)) * 1 > Val(PrimaCella.Offset(Index - 2, 0)) * 1 Then

                                                forzando con Val() la traduzione numerica del contenuto indicizzato di PrimaCella. Poi tutto fila liscio con la particolarità del livello zero come ho già accennato. In realtà poi io metterei il risultato in ultima colonna, senza sovrascrivere la descrizione.

                                                For Index = 1 To NumeroCelle
                                                    PrimaCella.Offset(Index - 1, 11) = Vettore(0, Index, 1) & Format(Vettore(0, Index, 2), NumZeri)
                                                Next Index

                                                Comunque complimenti non era facile   

                                                #8662 Risposta

                                                Jotric
                                                Partecipante

                                                  Ho risistemato le mie macro per impostare i dati in modo da far girare la macro. Impostando la colonna "B" col livello e lasciando libera la colonna "C", i livelli sono aggiunti correttamente, almeno per quanto riguarda la lettera. Adesso Devo sistemare i numeri che in realtà non sono progressivi ma sono i primi caratteri (quelli preceduti dal "-" ) nella colonna "A". Inoltre ci sono delle lettere che non sono ammesse (ad esempio la "I" e lo "O" come valori iniziali). Avevo pensato un approccio decisamente diverso, lavorando sul range del singolo gruppo, tu @luca hai lavorato sul range interno invece....Complimenti @vecchio frac che dici "sembra incasinato"....mi ci vorranno diversi giorni per capire il meccanismo di "vettore"  

                                                  #8667 Risposta

                                                  vecchio frac
                                                  Moderatore
                                                    24 pts

                                                    Bè dai, è un vettore a tre dimensioni che raccoglie per ogni cella (seconda dimensione) il proprio numero di livello (prima dimensione) e il numero progressivo per livello (terza dimensione). Nel primo elemento della prima dimensione (indice zero) il vettore si ricorda dell'elemento radice per ogni nuova lettera (ogni nuova foglia dell'albero). Complesso ma non complicato e anche ingegnoso.

                                                    Ma il risultato che ha raggiunto Luca ti soddisfa o no? perchè dici:

                                                    Jotric ha scritto:

                                                    Adesso Devo sistemare i numeri che in realtà non sono progressivi ma sono i primi caratteri (quelli preceduti dal "-" ) nella colonna "A".

                                                    #8673 Risposta

                                                    Jotric
                                                    Partecipante

                                                      In realtà, funziona in parte. Aumentando il livello di complessità dell'albero, ci sono degli errori nel risultato. Ora riuscire a capire dove e perché si verificano con una matrice a tre dimensioni non è semplicissimo. Vediamo se con un esempio riesco a spiegarmi:

                                                      Supponiamo questo albero, il risultato che si ottiene ha un errore...

                                                      Il livello è sempre il 3, quindi dovrebbe essere una C

                                                       

                                                    Login Registrati
                                                    Stai vedendo 25 articoli - dal 1 a 25 (di 43 totali)
                                                    Rispondi a: Funzione ricorsiva VBA per strutturazione file Excel
                                                    Gli allegati sono permessi solo ad utenti REGISTRATI
                                                    Le tue informazioni:



                                                    vecchio frac - 829 risposte

                                                    albatros54
                                                    albatros54 - 516 risposte

                                                    Marius44
                                                    Marius44 - 282 risposte

                                                    patel
                                                    patel - 264 risposte

                                                    Luca73
                                                    Luca73 - 235 risposte