Stringa testo ordinata



  • Stringa testo ordinata
    di maaslie data: 26/08/2014 10:49:34

    Buongiorno a tutti,

    sto realizzando un foglio Excel costituito da 5 colonne ed N righe.
    Vorrei che il foglio lavorasse nel modo seguente:

    nella colonna "ORDINE" deve essere riportato l'ordine dei frutti correlato al numero presente nella relativa cella. Nel caso in cui non sia scritto nessun numero in una cella, il relativo frutto non dove essere riportato nella lista.
    L'ordine dei frutti deve essere uguale all'ordine crescente dei numeri contenuti nelle celle per riga (caso A, caso B, caso C....)

    Esempio:
    CASO------ PERE--MELE--PRUGNE--ORDINE
    Caso A------1------2-------3-----pere-mele-prugne
    Caso B------2------1-------------prugne-pere
    Caso C------1------3-------2-----pere-prugne-mele

    Grazie per la vostra attenzione.



  • di Grograman (utente non iscritto) data: 26/08/2014 11:07:25

    Perchè nel caso 2 devi riportare "pruugne-pere" e non come suggerisce la logica dei dati "mele-pere"?

    Sono solo 3 le colonne?



  • di Luca73 data: 26/08/2014 11:10:04

    Avendo In Colonna A la definizione dei CASI, In Colonna B: Pere, in Colonna C Mele, in Colonna D Prugne e avendo in Riga 1 le Intestazioni di Colonna

    La seguente formula in Cella E2
    =SE(MAX(B2:D2)>=1;INDICE($B$1:$D$1;1;CONFRONTA(1;B2:D2;0));"") & SE(MAX(B2:D2)>=2; " - " & INDICE($B$1:$D$1;1;CONFRONTA(2;B2:D2;0));"")& SE(MAX(B2:D2)>=3; " - " &INDICE($B$1:$D$1;1;CONFRONTA(3;B2:D2;0));"")

    Copiata nelle Celle Sottostanti per quante righe ti servono.
    Ciao
    Luca





  • di Grograman data: 26/08/2014 11:12:16

    Mi ha preceduto Luca! Ora provo anche la sua.
     
    =SE.ERRORE(INDICE($B$1:$D$1;;CONFRONTA(1;$B2:$D2;0));"")&"-"&SE.ERRORE(INDICE($B$1:$D$1;;CONFRONTA(2;$B2:$D2;0));"")&"-"&SE.ERRORE(INDICE($B$1:$D$1;;CONFRONTA(3;$B2:$D2;0));"")



  • di maaslie data: 26/08/2014 11:31:21

    Ciao a tutti e grazie per le risposte.

    Nel mio caso reale non ho solo 3 colonne (pere, mele, prugne) ma ne ho una ventina (o qualcosa più).
    Nel caso della formula di Luca73, devo estendere a mano la formula fino ad arrivare alla colonna finale?
    Il problema, può essere risolto anche impostando una macro vba?

    @Grograman: purtroppo la formattazione del messaggio non mi permetteva di fare una tabella ordinata. Nel Caso 2, il frutto 1 sono le prugne e non le mele come sembrerebbe dal mio messaggio.



  • di scossa data: 26/08/2014 11:36:26

    Grograman, diamo una sfoltita?

    =SE.ERRORE(INDICE($B$1:$D$1;PICCOLO(B2:D2;B2));"")&"-"&SE.ERRORE(INDICE(B$1:D$1;PICCOLO(B2:D2;C2));"")&"-" &SE.ERRORE(INDICE($B$1:$D$1;PICCOLO(B2:D2;D2));"")



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Grograman (utente non iscritto) data: 26/08/2014 11:39:51

    La cosa più semplice allora è un file di esempio con la reale struttura dei dati.

    Oppure ti estendi la formula fino ad arrivare a:
     
    =SE(MAX(B2:U2)>=1;INDICE($B$1:$U$1;1;CONFRONTA(1;B2:D2;0));"")&SE(MAX(B2:D2)>=2;" - "&INDICE($B$1:$D$1;1;CONFRONTA(2;B2:D2;0));"")&SE(MAX(B2:D2)>=3;" - "&INDICE($B$1:$D$1;1;CONFRONTA(3;B2:D2;0));"")&……………..&SE(MAX(B2:D2)>=3;" - "&INDICE($B$1:$D$1;1;CONFRONTA(20;B2:D2;0));"")



  • di scossa data: 26/08/2014 11:40:43

    Ops, vedo che la cosa è più complicata ... serve un file "realistico".


    P.S.: la mia formula ha dei limiti sulla richiesta presenza dei valori, ad esempio non funziona se ci sono solo 2 e 3.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Grograman (utente non iscritto) data: 26/08/2014 11:43:13

    Eh eh la stavo proprio provando un questo momento, ma ti sei accorto ben prima di me che era zoppa in cazo di valori mancanti



  • di maaslie data: 26/08/2014 11:47:28

    sono stato troppo ottimista... ho un centinaio di colonne, non una "ventina" come ho scritto nel mio messaggio.

    La struttura del file è esattamente la stessa, solo anziché avere 3 colonne (3 frutti) ho 100 colonne (100 frutti).
    Nel mio file originale cambiano i nomi dei frutti in codici che identificano delle tratte ed ho circa 100 tratte.

    Per questo ponevo la domanda chiedendo se il problema potesse essere risolto con una macro.

    Grazie mille



  • di scossa data: 26/08/2014 11:49:47

    cit.: "Eh eh la stavo proprio provando un questo momento, ma ti sei accorto ben prima di me che era zoppa in cazo di valori mancti ..."

    Solo un banale errore
    Corrige:
    =SE.ERRORE(INDICE($B$1:$D$1;PICCOLO(B2:D2;3));"")&"-"&SE.ERRORE(INDICE(B$1:D$1;PICCOLO(B2:D2;2));"")&"-" &SE.ERRORE(INDICE($B$1:$D$1;PICCOLO(B2:D2;1));"")

    Ed è pure più corta!





    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di scossa data: 26/08/2014 11:51:27

    P.S.: non è vero! (è sempre zoppa) ma non si possono cancellare i post



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Grograman (utente non iscritto) data: 26/08/2014 11:59:59

    @Scossa: Tanto non se ne accorge nessuno se è zoppa, son sempre bellissime le tue formule

    @maaslie: così non ci siamo, che sia una formula o una macro, cambia tantissimo se sono 3, 5, 20 o 100 colonne.
    Specificare sempre bene i dati del problema da risolvere è già metà del lavoro. Se no facciamo solo un gran giro dell'oca...



  • di maaslie data: 26/08/2014 12:38:49

    Grograman, mi dispiace. Pensavo che enfatizzare il concetto piuttosto che la ripetitività del caso reale fosse meglio per spiegare il mio problema. Mi dispiace avervi fatto lavorare a vuoto, il mio obiettivo era farmi capire meglio.

    Come posso caricare il file originale? Il forum non mi permette di inserire dei link nella risposta..



  • di Luca73 data: 26/08/2014 14:19:41

    Con Le poche info in mio possesso ho provato a buttar giù queste poche righe di codice.
    Con le prove che ho fatto funziona.
    La selezione dell'intervallo di lavoro l'ho fatta tramite Inputbox coì da essere indipendente dalla partenza.
    Ho sfruttatto una matriche che ho riempito utilizzando i numeri inclusi nell'intervallo per posizionare le stringhe nelle celle.
    Sicuramente si puo semplificare togliendo almeno il vettore di appoggio ma così mi sembrava più chiaro.
    La macro è molto spartana.
    Ciao
    Luca
     
    Option Explicit
    
    Sub OrdinaStringhePerMatrice()
    
    Dim MatriceCelle As Range
    Dim NumRighe As Integer, NumColonne As Integer
    Dim MatriceIntestazioni()
    Dim MatriceMain()
    Dim Index, IndexC, IndexR As Integer
    Dim FinStringa As String
    
    On Error GoTo ERRORMSG
    Set MatriceCelle = Application.InputBox(Prompt:="Selezona range di lavoro Inclusivo della Prima Riga Con Intestazioni", Type:=8)
    
    NumRighe = MatriceCelle.Rows.Count
    NumColonne = MatriceCelle.Columns.Count
    
    ' dimensiona un Vettore con le intestazioni delle Colonne Che sono le stringhe da scrivere
    ReDim MatriceIntestazioni(1 To NumColonne)
    
    ' riempio il Vettore sopra dimensionato
    For Index = 1 To NumColonne
        MatriceIntestazioni(Index) = MatriceCelle.Cells(1, Index)
    Next Index
    
    'Dimensiono una matrice pari a tutte le celle con i criteri di ordine
    ReDim MatriceMain(2 To NumRighe, 1 To NumColonne)
    ' riempio la matrice sopra dimensionata mettendo nella posizione indicata dalla cella corrispondente la stringa voluta
    For IndexR = 2 To NumRighe
        For IndexC = 1 To NumColonne
            If MatriceCelle.Cells(IndexR, IndexC) <> "" Then
                MatriceMain(IndexR, MatriceCelle.Cells(IndexR, IndexC).Value) = MatriceIntestazioni(IndexC)
            End If
        Next IndexC
    Next IndexR
    
    'genero la stringa da scrivere alla fine ela scrivo nella cella subito a destra
    
    For IndexR = 2 To NumRighe
    FinStringa = ""
        For IndexC = 1 To NumColonne
            FinStringa = FinStringa & MatriceMain(IndexR, IndexC)
            If Not ((IndexC = NumColonne) Or (MatriceMain(IndexR, IndexC) = "")) Then
                FinStringa = FinStringa & "-"
            End If
        Next IndexC
        If Right(FinStringa, 1) = "-" Then
            FinStringa = Left(FinStringa, Len(FinStringa) - 1)
        End If
        MatriceCelle.Cells(IndexR, NumColonne).Offset(0, 1).Formula = FinStringa
    Next IndexR
    Exit Sub
    ERRORMSG:
    MsgBox Prompt:="Selezione non Valida"
    End Sub
    






  • di Grograman (utente non iscritto) data: 26/08/2014 15:51:08

    Altra versione, cicla le celle da A1 a XXX (ovvero fino a ultima colonna piena di riga 1) e sfruttando un vettore riordinato tramite una funzione non mia a seguire ricostruisce la stringa.

    Diciamo che è più o meno quanto richiesto, indipendentemente da quante colonne si possano avere.
     
    Option Explicit
    
    Sub OrdinaStringhePerMatrice2()
      Dim wb As Workbook
      Dim ws As Worksheet, ws2 As Worksheet
      Dim vIndex() As String
      Dim x As Long, y As Long, i As Long, n As Long
      Dim sNomi As String
      Dim rSort As Range, rFound As Range
      
      Set wb = ThisWorkbook
      Set ws = wb.Sheets(1)
     
      With ws
        x = .Range("A" & .Rows.Count).End(xlUp).Row
        y = .Cells(1, .Columns.Count).End(xlToLeft).Column
        
        For i = 2 To x
          ReDim vIndex(1 To 1)
          For Each rFound In .Range(.Cells(i, 1), .Cells(i, y)).Cells
            If rFound <> "" Then
              ReDim Preserve vIndex(1 To n + 1)
              vIndex(n + 1) = rFound.Value
              n = n + 1
            End If
          Next rFound
          n = 0
          Call BubbleSort(vIndex)
          For n = 1 To UBound(vIndex)
            If vIndex(n) <> "" Then Set rFound = .Range(.Cells(i, 1), .Cells(i, y)).Find(vIndex(n))
            If Not rFound Is Nothing Then
              sNomi = sNomi & .Cells(1, rFound.Column) & "-"
              Set rFound = Nothing
            End If
          Next n
          .Cells(i, y + 1) = sNomi
          sNomi = ""
        Next i
      End With
    
      Set ws2 = Nothing
      Set ws = Nothing
      Set wb = Nothing
    End Sub
    
    Sub BubbleSort(arr)
    'FONTE: h t t p://social.msdn.microsoft.com/Forums/en-US/830b42cf-8c97-4aaf _
    -b34b-d860773281f7/sorting-an-array-in-vba-without-excel-function?forum=isvvba
      Dim strTemp As String
      Dim i As Long
      Dim j As Long
      Dim lngMin As Long
      Dim lngMax As Long
      lngMin = LBound(arr)
      lngMax = UBound(arr)
      For i = lngMin To lngMax - 1
        For j = i + 1 To lngMax
          If arr(i) > arr(j) Then
            strTemp = arr(i)
            arr(i) = arr(j)
            arr(j) = strTemp
          End If
        Next j
      Next i
    End Sub