Estrarre parole da stringhe di testo e copiarle in celle adiacenti. - pagina vista: volte

Ancora un esercizio per "trafficare" con le parole. Sul sito sono già presenti altri articoli ("Cercare una parola", "Copia per lunghezza testo", "Tagliare stringhe di testo") dove reperire informazioni circa le funzioni (InStr, InStRev, Len, ecc. ecc.) che in genere si dovranno usare quando si lavora su stringhe.

Questa volta una richiesta è alla base dell'articolo: "Come posso realizzare una macro che selezioni solo una parola
all'interno di una stringa in una cella, e la ricopi in una cella vuota? (segue esempio)...In pratica si tratta di selezionare le parole di una stringa che sta in una cella per metterle in tante celle quante sono le parole e reimpaginare tutto in modo corretto
."

Traducendo la richiesta in un esempio, dovremmo trovarci in una situazione simile a questa:

  A B C D
1 sposato, bello, intelligente      
2 divorziato, bello, intelligente      
3 sposato, brutto, stupido      


e si vorrebbe un risultato del genere:

  A B C D
1 sposato, bello, intelligente sposato bello intelligente
2 divorziato, bello, intelligente divorziato bello intelligente
3 sposato, brutto, stupido sposato brutto stupido

cioè, per ogni parola che compone la stringa in una cella della colonna A, vogliamo estrarre le singole parole e copiarle sulla stessa riga, ma ognuna in una colonna diversa.

Bene, la prima cosa che dovremo capire, è come poter identificare ogni singola parola in un insieme di parole; la sintassi ci impone si separare tra loro le parole, sfrutteremo questa abitudine; diversi sono i modi per definire una separazione: uno spazio vuoto, una virgola, un punto e virgola, un trattino (o altro): qualunque sia il "separatore" scelto, dovremo creare una istruzione che legga tutti i "separatori" presenti in una stringa, e memorizzi la loro posizione all'interno della stringa stessa.

Utilizzando il Metodo Characters sarà quindi possibile reperire il testo compreso tra una posizione iniziale e la posizione del "separatore", e copiare questa parte di testo (una parola intera, quindi) in una cella a lato.

Se usiamo un ciclo For Next che scorrendo tutto il contenuto di una cella, e cerchi i vari "separatori" presenti, potremo incrementare il valore della posizione iniziale (si inizia da 1) nella intera stringa, assegnando ad ogni ciclo il nuovo valore della posizione iniziale uguale al valore corrispondente alla posizione del "separatore" precedente trovato, e "prendere quindi la successiva parola che si troverà tra la posizione "separatore" precedente e quello successivo trovato. Non è difficile, se seguiamo le istruzioni e relative spiegazioni risulterà più comprensibile il meccanismo.

Dovremo usare un doppio ciclo: un ciclo esterno che scorra tutte le celle di una determinata colonna, e per questo useremo un ciclo For Each Next, e per ogni cella in quel momento "letta", istruiamo un ciclo interno For Next che inizi da 1 e termini per quanto è lunga la stringa da valutare, "misurata" usando la funzione Len(), ma....

poichè la "ricerca" dei "separatori" (una virgola, come negli esempi sopra) sia funzionale, dovremo assicurarci di avere un "separatore" anche alla fine della stringa, e visto che qualche "distratto" potrebbe dimenticare di inserirla, facciamo controllare se la stringa possiede all'estrema destra una virgola, in caso contrario la aggiungiamo noi. Vorremo che ogni stringa termini così ad esempio : sposato, bello, intelligente,

Vediamo ora le istruzioni:

  • Sub CercaeCopia()
    Dim CL As Object
    For Each CL In Range("A1:A10")
     'impostiamo l'intervallo contenente le stringhe da scomporre
    If CL = "" Then GoTo 10 
    'se la cella in quel momento letta è vuota, passiamo alla successiva (Next)
    Ltesto = Len(CL.Text)  
     'con la variabile Ltesto prendiamo la lunghezza della stringa
    testo = [CL].Text          
     'con la variabile testo prendiamo il contenuto della cella ora letta (la stringa)
    riga = CL.Row         
    'poi con "riga" prendiamo il numero della riga corrispondente alla cella letta
    If Right(testo, 1) <> "," Then CL = testo & "," 
     'se la fine della stringa è diversa da virgola, la aggiungiamo
    Ltesto = Len(CL.Text) 
     'quindi rileggiamo la lunghezza della stringa
    testo = [CL].Text  
    'e rimemorizziamo la stringa comprensiva della virgola aggiunta se mancava
    ini = 1   
    'usiamo il contatore "ini" che rappresenta la posizione di Start del metodo Characters, e lo iniziamo a 1
    c = 2 
     'con la variabile "c" inizializziamo la colonna nella quale copiare la prima parola che verrà letta
    For N = 1 To Ltesto 
     'ora iniziamo il ciclo interno che tramite la funzione InStr cercherà, a partire dalla posizione N '(quindi 1 all'inizio), nella stringa rappresentata dalla variabile "testo", la virgola ",", ed assegnerà alla variabile "a" la 'posizione della virgola
    a = InStr(N, testo, ",")
    N = a  
    'si rende quindi il contatore "N" del ciclo, uguale alla posizione trovata. Quindi si copia nella cella uguale a "riga", colonna uguale alla variabile "c" (la 2 ad inizio ciclo) la parola letta tramite Characters (nella cella CL ora letta) 'e che è rappresentata dai caratteri che si trovano tra la posizione "a" e la posizione "a - ini"
    Cells(riga, c).Value = Trim(CL.Characters(Start:=ini, Length:=a - ini).Text) 
    'ed usiamo Trim per eliminare spazi
    ini = a + 1 
    'incrementiamo quindi la variabile "ini" che ora sarà uguale alla posizione della virgola ("a") + 1
    c = c + 1  
     'incrementiamo ora il numero di colonna predisponendo la cella dove copiare al prossimo ciclo
    If a = 0 Then 
    'quindi impostiamo la condizione di uscire dal ciclo interno quando saranno terminate le virgole
    Exit For
    End If
    Next
    10:
    Next
    End Sub

ed otterremo questo risultato:

Cambiando il simbolo del "separatore" andranno modificate le istruzioni nei punti dove si fa riferimento alla virgola.

 

Buon lavoro.

prelevato sul sito www.ennius.altervista.org