Lavorare con le ListBox o ComboBox a una e a più colonne
- parte quarta -

| <<< Prima parte | <<< Seconda parte | <<<Terza parte | Quarta parte |

Quando si usa una ListBox a più colonne possiamo trovarci in due situazioni comunque fastidiose:

Questo potrebbe essere un esempio.

Questo, invece, potrebbe essere l'aspetto che potremmo desiderare.

 

Larghezza delle colonne proporzionale al testo

In fase di esecuzione abbiamo la possibilità di ridimensionare opportunamente:

Conosco un metodo abbastanza semplice:

Il valore da assegnare come larghezza della UserForm è il risultato di un semplice calcolo.

quindi avremo: LenMax + 25 + 10 + 10 + 3 + 3

E' ovvio che, se non vogliamo, possiamo eccedere in queste misure, ma non sarà conveniente abbassarle.

Il cuore della routine che sto per presentare sta sul metodo che uso per determinare la lunghezza massima di ogni colonna.

  1. Sulla UserForm disegno, oltre agli oggetti che mi servono per la normale gestione dell'applicativo che sto per creare, un numero adeguato di Label pari al numero di campi previsto che debbono essere ospitati nella ListBox più uno (se i campi, per campi intendiamo colonne, sono 5, disegnamo 6 Label)
  2. Queste Label le possiamo nascondere intervenendo sula Proprietà Visible della finestra proprietà relativa a ciascuna Label impostando la proprietà a False, oppure le nascondiamo mettendole sotto un controllo che occupa maggior spazio e sia capace di sovrapprsi ad esse
  3. Per non complicarci la vita, queste Label saranno le prime che saranno disegnate nella UserForm in modo che siano denominate Label1, Label2, ecc (questo ci faciliterà le operazioni da eseguire nel codice)
  4. Impostiamo per tutte queste Label altre due proprietà o da programma o nella finestra proprietà della Label:
    • AutoSize = True (la Label assume la lunghezza adatta per contenere il testo)
    • WordWrap = False (al testo nella Label non è permesso di andare accapo ma si dispone su un'unica riga)
  5. Durante la lettura dei dati da aggiungere alla ListBox
    • scriviamo il campo anche nell'ultima label aggiungendo un paio di caratteri che chiaramente sono di una larghezza consistente in modo da ottenere un certo spazio tra una colonna ed un'altra:
      Controls("Label" & UltimaLabel).Caption = Intervallo(R, C) & "QQ"
    • confrontiamo la lunghezza acquisita da questa label con quella di turno (la 1, la 2, ecc)
      If Controls("Label" & UltimaLabel).Width > Controls("Label" & C).Width Then
    • se il controllo risulta positivo trasferiamo la stessa stringa alla label di turno
      Controls("Label" & C).Caption = Controls("Label" & UltimaLabel).Caption
    • in questo modo, alla fine del ciclo, avremo le label con la stringa più lunga e possiamo leggerne la lunghezza

Finita la lettura dei dati, concludiamo il nostro lavoro

For C = 1 To Colonne
LenMax = LenMax + Controls("Label" & C).Width
Larg = Larg & Controls("Label" & C).Width & ";"
Next
Larg = Left(Larg, Len(Larg) - 1)

Con queste istruzioni:

in LenMax avremo la lunghezza totale da attribuire alla ListBox

in Larg avremo una stringa in questo formato:
53,25;42;111,75;35,25;60,75
ossia avremo i valori da attribuire a ciascuna colonna separati da un ; (punto e virgola).

Questa stringa deve rispettare la sintassi usata per dimensionare le colonne di una ListBox:

ListBox1.ColumnWidths = Num1;Num2;num2;ecc

 

Con

Larg = Left(Larg, Len(Larg) - 1)

togliamo l'ultimo punto e virgola inserito durante l'esecuzione del ciclo ottenendo:

53,25;42;111,75;35,25;60,75 

anzichè

53,25;42;111,75;35,25;60,75

Finita questa preparazione siamo pronti a concludere il lavoro.

 

Attenzione

Ho provato ad usare la routine usando altri eventi della UserForm, ma sembra che questa funzioni solo nella UserForm_Activate

Con questo metodo siamo sicuri che le dimensioni delle colonne terranno conto anche del tipo di Font e di qualsiasi dimensione. Unico accorgimento in caso di cambio del Font e della dimensione del Font è quello di cambiarli sia nella ListBox che nelle Label usate per la misurazione.

Private Sub UserForm_Activate()
Dim Righe, Colonne, R, C
Dim Intervallo As Range
Dim LenMax, Larg
With Range("A1").CurrentRegion
Righe = Range("A1").CurrentRegion.Rows.Count - 1
Colonne = Range("A1").CurrentRegion.Columns.Count
End With
Set Intervallo = Range("A1").Resize(Righe, Colonne)
ListBox1.Clear
ListBox1.ColumnCount = Colonne
' impostazione delle proprietà AutoSize e WordWrap per le Label usate per la misurazione delle colonne
For C = 1 To Colonne + 1
Controls("Label" & C).AutoSize = True
Controls("Label" & C).WordWrap = False
Next
For R = 1 To Righe
ListBox1.AddItem
For C = 1 To Colonne
' controllo della lunghezza delle stringhe
Controls("Label" & Colonne).Caption = Intervallo(R, C) & "QQ"
If Controls("Label" & Colonne).Width > Controls("Label" & C).Width Then
Controls("Label" & C).Caption = Controls("Label" & Colonne).Caption
End If
' ed inserimento delle voci nella ListBox
ListBox1.List(R - 1, C - 1) = Intervallo(R, C)
Next
Next
' calcolo della lunghezza totale e creazione della stringa che contiene le misure delle colonne
For C = 1 To Colonne
LenMax = LenMax + Controls("Label" & C).Width
Larg = Larg & Controls("Label" & C).Width & ";"
Next
Larg = Left(Larg, Len(Larg) - 1)
' modifica della larghezza della UserForm
If UserForm1.Width < LenMax + 25 + 10 + 10 + 3 + 3 Then
UserForm1.Width = LenMax + 25 + 10 + 10 + 3 + 3
End If
' modifica della larghezza della ListBox
ListBox1.Width = LenMax + 25
' modifica della larghezza delle colonne della ListBox
ListBox1.ColumnWidths = Larg
' per una ListBox a 5 colonne la larghezza delle colonne si sarebbe dovuta impostare in questa maniera
' ListBox1.ColumnWidths = _
Label1.Width & ";" _
& Label2.Width & ";" _
& Label3.Width & ";" _
& Label4.Width & ";" _
& Label5.Width
End Sub

 

Bene. Per ora è tutto. Se sarà il caso torneremo sull'argomento.


| <<< Prima parte | <<< Seconda parte | <<<Terza parte | Quarta parte |