goodweath
Messages postés9Date d'inscriptionjeudi 29 janvier 2009StatutMembreDernière intervention 6 novembre 2009
-
8 oct. 2009 à 15:41
goodweath
Messages postés9Date d'inscriptionjeudi 29 janvier 2009StatutMembreDernière intervention 6 novembre 2009
-
20 oct. 2009 à 22:38
Bonjour,
Je suis en train de mettre en place un système de protection conditionnelle dans une feuille Excel 2003.
En gros, si un vérificateur appose ses initiales dans une colonne appropriée, il bloque la ligne correspondante : une plage avec un mot de passe est créée et agrandie à chaque ligne vérifiée, et cette même plage est retirée de la zone autorisée de TOUS les utilisateurs (sinon ils y ont toujours accès).
Inversement, si le vérificateur retire ses initiales, la ligne est déprotégée pour pouvoir faire des modifs.
J'ai réussi à coder l'agrandissement de la plage protégée contre tous les utilisateurs avec Union et en récupérant la plage protégée initiale.
Problème : je ne sais pas faire l'inverse, çàd enlever un morceau de plage à la plage protégée (Plage_Complete = Plage_Complete - Plage_A_Enlever). La Plage_A_Enlever peut se trouver en plein milieu de la Plage_Complete.
De même, est-il possible d'enlever Plage_A_Enlever à TOUS les utilisateurs autorisés d'UN SEUL coup ??
J'ai mis en bas un morceau de mon code : la variable Plage_A_Enlever ci-dessus est Plage_Supp dans mon code car je peux l'utiliser pour agrandir ou réduire mes plages selon les cas.
Merci d'avance pour vos idées!
GoodWeath'
Option Explicit
' Déclaration valable pour l'ensemble des subs de la feuille
Dim memo As String
Private Sub Worksheet_Change(ByVal target As Range)
Dim j As Long
Dim Plage_Supp As Range 'Plage supplémentaire à protéger après écriture des initiales dans une ligne
Dim Plage_Complete As Range 'Plage totale de lignes protégées
j = 1 'Compteur de colonnes
Do While Cells(1, j) <> "Vérificateur"
j = j + 1
Loop
If target.Column = j Then
'Opérations à réaliser si on RENSEIGNE une cellule initialement vide de la colonne Vérificateur
If memo = vbNullString And target.Value <> vbNullString Then
'Définition de la plage supplémentaire à protéger après écriture des initiales dans une ligne
Set Plage_Supp = Range(Cells(target.Row, j - 3), Cells(target.Row, j - 1))
'Déprotection de la feuille pour définir une nouvelle zone protégée
ActiveSheet.Unprotect Password:="jb"
'Récupération de l'adresse de la plage protégée jusque là
Set Plage_Complete = ActiveSheet.Protection.AllowEditRanges.Item("Ligne3").Range
'Agrandissement de la plage à protéger si besoin (pas si Plage_Supp déjà contenue dans Plage_Complete)
If Intersect(Plage_Supp, Plage_Complete) Is Nothing Then
'Union des 2 plages
Set Plage_Complete = Union(Plage_Complete, Plage_Supp)
End If
'Renvoi de la plage complète dans l'objet à protéger
Set ActiveSheet.Protection.AllowEditRanges.Item("Ligne3").Range = Plage_Complete
'Reprotection de la feuille
ActiveSheet.Protect Password:="jb", ...
'Opérations à réaliser si on VIDE une cellule de la colonne Vérificateur
ElseIf memo <> vbNullString And target.Value = vbNullString Then
'Retrait de la protection de la ligne correspondante
'--> Plage_Complete = Plage_Complete - Plage_Supp
End If
End If
End Sub
Private Sub worksheet_selectionchange(ByVal target As Range)
'Retient le contenu de la cellule
memo = target.Value
End Sub
A voir également:
Retirer une certaine plage à une plage protégée (modification Range protection)
goodweath
Messages postés9Date d'inscriptionjeudi 29 janvier 2009StatutMembreDernière intervention 6 novembre 2009 20 oct. 2009 à 22:38
Bon finalement, j'ai fini par trouver : il n'y a pas de solution directe, mais une méthode permet de reconstituer la plage réduite en retirant l'intersection à la plage de départ.
Par contre, cette méthode prend un peu de temps si la plage de départ est étendue : plusieurs minutes sur toute la feuille!!
Si quelqu'un a une idée pour faire mieux que cellule par cellule, je suis preneur (je vais regarder pour le faire ligne par ligne)!
Code à mettre au niveau de '--> plage_complete = plage_complete - plage_supp à la fin du code précédent :
'Réduction de la plage à protéger
For Each Cellule In Plage_Complete
If Intersect(Cellule, Plage_Supp) Is Nothing Then
'Plage_Resultat est d'abord vide puis se reconstruit cellule par cellule
If Plage_Resultat Is Nothing Then
Set Plage_Resultat = Cellule
Else
Set Plage_Resultat = Union(Plage_Resultat, Cellule)
End If
End If
Next Cellule
Set ActiveSheet.Protection.AllowEditRanges.Item("Ligne3").Range = Plage_Resultat