Vi è mai capitato di desiderare, dopo aver disegnato un modulo su un foglio di Excel spostarvi tra i suoi campi con precisione proprio come se vi trovaste su una maschera vera, magari disegnata su una UserForm? Recentemente ho avuto modo di attuare questo semplice progettino
Questo potrebbe essere un banale esempio di come potrebbe essere strutturata una nostra maschera
| A | B | C | D | E | F | G | H | I | J | K | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | |||||||||||
| 2 | |||||||||||
| 3 | INSERIMENTO DATI | ||||||||||
| 4 | |||||||||||
| 5 | COGNOME | NOME | |||||||||
| 6 | |||||||||||
| 7 | INDIRIZZO | ||||||||||
| 8 | |||||||||||
| 9 | CITTA' | CAP | |||||||||
| 10 | |||||||||||
| 11 | TEL 1 | TEL 2 | |||||||||
| 12 | |||||||||||
| 13 | FINE | ||||||||||
Come si intuisce l'inserimento deve avvenire nelle celle evidenziate nella colonna E e nella colonna I. Inserito il dato premendo il tasto INVIO si andrà via via nelle successive celle.
Prima di fare questo però è necessario preparare il foglio.
I passi per la preparazione del foglio
Se osservate bene sono quasi le stesse che ho mostrato all'inizio di Locazioni protette da scrittura .
Il lavoro da fare in VBA
Terminato questo lavoro sul foglio si può passare in VBA (Alt + F11)
Quel che vogliamo è dare la possibilità all'utente di spostarsi ed inserire i dati solo sulle celle lecite (E5 - E7 - E9 - E11 - I5 - I11) rifiutando anche la sola selezione di qualsiasi altra cella.
Per fare questo dobbiamo usare il modulo relativo al foglio da controllare, nel nostro caso il modulo relativo al Foglio1.
Per accedere a questo modulo, se non è ancora selezionato è sufficiente un foppio clic sul Foglio1 della finestra VBAProject
In questo modulo usiamo l'evento Worksheet_SelectionChange perchè la routine venga attivata alla semplice selezione di una cella. Con questo evento possiamo usare un parametro chiamato Target, che è un oggetto Range.
Il lavoro comincia
impedire la selezione multipla, quindi:
If Target.Count > 1 Then ActiveCell.Select
Selezionando la cella attiva di una qualsiasi selezione multipla viene eseguito il controllo
Si stabilisce l'intervallo valudo usando il metodo Union in quanto le celle che si vogliono aggregare non sono contigue:
Set Intervallo = Union(Range("E5"), Range("E7"), Range("E9"), Range("E11"), Range("I5"), Range("I9"), Range("I11"))
Verifica se si è selezionata la cella I13 (la cella che viene selezionata quando il lavoro è terminato)
In questo caso si controlla se sono stati inseriti tutti i campi:
Se tutti i campi sono stati inseriti la selezione della cella I13 resta
In caso contrario viene selezionata la prima cella ancora libera
If Target.Address(RowAbsolute:=False, ColumnAbsolute:=False) = "I13" Then
' con la Proprietà Address vengono usati gli argomenti RowAbsolute e ColumnAbsolute per avere un riferimento tipo "I13"
For Each CL In Intervallo
If CL = "" Then
CL.Select
Exit Sub
End If
Next
MsgBox "Fine inserimento"
End If
La cella selezionata non si trova in una delle celle definite sopra
In questo caso si va alla ricerca di una cella valida vuota. Se non si trova una cella vuota si seleziona la cella I13.
Per stabilire se la cella selezionata si trova nell'intervallo valido si usa il metodo Intersect che stabilisce appunto se la cella in esame è compresa nell'intervallo.
If Intersect(Target, Intervallo) Is Nothing Then
For Each CL In Intervallo
If CL = "" Then
CL.Select
Exit Sub
End If
Next
Range("I13").Select
End If
Qui di seguito l'intero listato della routine appena illustrata:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim Intervallo As Range, CL As Range
If Target.Count > 1 Then ActiveCell.Select
Set Intervallo = Union(Range("E5"), Range("E7"), Range("E9"), Range("E11"), Range("I5"), Range("I9"), Range("I11"))
If Target.Address(RowAbsolute:=False, ColumnAbsolute:=False) = "I13" Then
For Each CL In Intervallo
If CL = "" Then
CL.Select
Exit Sub
End If
Next
MsgBox "Fine inserimento"
End If
If Intersect(Target, Intervallo) Is Nothing Then
For Each CL In Intervallo
If CL = "" Then
CL.Select
Exit Sub
End If
Next
Range("I13").Select
End If
End Sub
Anche questa procedura non ci protegge in modo efficacie da azioni di malintenzionati, anche se per attuare questo tipo di protezione usassimo una password. E' invece abbastanza valida contro la nostra stessa distrazione.