Le ComboBox e le proprierà LinkedCell  e  ListFillRange

Quando si usano le ComboBox (casella combinata) (prese da Casella degli strumenti o Strumenti di controllo), è inevitabile avere a che fare con le "proprietà" riportate nel titolo. Ricordo che per "LinkedCell" si intende il riferimento alla cella del foglio di lavoro, nella quale far corrispondere il valore selezionato nel menù a discesa della combobox stessa, per "ListFillRange" invece si intende il riferimento al range di celle della colonna che conterrà i dati da visualizzare nella combobox. Questi riferimenti possono venir scritti direttamente nella finestra delle proprietà della combobox, oppure inserirli in eventi, come ad esempio l'apertura del foglio di lavoro nel quale risiede la combobox, tipo :

Private Sub Worksheet_Activate()
ComboBox1.LinkedCell = ("A1")
ComboBox1.ListFillRange = ("C1:C50")
End Sub

In questo modo è possibile pilotare, su una stessa combobox, sia la cella di destinazione, sia il range di provenienza dati, come potrebbe accadere se avessimo vari elenchi da caricare a secondo il tipo di dati da gestire. Sempre per fare un esempio, potremmo avere sul foglio di lavoro dove c'è la combobox, un elenco di nomi in C1:C50, e sul foglio2 un elenco di città, o numeri, o colori, o codici, o quel che vi pare, e che si voglia alternativamente, selezionare i dati presi dai due diversi elenchi. Procederemo così.

  1. lasceremo la routine all'apertura del foglio.

  2. inseriremo un CommandButton (sempre da casella degli strumenti) e nella proprietà Caption scriveremo l'identificativo, del tipo: Elenco A, indi nell'evento Click del CmdButton scriveremo:  PrivateSub CommandButton1_Click()
    ComboBox1.LinkedCell = ("A1")
    ComboBox1.ListFillRange = ("C1:C50")
    End Sub

  3. inseriremo un  secondo CommandButton (sempre da casella degli strumenti) e nella proprietà Caption scriveremo l'identificativo, del tipo: Elenco B, indi nell'evento Click del CmdButton scriveremo: PrivateSub CommandButton2_Click()
    ComboBox1.LinkedCell = ("A1")
    ComboBox1.ListFillRange = ("Foglio2!D1:D50")
    End Sub

In questo modo avremo: all'apertura del foglio1, il caricamento dei dati presenti su foglio1 da C1 a C50, premendo il pulsante 2 il caricamento dei dati provenienti dal foglio 2 da D1 a D50. Il Pulsante 1 servirà a ripristinare l'elenco originario (altrimenti avremmo dovuto provocare l'"Activate" del foglio1, selezionando un altro foglio per poi ritornare al foglio 1). Avremmo anche potuto indicare una diversa cella di destinazione (linkedCell) se fosse stato necessario. Ma per ciò che descrivo di seguito, lasciamo la LinkedCell invariata.

Il motivo di queste note, è scaturito da una domanda rivoltami, che chiedeva come si poteva fare ad avere la LinkedCell, non fissa, ma variabile, collegata ad una cella, in quel momento attiva (ActiveCell). Ora, questo non è possibile perchè anche se selezioniamo una cella qualsiasi (è diventa ActiveCell), nel momento che andiamo a selezionare la combobox per scegliere il dato che ci interessa, TOGLIAMO il focus dalla cella in quel momento attiva per spostarlo sulla combobox, e quindi "addio" alla cella attiva. Un'istruzione del tipo : ComboBox1.LinkedCell = ActiveCell non avrebbe quindi senso.

Tra le varie soluzioni possibili, la più indicata, mi sembra questa: definire quindi una LinkedCell fissa, e modificare invece la destinazione del valore presente in questa cella, usando il copia/incolla con destinazione su una cella attiva; risolviamo così il quesito postomi, con una semplice macro associata ad un pulsante. Selezioneremo PRIMA il dato voluto nella combobox, selezioniamo poi la cella di destinazione, e clicchiamo sul pulsante attivando questa macro

Sub Scopiazza()
Range("E1").Copy
'copia il contenuto di E1, la LinkedCell
With ActiveCell
'con la cella in quel momemto attiva, incolla
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
End With
Application.CutCopyMode = False
End Sub

 

E nella cella precedentemente selezionata otterremo il dato voluto.

Su alcune versioni precedenti, però non mi ricordo, può essere necessario variare l'istruzione relativa all'identificazione della cella attiva; queste sotto sono tutte equivalenti, eventualmente trovate la vostra.

ActiveCell
Application.ActiveCell
ActiveWindow.ActiveCell
Application.ActiveWindow.ActiveCell