Calcolare larghezza testo in una cella unita e numero di linee

di il
8 risposte

Calcolare larghezza testo in una cella unita e numero di linee

Buongiorno.
Sono certo che non è un problema di facile soluzione.
Ho provato varie strade, ma credo che le variabili in gioco siano troppe.

Questo il prospetto.
Ho una riga di celle unite (2 per ogni colonna) in cui in ognuna inserisco del testo. Le celle sono impostate per mandare a capo il testo.
L'altezza della riga è fissa, ovviamente, mentre la larghezza delle singole colonne può variare.
Il mio problema è che il testo che scrivo dovrebbe occupare al massimo 2 linee, altrimenti va in "overflow". Per ovviare vorrei verificare se lo spazio complessivo occupato è tale da superare le 2 righe e nel caso calcolare la larghezza della colonna necessaria (che imposterei) per rientrare nelle 2 righe volute.
Il font è fisso: Arial, 8 punti.
Ho provato a calcolare lo spazio occupato ma non è affatto semplice, e anche le soluzioni nel WEB non aiutano.
Vorrei precisare che non c'è "autofit" e che non voglio utilizzarlo.

Qualcuno ha una soluzione? Anche solo qualche suggerimento con cui iniziare a lavorare...

8 Risposte

  • Re: Calcolare larghezza testo in una cella unita e numero di linee

    Ciao
    Con qualche riga di codice VBA penso si possa risolvere. Io ho fatto la prova su 4 colonne di cui tre con celle unite e testo di lunghezza differente. Questo il codice:
    
    Sub Riduci_2_Righe()
    For i = 1 To 4
      Columns(i).EntireColumn.AutoFit
      Columns(i).ColumnWidth = Columns(i).ColumnWidth / 2 + 2
    Next i
    End Sub
    
    Fai sapere. Ciao,
    Mario
  • Re: Calcolare larghezza testo in una cella unita e numero di linee

    Grazie Marius, intanto.
    Allora, avevo già pensato all'autofit, ma il mio problema è che le celle in questione sono parte di un foglio più complesso, e le colonne incrociano altre celle soprastanti o sottostanti, quindi l'autofit ragiona in relazione a quella che al comando office sembra la larghezza più congegnale (come detto da Microsoft: achieve the best fit). Ciò implica che se io avessi solo le celle interessate e null'altro, la tua soluzione, che in qualche modo avevo già valutato , sarebbe corretta, ma dipendendo da diverse altre "configurazioni" non sempre l'autofit opera come desiderato. Anzi...
    In ogni modo, non trovando un sistema per calcolare in pixel (o in punti) lo spazio disponibile nel range unito e quello occupato dal testo (che sarebbe la strada più indicata), probabilmente mi avvarrò dell'autofit imponendo delle larghezze di cella massime, una faccenda arbitraria ma comoda.
    Se hai qualche altro suggerimento per migliorare il codice, ben venga.

    Grazie ancora.
  • Re: Calcolare larghezza testo in una cella unita e numero di linee

    Ciao
    Senza un esempio concreto non riesco a capire la problematica. Se le colonne incrociano altre celle soprastanti o sottostanti, come dici, se queste celle NON SONO UNITE il mio codice non le tocca; se fossero unite allora il problema è un altro.
    Credo sarebbe meglio poter "lavorare" sul tuo foglio (senza dati sensibili ma con righe e colonne che evidenzino il problema); se puoi, allegalo.
    Ciao,
    Mario

    NB - Non dimentichiamo, se non erro, che la visualizzazione è influenzata anche dalla risoluzione dello schermo.
  • Re: Calcolare larghezza testo in una cella unita e numero di linee

    Sicuramente ci sono molte celle sotto e sopra quelle interessate, e parecchie di queste sono unite. Infatti questo è il punto (tra l'altro non sono ripetute, ma sparse in un foglio ampio, colmo di dati).
    Non ti allego il foglio perché, appunto, è molto complesso.
    Aggiungo, però, qualche elemento. In partenza, l'intero foglio è in italiano, e le larghezze delle colonne sono tali da permettere la visualizzazione su 2 righe nelle celle unite interessate. Tramite un tasto, una macro procede alla sostituzione del testo in un'altra lingua che può essere scelta dall'utente, e qui si giunge al problema, perché molti testi sono più lunghi, quindi vanno in overflow.
    Come dicevo, ci sono troppe variabili, e la strada maestra sarebbe quella che ho specificato sopra riguardante lo spazio reale disponibile e quello occupato in punti.
    Non trovando il modo, ho deciso di mappare le larghezze e trovare la minima necessaria affinché si abbiamo tutti i testi su 2 righe, per ogni lingua; non un lavoro informaticamente ineccepibile, ma sufficiente per i miei bisogni.
    Soluzione "maccheronica", lo so...
  • Re: Calcolare larghezza testo in una cella unita e numero di linee

    Arial e' un font in cui la dimensione del carattere dipende da carattere a carattere.
    Il piu' corto e' ovviamente la 'i' il piu' largo la 'M' e la 'W'.
    Ora, per evitare conti complicati, puoi semplicemente vedere quante M ci stanno su due righe (diciamo N) e limitare il testo a N*1.5 o N*2 caratteri.
    Eventualmente aumenti un po' se vedi che 'mediamente' avanza troppo spazio.
  • Re: Calcolare larghezza testo in una cella unita e numero di linee

    Grazie per il suggerimento, Migliorabile.
    A dire il vero, io ho già scritto una routine per il calcolo dello spazio di un testo in punti. La allego, così magari la valutate.
    Il problema è che non c'è corrispondenza tra il risultato e la column.width; voglio dire, io riesco a calcolare (credo, se la routine è corretta) lo spazio occupato dal testo, ma non quello disponibile nel range delle celle unite.
    Magari qualcuno può "illuminarmi"...
    Questa è la routine:
    Dim mDimensCarattere(32 To 127) As Double ' widths of printing characters
    Dim msNomeFont  As String ' font name having these widths
    
    Sub testo()
    'Debug.Print ActiveCell.Font.Name, ActiveCell.Font.Size
    'Debug.Print sLarghezzaInPunti(Cells(45, 18), "Arial", 7)
    End Sub
    
    Function sLarghezzaInPunti(sDatoTesto As String, sNomeFont As String, sDimensioneFont As Double) As Double
         ' ----  restituisce la larghezza approssimativa in punti di una stringa di testo
         ' di un font specifico avente una specifica dimensione ----
         ' ---> esempio: sLarghezzaInPunti("Hello, World", "Arial", 10) (ritorna 55.78) <---
         
        Dim i       As Long
        Dim j       As Long
         
        If Len(sNomeFont) = 0 Then Exit Function
        If sNomeFont <> msNomeFont Then
            If Not inizialDimCarattere(sNomeFont) Then Exit Function
        End If
         
        For i = 1 To Len(sDatoTesto)
            j = Asc(Mid(sDatoTesto, i, 1))
            If j >= 32 Then
                sLarghezzaInPunti = sLarghezzaInPunti + sDimensioneFont * mDimensCarattere(j)
            End If
        Next i
    End Function
     
    Function inizialDimCarattere(sNomeFont As String) As Boolean
        Dim i       As Long
         'in base al font, determina la larghezza in punti per il singolo carattere
         ' e lo restituisce nella variabile 'mDimensCarattere' dichiarata a livello di modulo.
         'la funzione restituisce il valore VERO solo se il testo è stato trovato nell'elenco
        Select Case sNomeFont
        Case "Arial"
            For i = 32 To 127
                Select Case i
                Case 39, 106, 108
                    mDimensCarattere(i) = 0.1902
                Case 105, 116
                    mDimensCarattere(i) = 0.2526
                Case 32, 33, 44, 46, 47, 58, 59, 73, 91 To 93, 102, 124
                    mDimensCarattere(i) = 0.3144
                Case 34, 40, 41, 45, 96, 114, 123, 125
                    mDimensCarattere(i) = 0.3768
                Case 42, 94, 118, 120
                    mDimensCarattere(i) = 0.4392
                Case 107, 115, 122
                    mDimensCarattere(i) = 0.501
                Case 35, 36, 48 To 57, 63, 74, 76, 84, 90, 95, 97 To 101, 103, 104, 110 To 113, 117, 121
                    mDimensCarattere(i) = 0.5634
                Case 43, 60 To 62, 70, 126
                    mDimensCarattere(i) = 0.6252
                Case 38, 65, 66, 69, 72, 75, 78, 80, 82, 83, 85, 86, 88, 89, 119
                    mDimensCarattere(i) = 0.6876
                Case 67, 68, 71, 79, 81
                    mDimensCarattere(i) = 0.7494
                Case 77, 109, 127
                    mDimensCarattere(i) = 0.8118
                Case 37
                    mDimensCarattere(i) = 0.936
                Case 64, 87
                    mDimensCarattere(i) = 1.0602
                End Select
            Next i
             
        Case "Consolas"
            For i = 32 To 127
                Select Case i
                Case 32 To 127
                    mDimensCarattere(i) = 0.5634
                End Select
            Next i
             
        Case "Calibri"
            For i = 32 To 127
                Select Case i
                Case 32, 39, 44, 46, 73, 105, 106, 108
                    mDimensCarattere(i) = 0.2526
                Case 40, 41, 45, 58, 59, 74, 91, 93, 96, 102, 123, 125
                    mDimensCarattere(i) = 0.3144
                Case 33, 114, 116
                    mDimensCarattere(i) = 0.3768
                Case 34, 47, 76, 92, 99, 115, 120, 122
                    mDimensCarattere(i) = 0.4392
                Case 35, 42, 43, 60 To 63, 69, 70, 83, 84, 89, 90, 94, 95, 97, 101, 103, 107, 118, 121, 124, 126
                    mDimensCarattere(i) = 0.501
                Case 36, 48 To 57, 66, 67, 75, 80, 82, 88, 98, 100, 104, 110 To 113, 117, 127
                    mDimensCarattere(i) = 0.5634
                Case 65, 68, 86
                    mDimensCarattere(i) = 0.6252
                Case 71, 72, 78, 79, 81, 85
                    mDimensCarattere(i) = 0.6876
                Case 37, 38, 119
                    mDimensCarattere(i) = 0.7494
                Case 109
                    mDimensCarattere(i) = 0.8742
                Case 64, 77, 87
                    mDimensCarattere(i) = 0.936
                End Select
            Next i
             
        Case "Tahoma"
            For i = 32 To 127
                Select Case i
                Case 39, 105, 108
                    mDimensCarattere(i) = 0.2526
                Case 32, 44, 46, 102, 106
                    mDimensCarattere(i) = 0.3144
                Case 33, 45, 58, 59, 73, 114, 116
                    mDimensCarattere(i) = 0.3768
                Case 34, 40, 41, 47, 74, 91 To 93, 124
                    mDimensCarattere(i) = 0.4392
                Case 63, 76, 99, 107, 115, 118, 120 To 123, 125
                    mDimensCarattere(i) = 0.501
                Case 36, 42, 48 To 57, 70, 80, 83, 95 To 98, 100, 101, 103, 104, 110 To 113, 117
                    mDimensCarattere(i) = 0.5634
                Case 66, 67, 69, 75, 84, 86, 88, 89, 90
                    mDimensCarattere(i) = 0.6252
                Case 38, 65, 71, 72, 78, 82, 85
                    mDimensCarattere(i) = 0.6876
                Case 35, 43, 60 To 62, 68, 79, 81, 94, 126
                    mDimensCarattere(i) = 0.7494
                Case 77, 119
                    mDimensCarattere(i) = 0.8118
                Case 109
                    mDimensCarattere(i) = 0.8742
                Case 64, 87
                    mDimensCarattere(i) = 0.936
                Case 37, 127
                    mDimensCarattere(i) = 1.0602
                End Select
            Next i
             
        Case "Lucida Console"
            For i = 32 To 127
                Select Case i
                Case 32 To 127
                    mDimensCarattere(i) = 0.6252
                End Select
            Next i
             
        Case "Times New Roman"
            For i = 32 To 127
                Select Case i
                Case 39, 124
                    mDimensCarattere(i) = 0.1902
                Case 32, 44, 46, 59
                    mDimensCarattere(i) = 0.2526
                Case 33, 34, 47, 58, 73, 91 To 93, 105, 106, 108, 116
                    mDimensCarattere(i) = 0.3144
                Case 40, 41, 45, 96, 102, 114
                    mDimensCarattere(i) = 0.3768
                Case 63, 74, 97, 115, 118, 122
                    mDimensCarattere(i) = 0.4392
                Case 94, 98 To 101, 103, 104, 107, 110, 112, 113, 117, 120, 121, 123, 125
                    mDimensCarattere(i) = 0.501
                Case 35, 36, 42, 48 To 57, 70, 83, 84, 95, 111, 126
                    mDimensCarattere(i) = 0.5634
                Case 43, 60 To 62, 69, 76, 80, 90
                    mDimensCarattere(i) = 0.6252
                Case 65 To 67, 82, 86, 89, 119
                    mDimensCarattere(i) = 0.6876
                Case 68, 71, 72, 75, 78, 79, 81, 85, 88
                    mDimensCarattere(i) = 0.7494
                Case 38, 109, 127
                    mDimensCarattere(i) = 0.8118
                Case 37
                    mDimensCarattere(i) = 0.8742
                Case 64, 77
                    mDimensCarattere(i) = 0.936
                Case 87
                    mDimensCarattere(i) = 0.9984
                End Select
            Next i
             
        Case Else
            MsgBox "Font name """ & sNomeFont & """ not available!", vbCritical, "sLarghezzaInPunti"
            Exit Function
        End Select
        msNomeFont = sNomeFont
        inizialDimCarattere = True
    End Function
    
    La subroutine "testo" serve per eseguire una prova.
    La routine non tiene conto della risoluzione dello schermo.
    Fatemi sapere.
  • Re: Calcolare larghezza testo in una cella unita e numero di linee

    Salve a tutti
    Si potrebbe utilizzare un Font di caratteri "Monospaced" i cui caratteri occupano tutti il medesimo spazio.
    Puoi leggere qualcosa a questo indirizzo https://webcrew.it/font-monospaced

    Ciao,
    Mario
  • Re: Calcolare larghezza testo in una cella unita e numero di linee

    Eh, vallo a spiegare al mio capo... o Arial, o niente.
    In ogni modo, resto sempre all'oscuro su come calcolare lo spazio disponibile all'interno delle celle unite. Lo so che sono pedante, ma senza quest'informazione non procedo di un passo.
    Comunque, grazie Mario. L'articolo mi sarà utile per altri scopi.
Devi accedere o registrarti per scrivere nel forum
8 risposte