Retirer une certaine plage à une plage protégée (modification Range protection)

Résolu
goodweath Messages postés 9 Date d'inscription jeudi 29 janvier 2009 Statut Membre Dernière intervention 6 novembre 2009 - 8 oct. 2009 à 15:41
goodweath Messages postés 9 Date d'inscription jeudi 29 janvier 2009 Statut Membre Derniè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

1 réponse

goodweath Messages postés 9 Date d'inscription jeudi 29 janvier 2009 Statut Membre Derniè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
3