Excel: protéger des cellules non vides par VBA

Signaler
Messages postés
3
Date d'inscription
vendredi 15 août 2008
Statut
Membre
Dernière intervention
16 août 2008
-
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
-
Bonjour, tout le monde.
Je recherche un bout de VBA me permettant de sélectionner toutes les cellules non vides d'une feuille Excel pour les verrouiller automatiquement à la sortie de la feuille, afin que lorsqu'on revient sur la feuille on ne puisse les modifier (sauf à déprotéger la feuille avec le mot de passe, bien sûr).
Quelqu'un aurait-il une suggestion?
Merci

Elge64

11 réponses

Messages postés
372
Date d'inscription
vendredi 27 juillet 2007
Statut
Membre
Dernière intervention
22 juillet 2013
1
Salut elge64

Voici un programme que j'ai fais spécialement pour toi sur Excel 2000.
J'espère que ça marchera sur ta version.
Inserer un bouton nommé "CmdVerCellNonVide" sur la feuil1.

-----------------------------------------------------------------------------------------
Private Sub CmdVerCellNonVide_Click()
 
'Zone utilisée


  Dim ZoneUtilisée As String
  Dim MotDePasse As String
 
'Plage utilisée sur la feuil1 de Excel


  ZoneUtilisée = "A1:M40"
 
'Mot de passe utilisé


  MotDePasse = "SESAME"
 
 
'On deprotege la feuille par le mot de passe "SESAME"


  Feuil1.Unprotect MotDePasse
 
'Verrouilles toutes les cellules de la plage


  Feuil1.Range("A1:M40").Locked = True
 
'Deverouilles les cellules vides de la plage


  Feuil1.Range("A1:M40").SpecialCells(xlCellTypeBlanks).Locked = False
 
'Bloque la saisie des cellules non vides en protégeant la feuil1 par "SESAME"


  Feuil1.Protect MotDePasse
  
End Sub

----------------------------------------------------------------------------------------

 Tu peux modifier le mot de passe ainsi que la zone utilisée dans ce code.
 A éviter d'écrire "ZoneUtilisée = "A1:IV65536".Ca ralentit !

 J'espère que ça te conviens.Merci de me donner des nouvelles

A++
Messages postés
3
Date d'inscription
vendredi 15 août 2008
Statut
Membre
Dernière intervention
16 août 2008

Ah oui, excellent le Specialcells sur les cellules vides, il suffisait d'y penser, mdr.
Je teste, et je te dis. Mais cela devrait le faire.
Merci, en tout cas, d'avoir réagi si rapidement.
Messages postés
3
Date d'inscription
vendredi 15 août 2008
Statut
Membre
Dernière intervention
16 août 2008

Après test, un constat, cela ne fonctionne pas pour les cellules fusionnées.
En suivant pas à pas, je vois qu'elles sont verrouillées, puis déverrouillées comme si elles étaient vides.
Etrange, non?
Si tu veux voir, je t'envoie ma feuille, tu verras. J'utilise Excel 2003.
A+
Messages postés
372
Date d'inscription
vendredi 27 juillet 2007
Statut
Membre
Dernière intervention
22 juillet 2013
1
salut
Effectivement , cela ne marche pas sur les cellules fusionnées.
je ne sais pas comment ta feuille Excel est formaté.
Le problème , c'est que l'on ne detecte pas les cellules fusionnées vides
avec l'instruction "SpecialCells".
On doit pouvoir trouver une autre solution..
Je regarde
A++
Messages postés
3
Date d'inscription
jeudi 20 août 2015
Statut
Membre
Dernière intervention
21 août 2015

Bonjour,

J'ai modifié un peu le code de départ pour que la protection s'active à chaque nouvelle modification de cellules, par contre la protection ne fonctionne pas pour toute les cases et je n'arrive pas à voir où est le problème.
J'ai créé un nom "Data" qui renvoi à une plage dynamique :

=DECALER(Data!$A$1;;;NBVAL(Data!$A:$A);NBVAL(Data!$1:$1)

pour ne pas avoir à sélectionner une plage, car mon tableau comprend beaucoup de données.

Private Sub Worksheet_Change(ByVal Target As Range)

  Dim ZoneUtilisée As String
  Dim MotDePasse As String
  ZoneUtilisée = "Data"
  MotDePasse = "data"
  ActiveSheet.Unprotect MotDePasse
  ActiveSheet.Range("Data").Locked = True
  ActiveSheet.Range("Data").SpecialCells(xlCellTypeBlanks).Locked = False
  ActiveSheet.Protect MotDePasse
End Sub


Est-ce que quelqu'un pourrait m'éclairer svp ?
Merci d'avance
Messages postés
14862
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
16 octobre 2020
446
EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ICI

Merci d'y penser dans tes prochains messages.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
229
Bonjour, Maaaj,
Ainsi que je l'ai déjà dit à plusieurs reprises :
Les formules Excel s'exécutent dans un fil (thread) distinct de VBA.
Elles ne déclenchent donc aucun évènement WorkSheet_Change (qui est un évènement VBA).

Messages postés
3
Date d'inscription
jeudi 20 août 2015
Statut
Membre
Dernière intervention
21 août 2015

Merci pour cette réponse rapide ucfoutu, je débute sous VBA et je ne maîtrise pas encore bien le sujet.
Comment pourrais-je faire alors pour que ces deux lignes s'applique soit à une plage dynamique soit à toute ma feuille (si cela n'alourdi pas trop mon évènement VBA ?

ActiveSheet.Range("Data").Locked = True
ActiveSheet.Range("Data").SpecialCells(xlCellTypeBlanks).Locked = False
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
229
Il n'est jamais adroit, avec Excel, de développer en "panachage" de formules excel et de code VBA.
Ou tout l'un, ou tout l'autre, mais pas les deux à la fois !
Avec ton histoire de formules, le seul évènement qui serait déclenchable serait l'évènement : worksheet_Calculate de la feuille contenant ces formules.... Ce qui veut dire : lourd de chez lourd ... puisque déclenchable à tout moment !
Que faire alors ?
Je ne saurais te répondre valablement sans connaître la TOTALITE de ton application (la stratégie à mettre en place dépendant totalement de cette connaissance).
________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
Messages postés
3
Date d'inscription
jeudi 20 août 2015
Statut
Membre
Dernière intervention
21 août 2015

Encore une fois merci de ta réponse rapide, je n'avais pas très bien expliquer mon problème en effet.

Je reprends depuis le début :

Mon application est une base de données comportant sur des essais. Elle comprend des notations réalisées sur le terrain chaque années. La plupart des données sont rentrées sur une seule feuille nommée Data, qui fait référence à d'autres notamment pour les listes déroulantes.
Sur cette feuille il y a aussi bien des dates, des chiffres, du texte et des formules.

Ce que je souhaiterais faire c'est pouvoir rentrer de nouvelles donnée sur la feuille Data sans avoir accès à celles qui ont été enregistrées plus tôt (que ce soit 5 min ou 2 ans plus tôt) ! Tout ça dans le but d'éviter de supprimer ou modifier des données par inadvertance.

PS : Je sais que je pourrai faire tout ça sous Accès, plus facilement mais le but est d'avoir une application légère (en taille), qui soit facilement modifiable par des personnes qui ne maîtrise pas très bien les fonctions d'Accès mais aussi que tout le monde puisse lire !
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
229
Je ne comprends alors pas pourquoi tout ce tsoin-tsoin.
Si là est vraiment ton seul problème, il te suffit de verrouiller toutes les lignes déjà remplies au dessus de celle en cours, dès que toutes les colonnes à remplir de cette ligne ont été remplies
Je te fais observer l'aspect gênant de ta stratégie de verrouillage automatique. Elle empêche toute correction qui s'avèrerait nécessaire.
Il vaudrait mille fois mieux ne verrouiller que sur commande (macro ad hoc) et avec message de demande de confirmation.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
229
Une autre manière de procéder, si vraiment plus rien ne doit pouvoir ensuite être modifié :
à chaque nouvelle ligne encore vide, repérée par l'absence de constante ===>>> si pas de constantes (les formules n'en sont pas) === verrouiller au-dessus et déverrouiller au dessous
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error Resume Next
If Rows(Target.Row).SpecialCells(xlCellTypeConstants) Is Nothing Then MsgBox "verrouiller jusqu'à la ligne " & Target.Row - 1 & _
" et déverrouiller (au besoin) à partir de " & Target.Row
On Error GoTo 0
End Sub

remplace la msgbox par tes instructions de verrouillage