All’epoca dei primi pc, qualche milione di anni fa…
Ehm, qualche decina di anni fa, all’alba dell’èra informatica di massa, quando ancora il WYSIWYG era un sogno (cioè poter vedere su schermo gli effetti di testo), chi utilizzava i primi Word processor poteva delimitare la formattazione del testo con caratteri speciali per ottenere in fase di stampa l’effetto voluto. Il testo grassetto per esempio si otteneva circondando il testo con asterischi (*esempio*), il sottolineato con il carattere di underscore (_esempio_) e l’italico o corsivo con lo slash (/esempio/).
Una pratica intramontabile, tanto che ai giorni nostri WhatsApp ha ampliato le proprie potenzialità fornendo agli utenti le medesime features.
Vi illustro oggi una simpatica routine, che accetta in input un testo e vi cerca una coppia di delimitatori (per default, il carattere cancelletto “#”), quindi colora il testo racchiuso tra essi in rosso e sistema il risultato in una cella di destinazione.
L’idea è nata, tra parentesi, durante una discussione qui su ExcelVBA, se il paziente lettore di quella discussione si ritrova forse può trarne ulteriori spunti 🙂

Ecco il codice (in un Modulo):

Option Explicit

Sub colorize_text(sText As String, rCell As Range, Optional delimiter As String = "#")
'usage: colorize_text range("A1", range("A3"), "!"
'colorize delimited text and set desired cell with result
'ignore consecutive delimiters and translate its as one only (text ## text --> text # text)

Dim s As String
Dim re As Object, match As Variant, matches As Variant
Dim m As String
Dim i As Integer, k As Integer
Dim p1() As Integer, p2() As Integer
    
    sText = Replace(sText, String(2, delimiter), Chr(255))
    Set re = CreateObject("VBScript.RegExp")
    re.Pattern = "[" & delimiter & "](.*?)[" & delimiter & "]"
    re.IgnoreCase = True
    re.Global = True
    
    s = sText
    Set matches = re.Execute(s)
    
    m = ""
    For Each match In matches
        i = InStr(s, match)
        k = k + 1
        ReDim Preserve p1(k), p2(k)
        p1(k) = i
        p2(k) = Len(match)
    Next
    
    sText = Replace(sText, Chr(255), delimiter)
    rCell = sText
    For i = 1 To k
        rCell.Characters(p1(i), p2(i)).Font.Color = vbRed
    Next
    
    For i = matches.Count - 1 To 0 Step -1
        rCell.Characters(matches(i).firstindex + Len(matches(i)), 1).Text = ""
        rCell.Characters(matches(i).firstindex + 1, 1).Text = ""
    Next
       
End Sub

 

Il codice spiegato nel dettaglio

La procedura accetta due parametri obbligatori e uno facoltativo: il primo è il testo da interpretare (anche un riferimento a una cella va bene, se contiene un testo), il secondo è una cella dove depositare il risultato dell’elaborazione. Il terzo parametro rappresenta il delimitatore utilizzato, se questo parametro viene omesso verrà utilizzato per default il cancelletto.
La routine si preoccupa di eliminare i delimitatori al termine dell’elaborazione (perchè non fanno parte del testo, sono solo dei marcatori).

sText = Replace(sText, String(2, delimiter), Chr(255))

Il primo passaggio è subito interessante, perchè due delimitatori consecutivi vengono compressi a uno solo, questo per evitare che vengano spazzati via. Per far questo sostituiamo le occorrenze dei doppi delimitatori con un carattere speciale, che al termine verrà di nuovo rimpiazzato dal delimitatore singolo.

Set re = CreateObject("VBScript.RegExp")

Poi arriviamo al cuore dell’intera faccenda: per ottenere le sostituzioni desiderate sfruttiamo un’espressione regolare. Argomento affascinante e complesso, ricordatemi di farne un bell’articolo un giorno 🙂
In breve un’espressione regolare è un modello per cui il motore delle espressioni regolari tenta di trovare una corrispondenza nel testo di input. Un modello è costituito da uno o più i valori letterali carattere, operatori o costrutti. Si tratta di uno strumento tanto utile, e potente quanto ostico e di difficile assimilazione. Si possono effettuare ricerche e sostituzioni all’interno di una stringa, verifiche, convalide di dati, ricerca di schemi regolari. La chiave di una espressione “regolare” (detta così proprio perchè risponde a regole predeterminate) è il “pattern” che è in sostanza una sequenza di caratteri in cui sono descritte mediante qualche convenzione le informazioni necessarie ad eseguire le operazioni richieste. 

re.Pattern = "[" & delimiter & "](.*?)[" & delimiter & "]"

Nel nostro codice, il pattern dell’espressione regolare dice al motore di RegExp di cercare un delimitatore seguito da una o più ricorrenze di un carattere qualsiasi, seguito da un delimitatore, e lo memorizza come “gruppo”. In pratica cerca qualsiasi cosa racchiusa tra due delimitatori. Questo permette di interpretare correttamente solo le coppie chiuse di delimitatori.

For Each match In matches
    i = InStr(s, match)
    k = k + 1
    ReDim Preserve p1(k), p2(k)
    p1(k) = i
    p2(k) = Len(match)
Next

Quando l’espressione regolare viene eseguita, restituisce dei risultati (memorizzati nel vettore “matches” che rappresenta tutti i “gruppi” riconosciuti dalla ricerca). Per ogni risultato, cioè per ogni parola racchiusa tra due delimitatori, vengono memorizzate le posizioni relative all’interno della stringa di testo originale.

sText = Replace(sText, Chr(255), delimiter)
rCell = sText

Il testo originale viene immesso nella cella di destinazione, pronto per essere ripulito e formattato (abbiamo avuto cura di ricordarci di rimpiazzare il carattere speciale iniziale con un solo delimitatore).

For i = 1 To k
    rCell.Characters(p1(i), p2(i)).Font.Color = vbRed
Next

Il successivo ciclo For provvede a colorare di rosso (vbRed) le porzioni della stringa di testo nella cella di destinazione che si trovano nelle posizioni già memorizzate.

For i = matches.Count - 1 To 0 Step -1
    rCell.Characters(matches(i).firstindex + Len(matches(i)), 1).Text = ""
    rCell.Characters(matches(i).firstindex + 1, 1).Text = ""
Next

L’ultimo ciclo For si preoccupa di eliminare i caratteri indesiderati dalla cella di destinazione (ossia, i delimitatori, ormai inutili, che hanno fatto parte delle coppie riconosciute come regolari).

Volete provare e dirci cosa ne pensate?

Avete suggerimenti o volete implementare la vostra versione? Fatecelo sapere nei commenti!

Delimitare e formattare testo

Delimitare e formattare testo

LoginRegistrati
Stai vedendo 1 articolo (di 1 totali)
  • Autore
    Articoli
  • #12805 Risposta

    vecchio frac
    Senior Moderator
    • Sfida #1
      171 pts

      All'epoca dei primi pc, qualche milione di anni fa... Ehm, qualche decina di anni fa, all'alba dell'èra informatica di massa, quando ancora il WYSIWYG era un sogno (cioè poter vedere su schermo gli effetti di testo), chi utilizzava i primi Word processor poteva delimitare la formattazione del testo con caratteri speciali per ottenere in fase di stampa l'effetto voluto...

      [Leggi tutto al seguente link: https://www.excelvba.it/forumexcel/delimitare-e-formattare-testo/]

    LoginRegistrati
    Stai vedendo 1 articolo (di 1 totali)
    Rispondi a: Delimitare e formattare testo
    Gli allegati sono permessi solo ad utenti REGISTRATI
    Le tue informazioni:



    vecchio frac - 2748 risposte

    albatros54
    albatros54 - 741 risposte

    patel
    patel - 636 risposte

    Marius44
    Marius44 - 564 risposte

    Luca73
    Luca73 - 532 risposte