[vba] Définir un mot de passe variable

Brizweb

Nouveau membre
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...
 

Brizweb

Nouveau membre
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.

[cpp]For i = 3 To 14
Sheets(i).Select
ActiveSheet.Unprotect Password:="pass"
Next

'mettre un marqueur dans les colonnes appropriées

Sheets(ongletfin).Select
For i = colonnedeb To colonnefin Step 2
Cells(ligneut, i).Select
ActiveCell.Value = raison
Next
UserForm1.Hide
For j = 3 To 14
Sheets(j).Select
ActiveSheet.Protect Password:="pass", DrawingObjects:=True, Contents:=True, Scenarios:=True
Next[/cpp]

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.

[cpp]Application.ScreenUpdating = False
Sheets(2).Select
Range("e5").Select
code2 = Selection.Value
essai = InputBox("Entrez votre ancien mot de passe", "Changement de mot de passe")
If essai = code2 Then
saisie:
newcode = InputBox("Entrez votre nouveau mot de passe", "Changement de mot de passe")
newcode2 = InputBox("Confirmez votre mot de passe", "changement de mot de passe")
If newcode = newcode2 Then
Sheets(2).Select
Range("e5").Select
Selection.Value = newcode
MsgBox "Votre mot de passe a été changé. Votre nouveau mot de passe est " & newcode & " Conservez le précieusement !", vbOKOnly, "Changement effectué !"
Else
MsgBox " Les deux nouveaux mot de passe sont différents. Essayez à nouveau.", vbCritical, "Erreur"
GoTo saisie

End If
Else
MsgBox "Le code est erroné", vbCritical, "Erreur"
Sheets(1).Select
Exit Sub
End If
Sheets(1).Select
Application.ScreenUpdating = True[/cpp]
 

KangOl

Grand Maître
ca devient si rare les gens qui savent écrire correctement :'(
 

zeb

Modérateur
Le langage VBA t'est plus hermétique et tu l'avoues. Je n'en aurais que plus de plaisir à critiquer ton code. :)
 

zeb

Modérateur
Alors ça, ça m'énerve :fou:
Code:
Sheets(2).Select
Range("e5" ).Select
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[fixed]code2 = Sheets(2).Range("e5").Value[/fixed]

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 :
Code:
Application.ScreenUpdating = False

code2 = Sheets(2).Range("e5").Value
essai = InputBox("Entrez votre ancien mot de passe", "Changement de mot de passe")

'On se débarrasse de ceux qui ne connaissent pas le mot de passe
'Je ne remets pas le Sheets(1).Select, puisqu'on ne change plus de feuille
If code2 <> essai Then
    Application.ScreenUpdating = True
    MsgBox "Le code est erroné", vbCritical, "Erreur"
    Exit Sub
End If

'Boucle infini
Do While True
    newcode = InputBox("Entrez votre nouveau mot de passe", "Changement de mot de passe")
    newcode2 = InputBox("Confirmez votre mot de passe", "changement de mot de passe")
    
    ' Fin de l'infini :)
    If newcode = newcode2 Then Exit Do
    
    ' J'ai mis un s à mot, pour faire plaisir à KangOl :D
    MsgBox "Les deux nouveaux mots de passe sont différents. Essayez à nouveau.", vbCritical, "Erreur"
Loop

Sheets(2).Range("e5").Value = newcode
MsgBox "Votre mot de passe a été changé. Votre nouveau mot de passe est " & newcode & "  Conservez le précieusement !", vbOKOnly, "Changement effectué !"

Application.ScreenUpdating = True

Qu'en penses-tu ?
Que le problème n'est pas réglé ? J'y viens...
 

zeb

Modérateur
Vérifier le mot de passe d'une feuille :
Code:
Function TestMotDePasse(motdepasse As String) As Boolean
    ' La feuille est protégée
    If Sheets(1).ProtectContents Then
        'On s'apprète à gérer nous même les erreurs
        On Error GoTo GESTION_DES_ERREURS
        'Si le mot de passe n'est pas le bon --> Erreur
        Sheets(1).Unprotect Password:=motdepasse
        'Sinon, on rend à Excel le soin de gérer les erreurs
        On Error GoTo 0
        'On reprotège la feuille
        Sheets(1).Protect Password:=motdepasse
        TestMotDePasse = True
    ' La feuille n'est pas protégée
    Else
        'Si Le mot de passe donné est vide, normal, sinon, pas bon.
        'Attention, code sioux !!
        TestMotDePasse = motdepasse = ""
    End If
    
Exit Function
GESTION_DES_ERREURS:
    'On a le droit d'utiliser les GoTos et les labels pour gérer les erreurs :o
    TestMotDePasse = False
End Function
 

zeb

Modérateur
Regarde comme c'est facile :
Code:
Application.ScreenUpdating = False

essai = InputBox("Entrez votre ancien mot de passe", "Changement de mot de passe")
If TestMotDePasse(essai) Then
    Application.ScreenUpdating = True
    MsgBox "Le code est erroné", vbCritical, "Erreur"
    Exit Sub
End If

Do While True
    newcode = InputBox("Entrez votre nouveau mot de passe", "Changement de mot de passe")
    newcode2 = InputBox("Confirmez votre mot de passe", "changement de mot de passe")
    If newcode = newcode2 Then Exit Do
    MsgBox "Les deux nouveaux mots de passe sont différents. Essayez à nouveau.", vbCritical, "Erreur"
Loop

Sheets(1).Unprotect Password:=essai
Sheets(1).Protect Password:=newcode

MsgBox "Votre mot de passe a été changé. Votre nouveau mot de passe est " & newcode & "  Conservez le précieusement !", vbOKOnly, "Changement effectué !"
Application.ScreenUpdating = True

Evidemment, tout cela ne marche que pour la feuille 1. A adapter pour la feuille n.
 

Brizweb

Nouveau membre
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 !
 

zeb

Modérateur
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 :
Code:
Function TestMotDePasse(numerofeuille As Integer, motdepasse As String) As Boolean
.....

Tu as vu comme lâchement, je laisse ce code vide :ange:
 

Brizweb

Nouveau membre
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.
 

zeb

Modérateur
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é.

[strike]Les macros ne peuvent pas s'auto-écrire.[/strike]
EDIT: Les macros peuvent s'auto-écrire. :o
 

Brizweb

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

[cpp]Sub RemplacementMotDansProcedure()
'Nécéssite d'activer la référence
'"Visual basic For Application Extensibility 5.3"
'
Dim Ancien As String, Nouveau As String, Cible As String
Dim VBComp As VBComponent
Dim i As Integer
Dim Wb As Workbook

Set Wb = Workbooks("NomClasseur.xls")

Ancien = "Feuil1"
Nouveau = "Feuil3"

For Each VBComp In Wb.VBProject.VBComponents
For i = 1 To VBComp.CodeModule.CountOfLines
Cible = VBComp.CodeModule.Lines(i, 1)
Cible = Replace(Cible, Ancien, Nouveau)
VBComp.CodeModule.ReplaceLine i, Cible
Next i
Next VBComp
End Sub[/cpp]

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...
 

Brizweb

Nouveau membre
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...
 

zeb

Modérateur
[strike]Moi non plus, ça marche sans.[/strike]
Bon à part ça, le code proposé n'est pas beau du tout. Je t'en refais un :)
...
 

zeb

Modérateur
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
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 098
Messages
6 717 057
Membres
1 586 284
Dernier membre
fjfkfjfkfjfjcj
Partager cette page
Haut