Tagliare, andare a capo, ricomporre stringhe di testo. Da una richiesta di Giorgio Fisanotti e-mail giorgio_fisanotti@katamail.com, nasce questo interessante esercizio, che risulterà interessante per alcuni aspetti che aiuteranno coloro che si cimentano nella manipolazione di stringhe di testo. il problema che
Giorgio presentava è questo "....Si tratta di trasferire del testo da una
textbox al foglio di excel, questa operazione che mi riesce abbastanza
bene ha però un problema e cioè, non mi restituisce il testo a capo corretto
sul foglio. Non sono riuscito a intuire quale istruzione dare, affinchè il
testo venisse ricopiato sulle celle del foglio tenendo conto del ritorno a
capo. Infatti dopo 55 caratteri (da me impostati, potevano essere anche 100
o 150) il testo doveva proseguire sulla cella successiva (cosa che
effettivamente avviene) ma doveva anche tener conto del ritorno a capo
cioè deve intercettare che l'ultima parola
venga copiata intera, o passata alla seconda cella se non ci stà intera
nella prima..."
In pratica le istruzioni leggono gruppi di 55 caratteri (compresi gli spazi vuoti) contenuti nella TextBox, e per ogni gruppo copiano il testo (55 caratteri per volta) in celle del foglio, iniziando dalla cella A1, incrementando sia i successivi 55 caratteri nella textbox, sia la cella successiva, (con l'istruzione i = i + 1 e prendendo poi con Mid la parte di testo che inizierà da 55 * i +1, per 55 caratteri ancora, attraverso il ciclo While..Wend. Premetto che la soluzione al problema non è affrontabile come su Word, che provvede in automatico a mandare a capo una parola se non entra tutta nella riga. Excel non è nato come elaboratore di testi, ma come foglio di calcolo, e le sue possibilità di gestione di stringhe di testo sono legate alle proprietà degli "oggetti" usati come "contenitori" di testo, quindi a celle del foglio di lavoro oppure a TextBox come in questo caso: per entrambi questi oggetti non sono disponibili istruzioni che permettano di gestire un comportamento analogo a ciò che avviene in Word. (ed escludo l'opzione "giustifica" applicabile al testo contenuto in una cella, che non provvede alla eventuale separazione sulla cella successiva, ma eventualmente ad aggiungere una riga nella stessa cella). Inoltre, condizione determinante, la routine così impostata non tiene conto di eventuali indici riga (peraltro non esistenti per celle o TextBox) ma vede come un tutt'uno il testo da trasferire, e lo "legge" a blocchi predefiniti (55 caratteri in questo caso). Anche istruzioni basate sull'evento KeyPress della TextBox, istruzioni che leggendo il 55mo carattere mentre si digita, consentissero di mandare a capo la parola in quel momento digitata, se superasse il 55mo carattere senza sentire che viene digitato uno spazio (quindi sinonimo di una unica parola) non servirebbero a niente proprio per quanto detto al punto precedente. Volendo quindi continuare a lavorare (senza rifare completamente la routine di Giorgio), rimane (secondo me) una unica possibilità: intervenire sulle celle del foglio DOPO che il testo è stato copiato dalla TextBox. E' evidente che l'esercizio a questo punto si presta ad interventi sulle stringhe di testo presenti nelle celle di un foglio, qualunque sia il modo in cui il testo vi compare (quindi anche se scritto direttamente nelle celle, e non copiatoci, purchè si mantengano gli spazi tra parola e parola anche si si va alla cella successiva). E qui nascono i problemi: come poter identificare se la lettera alla fine di una stringa è una lettera facente parte di una parola che prosegue nella cella sottostante (quindi "troncata") , o invece è una lettera che appartiene alla fine di una parola regolarmente completa (quindi "intera"), contenuta nella cella? Non penso che esista la possibilità di controllare la "completezza" di una parola, l'ideale sarebbe di poter disporre di un dizionario completo con il quale comparare se la parte finale di una stringa (rintracciabile leggendo la posizione dello spazio vuoto che precede l'ultima parola) unita alla parte iniziale della stringa della cella successiva (rintracciabile leggendo la posizione del primo spazio vuoto dopo la prima parola) formassero una parola contenuta nel dizionario, ecc. ecc. Cosa questa fattibile, ma credo, impensabile da intraprendere per tutta una serie di appesantimenti del progetto che non sto neppure ad elencare. Tornando alla realtà, dopo vari tentativi per cercare la soluzione al problema, ne è venuto fuori questo ragionamento: una parola la
possiamo considerare "troncata" quando l'ultima posizione di una stringa (x
n. di caratteri, es. 55, quindi la 55.ma posizione) contiene una lettera.
Questo vorrebbe dire che la lettera in quella posizione è una lettera che fa
parte di una parola, che inizia alla fine (non importa da quale posizione)
della stringa e prosegue sotto nella cella successiva, esempio la parola "melograno"
in cui alla 55.ma posizione trovassimo la "o" di
"melo" (e "grano",
per effetto della routine vista sopra, si troverebbe nella cella sotto,
senza spazio iniziale).
ricordo che gli spazi vuoti vengono contati come caratteri e quindi potremo trovarli a fine stringa o inizio in conseguenza della lunghezza delle stringhe passate dalla routine. Bene, ora possiamo impostare un ciclo che scorrendo le celle della colonna A, nell'intervallo occupato, controllino se l'ultimo carattere della stringa (che è lunga 55 caratteri) è diverso da vuoto, (quindi è una lettera) e se il primo carattere della stringa nella cella successiva è vuoto o contiene un carattere. Se verrà riscontrata una parola troncata, taglieremo la parte finale delle stringa che fa parte di una parola troncata e la aggiungeremo all'inizio della cella successiva: in questo modo "uniamo" le due parti della parola troncata. A questo punto però perderemo la lunghezza stringa che non sarà più di 55 caratteri per tutte le celle, come l'istruzione di Giorgio aveva predisposto, ma necessariamente modificata per lo spostamento del testo che sarà avvenuto. Otterremo comunque che ogni stringa conterrà parole intere e non troncate, che è l'obiettivo che soddisfa le richiesta di Giorgio. Intanto vediamo le istruzioni che consentono di "ricomporre" parole troncate. In Excel, per fare un "taglia e incolla" di una parte di una stringa di testo, possiamo utilizzare due Metodi dell'"Oggetto" Characters : Delete e Insert. Ritenendo un pò più complicato utilizzare Insert in questo caso, e visto che comunque dobbiamo "leggere" la parte di testo da copiare, ho sfruttato il Metodo Characters dell'"Oggetto" Range, che ci consente, impostato un punto di inizio all'interno della stringa (Start), e la lunghezza dei caratteri che ci interessano (Length), di "copiare" questi caratteri, mentre sfrutteremo l'"Oggetto" Characters al quale applichiamo il metodo Delete, per cancellare la parte del testo che avremo copiato nella cella sottostante. Predisponiamo in un modulo standard la nostra routine (ma potrà essere lo stesso modulo della UserForm) e la chiameremo alla fine dell'istruzione di Giorgio, dopo Else e prima di Exit Sub oppure potremo chiamare la routine Controller da un altro pulsante, in successione:
Ed ora vediamo un esempio delle due routine, in due fasi: la prima immagine mostra la UserForm dove nella TextBox1 è stato scritto del testo, e nella colonna A, l'effetto della routine di Giorgio, per l'occasione ridotta ad un esempio impostato su 15 caratteri anzichè 55 (tanto è lo stesso, come esempio); si nota chiaramente la presenza di parole "troncate" e fatte proseguire sulla cella sottostante: e questo invece ciò che otteniamo lanciando la routine Sub Controller() Come si nota, le parola "troncate" sono state unite, ma si è persa necessariamente la lunghezza di 15 caratteri per cella; oserei dire che non si può avere la botte piena e la moglie ubriaca. In questo esempio comunque si nota maggiormente la diversa lunghezza nelle stringhe visto che ho impostato un gruppo di soli 15 caratteri; se le stringhe fossero state impostate su 55 caratteri, sarebbero apparse meno diverse in lunghezza. Se vi ho forniti utili suggerimenti, meglio così. Buon Lavoro. prelevato sul sito www.ennius.altervista.org |