Se connecter avec
S'enregistrer | Connectez-vous
Votre question

[vba] Définir un mot de passe variable

Dernière réponse : dans Programmation
Partagez
28 Février 2007 10:16:55

Bonjour à tous,

Je cherche à permettre à l'utilisateur de changer le mot de passe qui verrouille tous les onglets et le menu macro d'un classeur. J'ai donc besoin de demander l'ancien mot de passe afin de le faire changer. Toutefois, tout se passe comme si la variable "mot de passe" n'était pas initialisée et donc le premier test est faux (vérifier que l'ancien mot de passe correspond à celui saisi).

Quelqu'un aurait il une solution pour faire lire à vba les mots de passe qui protègent une feuille ?

D'avance merci.

PS: j'ai essayé de créer un boolean qui renverrait la valeur true si le mot de passe saisi permettait de déverrouiller la feuille, mais ça semble assez instable...

Autres pages sur : vba definir mot passe variable

28 Février 2007 17:47:25

sans code, on sais pas t'aider :o 
1 Mars 2007 08:26:01

C'est pas évident de mettre du code, enfin, il faut considérer que les feuilles du classeurs sont en permanence bloquées. Ainsi, la procédure principale déverrouille et revérouille les feuilles à chaque fois.

  1. For i = 3 To 14
  2. Sheets(i).Select
  3. ActiveSheet.Unprotect Password:="pass"
  4. Next
  5.  
  6. 'mettre un marqueur dans les colonnes appropriées
  7.  
  8. Sheets(ongletfin).Select
  9. For i = colonnedeb To colonnefin Step 2
  10. Cells(ligneut, i).Select
  11. ActiveCell.Value = raison
  12. Next
  13. UserForm1.Hide
  14. For j = 3 To 14
  15. Sheets(j).Select
  16. ActiveSheet.Protect Password:="pass", DrawingObjects:=True, Contents:=True, Scenarios:=True
  17. Next


On voit ici que le mot de passe est "pass". Je souhaiterais remplacer cette constante par une variable, qu'il serait alors possible de faire changer à l'utilisateur. Depuis hier, j'ai un peu avancer, et j'ai trouvé une solution qui me convient moyennement. Il s'agit de stocker le mot de passe dans l'une des feuilles excel et de le faire lire ensuite pour pouvoir le changer. Voila ce que ça donne, le but est désormais de supprimer l'étape feuille de calcul.

  1. Application.ScreenUpdating = False
  2. Sheets(2).Select
  3. Range("e5").Select
  4. code2 = Selection.Value
  5. essai = InputBox("Entrez votre ancien mot de passe", "Changement de mot de passe")
  6. If essai = code2 Then
  7. saisie:
  8. newcode = InputBox("Entrez votre nouveau mot de passe", "Changement de mot de passe")
  9. newcode2 = InputBox("Confirmez votre mot de passe", "changement de mot de passe")
  10. If newcode = newcode2 Then
  11. Sheets(2).Select
  12. Range("e5").Select
  13. Selection.Value = newcode
  14. MsgBox "Votre mot de passe a été changé. Votre nouveau mot de passe est " & newcode & " Conservez le précieusement !", vbOKOnly, "Changement effectué !"
  15. Else
  16. MsgBox " Les deux nouveaux mot de passe sont différents. Essayez à nouveau.", vbCritical, "Erreur"
  17. GoTo saisie
  18.  
  19. End If
  20. Else
  21. MsgBox "Le code est erroné", vbCritical, "Erreur"
  22. Sheets(1).Select
  23. Exit Sub
  24. End If
  25. Sheets(1).Select
  26. Application.ScreenUpdating = True
Contenus similaires
1 Mars 2007 11:20:06

1 Mars 2007 13:35:14

Au temps pour moi, j'ai édité mon post
1 Mars 2007 18:13:45

ca devient si rare les gens qui savent écrire correctement :'( 
2 Mars 2007 08:14:26

Malheureusement, le langage vba m'est plus hermétique...
2 Mars 2007 12:34:18

Le langage VBA t'est plus hermétique et tu l'avoues. Je n'en aurais que plus de plaisir à critiquer ton code. :) 
2 Mars 2007 12:51:01

Alors ça, ça m'énerve :fou: 
  1. Sheets(2).Select
  2. Range("e5" ).Select
  3. code2 = Selection.Value

Ce n'est pas de ta faute, c'est celle de l'enregistreur de macro je suppose.

Si je te dis que la ligne suivante revient au même
code2 = Sheets(2).Range("e5").Value


Deux erreurs dans ton code, la première bégnine, l'utilisation de GOTO :sarcastic:  l'autre plus grave : Ligne 23, tu fais un Exit Sub. La ligne 26 ne sera jamais atteinte :( 

Il faut remplacer le GOTO par une boucle.

Je réécris proprement ton code :
  1. Application.ScreenUpdating = False
  2.  
  3. code2 = Sheets(2).Range("e5").Value
  4. essai = InputBox("Entrez votre ancien mot de passe", "Changement de mot de passe")
  5.  
  6. 'On se débarrasse de ceux qui ne connaissent pas le mot de passe
  7. 'Je ne remets pas le Sheets(1).Select, puisqu'on ne change plus de feuille
  8. If code2 <> essai Then
  9. Application.ScreenUpdating = True
  10. MsgBox "Le code est erroné", vbCritical, "Erreur"
  11. Exit Sub
  12. End If
  13.  
  14. 'Boucle infini
  15. Do While True
  16. newcode = InputBox("Entrez votre nouveau mot de passe", "Changement de mot de passe")
  17. newcode2 = InputBox("Confirmez votre mot de passe", "changement de mot de passe")
  18.  
  19. ' Fin de l'infini :)
  20. If newcode = newcode2 Then Exit Do
  21.  
  22. ' J'ai mis un s à mot, pour faire plaisir à KangOl :D
  23. MsgBox "Les deux nouveaux mots de passe sont différents. Essayez à nouveau.", vbCritical, "Erreur"
  24. Loop
  25.  
  26. Sheets(2).Range("e5").Value = newcode
  27. MsgBox "Votre mot de passe a été changé. Votre nouveau mot de passe est " & newcode & " Conservez le précieusement !", vbOKOnly, "Changement effectué !"
  28.  
  29. Application.ScreenUpdating = True


Qu'en penses-tu ?
Que le problème n'est pas réglé ? J'y viens...
2 Mars 2007 13:07:07

Vérifier le mot de passe d'une feuille :
  1. Function TestMotDePasse(motdepasse As String) As Boolean
  2. ' La feuille est protégée
  3. If Sheets(1).ProtectContents Then
  4. 'On s'apprète à gérer nous même les erreurs
  5. On Error GoTo GESTION_DES_ERREURS
  6. 'Si le mot de passe n'est pas le bon --> Erreur
  7. Sheets(1).Unprotect Password:=motdepasse
  8. 'Sinon, on rend à Excel le soin de gérer les erreurs
  9. On Error GoTo 0
  10. 'On reprotège la feuille
  11. Sheets(1).Protect Password:=motdepasse
  12. TestMotDePasse = True
  13. ' La feuille n'est pas protégée
  14. Else
  15. 'Si Le mot de passe donné est vide, normal, sinon, pas bon.
  16. 'Attention, code sioux !!
  17. TestMotDePasse = motdepasse = ""
  18. End If
  19.  
  20. Exit Function
  21. GESTION_DES_ERREURS:
  22. 'On a le droit d'utiliser les GoTos et les labels pour gérer les erreurs :o
  23. TestMotDePasse = False
  24. End Function
2 Mars 2007 13:14:40

Regarde comme c'est facile :
  1. Application.ScreenUpdating = False
  2.  
  3. essai = InputBox("Entrez votre ancien mot de passe", "Changement de mot de passe")
  4. If TestMotDePasse(essai) Then
  5. Application.ScreenUpdating = True
  6. MsgBox "Le code est erroné", vbCritical, "Erreur"
  7. Exit Sub
  8. End If
  9.  
  10. Do While True
  11. newcode = InputBox("Entrez votre nouveau mot de passe", "Changement de mot de passe")
  12. newcode2 = InputBox("Confirmez votre mot de passe", "changement de mot de passe")
  13. If newcode = newcode2 Then Exit Do
  14. MsgBox "Les deux nouveaux mots de passe sont différents. Essayez à nouveau.", vbCritical, "Erreur"
  15. Loop
  16.  
  17. Sheets(1).Unprotect Password:=essai
  18. Sheets(1).Protect Password:=newcode
  19.  
  20. MsgBox "Votre mot de passe a été changé. Votre nouveau mot de passe est " & newcode & " Conservez le précieusement !", vbOKOnly, "Changement effectué !"
  21. Application.ScreenUpdating = True


Evidemment, tout cela ne marche que pour la feuille 1. A adapter pour la feuille n.
2 Mars 2007 14:41:46

Très bonne idée, merci d'avoir passé du temps la dessus, ça va bien m'aider. Merci aussi d'avoir relevé mes erreurs, je ne m'en était pas rendu compte. Question plus anodine, est ce grave de ne pas avoir application.screenupdating = True ? Cela entraine t il des blocages quelconques ?
Je teste ta solution. Pour généraliser à toutes les feuilles du classeurs, il me suffit de faire une petite boucle, donc pas de soucis.

Encore merci, zeb !
3 Mars 2007 00:13:54

Pourquoi faire Application.ScreenUpdating = False, si tu ne veux pas faire un Application.ScreenUpdating = True à la fin ?
(Interdit de répondre que tu ne sais pas, l'aide existe pour ça :o  )

Et non, pour la boucle, en l'état.
La fonction TestMotDePasse n'est pas paramétrée pour accepter un numéro de feuille. Ligne 3, 7 et 11, il y a une référence à la feuille n°1.

Ce n'est pas impossible, mais il faudrait avec quelque chose comme ça à la place :
  1. Function TestMotDePasse(numerofeuille As Integer, motdepasse As String) As Boolean
  2. .....


Tu as vu comme lâchement, je laisse ce code vide :ange: 
12 Mars 2007 09:33:55

Salut Zeb,

J'ai testé ta solution, ça marche parfaitement. Quand je parlais de boucle, c'était pour changer le mot de passe sur toutes les feuillles, en effet, il s'agit du même mot de passe sur toutes les feuilles. S'il fonctionne pour une, il fonctionne pour toutes.

Toutefois, je me heurte toujours au probleme fondamental, c'est à dire le stockage du mot de passe. En effet, si je peux aisément changer le mot de passe, je ne peux pas utiliser ce mot de passe quand l'utilisateur ne l'a pas renseigné et c'est bien la tout mon probleme.

Le but est que l'administrateur du fichier puisse changer le mot de passe s'il le souhaite mais le reste des macros doit pouvoir écrire dans les pages et donc déverouiller les pages pour écrire dedans quand les utilisateurs l'utilisent. Et ces utilisateurs ne connaissent pas le mot de passe administrateur.

La seule solution, à mon sens, serait une macro qui permette d'écrire dans le reste du module et qui aille remplacer le mot de passe dans chacun des morceaux de code (on peut aussi envisager que je regroupe cela dans un seul sub qui servirait à déverrouiller / reverrouiller les pages.) J'ai beau chercher dans l'aide et sur d'autres forums (google est mon ami, je le sais), je ne trouve pas de solution.

Quand au screenupdating, ma question venait du fait que je ne constate pas de bug quand on "oublie" de le réactiver...

Merci de ton aide dans tous les cas, j'apprends beaucoup à ton contact.
12 Mars 2007 11:15:20

Il n'est heureusement pas possible de lire les mots de passe. On ne peut que saisir un mot de passe pour déverouiller la feuille et vérifier que cela c'est bien passé.

Les macros ne peuvent pas s'auto-écrire.
EDIT: Les macros peuvent s'auto-écrire. :o 
12 Mars 2007 12:17:08

Si ça peut t'intéresser, au cours de mes périgrinations, j'ai trouvé ça.

  1. Sub RemplacementMotDansProcedure()
  2. 'Nécéssite d'activer la référence
  3. '"Visual basic For Application Extensibility 5.3"
  4. '
  5. Dim Ancien As String, Nouveau As String, Cible As String
  6. Dim VBComp As VBComponent
  7. Dim i As Integer
  8. Dim Wb As Workbook
  9.  
  10. Set Wb = Workbooks("NomClasseur.xls")
  11.  
  12. Ancien = "Feuil1"
  13. Nouveau = "Feuil3"
  14.  
  15. For Each VBComp In Wb.VBProject.VBComponents
  16. For i = 1 To VBComp.CodeModule.CountOfLines
  17. Cible = VBComp.CodeModule.Lines(i, 1)
  18. Cible = Replace(Cible, Ancien, Nouveau)
  19. VBComp.CodeModule.ReplaceLine i, Cible
  20. Next i
  21. Next VBComp
  22. End Sub


Je vais essayer de définir mon mot de passe par une variable qui serait initialiser avec le mot de passe, mot de passe qui serait modifier par cette procédure lors des changements de mot de passe. Mauvaise idée à ton avis, problème de stabilité peut être...
12 Mars 2007 13:31:16

Whaou.... C'est chiadé !
Je regarde ça de plus près
13 Mars 2007 08:44:40

Je ne trouve pas la référence Visual basic for application extensibility 5.3. Tu la trouves toi ? Sinon, c'est peut être juste une mauvaise blague...
13 Mars 2007 10:41:53

Moi non plus, ça marche sans.
Bon à part ça, le code proposé n'est pas beau du tout. Je t'en refais un :) 
...
13 Mars 2007 10:53:03

La référence s'appelle "Visual Basic For Applications Extensibility" ou "Microsoft Visual Basic For Applications Extensibility 5.3" selon les versions d'Excel