Locazioni protette da scrittura

Ultima modifica: 29-05-2016

Premesso che una protezione sicura in Excel non è possibile ottenerla contro malintenzionati, potremmo desiderare proteggerci almeno dalla nostra distrazione.

 

Il lavoro sul foglio di Excel

Per fare questo occorre seguire questi passi.

  1. Selezionare tutte le cdelle del foglio portandosi nell'angolo superiore destro del foglio e facendo clic sul quadratino grigio che si trova tra la A ed 1 come è visibile in questa immagine 
  2. Selezionare da menù Formato ==> celle per mostrare questa finestra
  3. Scegliere la scheda Protezione nella finestra Formato celle
  4. Deselezionare le due caselle se sono selezionate per rimuovere la protezione a tutto il foglio
  5. Chiudere la finestra di dialogo
  6. Selezionare le celle che si intendono proteggere e ripetere i punti 2 e 3
  7. Selezionare le due caselle Bloccata e Nascosta
  8. Uscire da questa finestra
  9. Selezionare da menù Strumenti ==> protezione ==> Proteggi foglio
  10. Nella conseguente finestra comportarsi come mostrato nella figura
  11. Chiudere anche questa finestra

Da questo momento il foglio è protetto nelle sole celle indicate nel punto 6 e queste possono essere modificate solo intenzionalmente, ossia togliendo la protezione al foglio eseguita nei punti 9 e 10 scegliendo da menù Strumenti ==> protezione ==> Rimuovi protezione foglio.

 

Il Lavoro in VBA

Se volessimo lavorare in VBA Le cose non sarebbero poi tanto più complicate. anzi potremmo muoverci con più sicurezza. Una volta scritte le istruzioni non ci sarebbe più il pericolo di dimenticare alcuni passaggi.

Potremmo anche fare qualcosa in più, come per esempio individuare La prima cella di una tabella e l'intervallo che questa occupa nel foglio per poter poi lavorare su tale intervallo.

 

Quel che presento è leggermente più complesso che individuare una tabella. Ma presento come individuare più di una tabella.

Per fare questo poniamo delle celle sentinella per poter individuare da codice il settore su cui dobbiamo lavorare, quindi proteggiamo queste per evitare che vengano accidentalmente sovraascritte e cambiate.

Poniamo questo esempio. Una banale tabella altrettanto banalmente posizionata in una locazione imprecisata del foglio ed impostata in questo modo

 

  D E F G H
6 COGNOME NOME INDIRIZZO CAP PROV
7 Migliavacca Luigi Carassai 52012 LT
8 Rizzi Carlo Portico 26010 CH
9 Liberali Franca Borgomasino 6060 VI
10 Di Maggio Mario Castilenti 11020 PS
11 Scicchitano Andrea Santa Mama 28040 RC
12 Maggi Massimo Capanne Vecchie 36010 LI
13 Edelvisi Maurizio San Marco di Teggiano 16010 LO
14 Gerardini Silvano Capriglio 61040 FI
15 Pasotti Alessio Ascea 90024 CN
16 Calvi Giovanni San Carlo di Sessa 28026 BZ

 

ed un'altra tabella posta in un altra locazione imprecisata del foglio

 

  J K L M
6 OPERATORE REGIONE ATTIVITA' COD FISC
7 Migliavacca Lombardia Agente di commercio 39758885447
8 Rizzi Lombardia Ottico 63412085762
9 Liberali Piemonte Agente di commercio 84358933607
10 Di Maggio Veneto Ottico 46135462107
11 Scicchitano Lazio Imprenditore 38577046928
12 Maggi Lazio Medico 64974410522
13 Edelvisi Sardegna Orafo 23227159739
14 Gerardini Piemonte Avvocato 63116541155
15 Pasotti Abruzzo Musicista 90178260521
16 Calvi Veneto Musicista 6823185060

 

In ciascuna delle tabelle abbiamo posto delle celle sentinella: Cognome ed Operatore.

Per individuare ciascuna delle tabelle su cui cui vogliamo lavorare scriviamo una routine che, una volta trovata la cella sentinella, ne determina la dimensione e la esatta locazione. Un esempio potrebbe essere questo, ovviamente, se siamo sicuri che nessuno ci venga a cambiare il contenuto di tali celle. Il codice per individuare le due tabelle e determinarne le rispettive dimensioni è relativamente semplice.

Per comodità e per risparmiare codice iniziamo con il dichiarare alcune variabili nella zona pubblica del modulo:

Dim CellaCognome, CellaOperatore
Dim TabCognome As Range, TabOperatore As Range

Quindi passiamo alla routine che individua la locazione delle singole tabelle:

Sub TrovaTabelle()
Dim CL As Range
Dim NumR, NumC
'"Individuo le due celle sentinella delle due tabelle
For Each CL In ActiveSheet.UsedRange
If CL = "COGNOME" Then
CellaCognome = CL.Address
With Range(CellaCognome).CurrentRegion
NumR = .Rows.Count
NumC = .Columns.Count
Set TabCognome = .Offset(1, 0).Resize(NumR - 1, NumC)
End With
ElseIf CL = "OPERATORE" Then
CellaOperatore = CL.Address
With Range(CellaOperatore).CurrentRegion
NumR = .Rows.Count
NumC = .Columns.Count
Set TabOperatore = .Offset(1, 0).Resize(NumR - 1, NumC)
End With
Exit For
End If
Next
'eseguo la protezione delle due celle individuate
Cells.Locked = False
Cells.FormulaHidden = False
Range(CellaCognome).Locked = True
Range(CellaCognome).FormulaHidden = True
Range(CellaOperatore).Locked = True
Range(CellaOperatore).FormulaHidden = True
Sheets("Foglio1").Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
End Sub

Alla fine di questa routine abbiamo, nel caso presentato, che:

Da questi presupposti possiamo partire con il resto del nostro lavoro che ora non affronteremo in quanto è fuori dell'argomento che stiamo trattando.

Dirò solo che conoscendo la prima cella delle nostre tabelle e l'intervallo che queste occupano nele foglio possiamo fare qualsiasi operazione riferendoci ora ad una ora all'altra tabella.

Ma cosa succede se disgraziatamente a qualcuno viene in mente di cambiare il nome delle celle sentinella o magari solo di cambiarle da maiuscole a minuscole? Semplicemente la ricerca fallisce e tutto il lavoro verrebbe vanificato. Allora dobbiamo fare in modo che almeno le celle di cui ci serviamo per rintracciare le tabelle non vengano corrette, proteggendole.

Per far questo usiamo alcuni mezzi che il VBA ci mette a disposizione con queste istruzioni poste in fondo al codice:

Cells.Locked = False
Cells.FormulaHidden = False
Range(CellaCognome).Locked = True
Range(CellaCognome).FormulaHidden = True
Range(CellaOperatore).Locked = True
Range(CellaOperatore).FormulaHidden = True
Sheets("Foglio1").Protect DrawingObjects:=True, Contents:=True, Scenarios:=True

Per l'ultima istruzione di questo blocco uso il Metodo Protect ed alcune espressioni ad esso associate: DrawingObjects, Contents, Scenarios.