IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

worksheet_change seulement lors d'une suppression [XL-2019]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Janvier 2020
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Janvier 2020
    Messages : 129
    Par défaut worksheet_change seulement lors d'une suppression
    Bonjour à tous gens du Forum
    Voici le sujet de mes réflexions.
    Je souhaite interdire la suppression de certaines lignes de mon fichier. La position de celles ci peut varier ua gré des insertions/suppressions de lignes. Pour les repérer j'ai mis du texte dans les cellule A.

    J'ai codé ça, dans le code du worksheet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Private Sub Worksheet_Change(ByVal Target As Range)
     
    If Target.Address = Target.EntireRow.Address Then  'And Cells(ActiveCell.Row, 1).Value <> ""   si toute la ligne sélectionnée et cellule A non vide
       Application.EnableEvents = False 'excel ne détecte plus les nouveaux évènements
       MsgBox "Suppression de ligne interdite."
       Application.Undo
       Application.EnableEvents = True
    End If
    MsgBox ("ok")
    End Sub
    la condition cells.value<>"" est en commentaire pour l'instant : une chose à la fois.
    Grace au message "OK", je sais que je rentre bien dans le macro à chaque fois que j'ajoute/supprime du texte dans une cellule.
    Dès que je sélectionne une ligne complète, que j'insère ou que je supprime, j'ai le message "suppression interdite".
    Je n'arrive pas à trouver la condition qui interdira seulement la suppression, et pas l'insertion.
    Mais peut être que worksheet_change n'est pas la bonne fonction....
    J'ai regardé du côté de before_delete, mais ça ne semble fonctionner que pour la suppression de la feuille.

    Quelqu'un aurait'il la solution? Une piste
    Cordialement
    Benoit

  2. #2
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    13 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13 176
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Lorsque l'on protège une feuille, il est possible d'autoriser l'insertion de ligne mais pas la suppression.
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Janvier 2020
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Janvier 2020
    Messages : 129
    Par défaut
    Bonjour,
    Je regardé de ce côté là, mais je ne veux pas interdire toute suppression de ligne, mais uniquement la suppression de certaines : celles qui ont du texte en colonne A.
    y'aurait-il une condition "si l'action demandée est suppression"?

    Merci pour ce retour

  4. #4
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    13 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13 176
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    y'aurait-il une condition "si l'action demandée est suppression"?
    Pas que je sache.
    Pour gérer cela par programmation, je crains que cela devienne rapidement une usine à gaz et je ne vois pas comment empêcher la suppression d'une ligne.
    On ne pourrait que la constater.
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Janvier 2020
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Janvier 2020
    Messages : 129
    Par défaut
    Gasp...ça sent le roussi...

    Je ne sais pas si ça pourrait aider, mais avec ce code (pompé sur doc.microsoft.com) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, _ 
     Cancel As Boolean) 
     Dim icbc As Object 
     For Each icbc In Application.CommandBars("cell").Controls 
     If icbc.Tag = "brccm" Then icbc.Delete 
     Next icbc 
     If Not Application.Intersect(Target, Range("b1:b10")) _ 
     Is Nothing Then 
     With Application.CommandBars("cell").Controls _ 
     .Add(Type:=msoControlButton, before:=6, _ 
     temporary:=True) 
     .Caption = "New Context Menu Item" 
     .OnAction = "MyMacro" 
     .Tag = "brccm" 
     End With 
     End If 
    End Sub
    Comme pour supprimer ma ligne, je dois faire un clic droit, je me dis qu'il y a peut être une piste.

    Ce code doit "ajouter un nouvel élément au menu contextuel pour les cellules B1:B10." dixit le site.
    Si on peut ajouter un élément au menu, ne pourrait-on pas en masquer un (la fonction "supprimer" en l’occurrence) ou le rentre inactif?
    Et seulement si les conditions (sélection ligne complète ET case A non vide) sont remplies.

    Bonne ou mauvaise idée?

    Il n'y aura pas de message d'alerte...je m'en contenterais.
    Il y a d'autre méthodes que clic droit pour supprimer une ligne, mais celle ci est la plus courante. Je prends le risque qu'un petit malin puisse supprimer une ligne par un autre biais.

    Merci

  6. #6
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    très complexe ce que vous nous demandez là.
    Il existe plusieurs manières de "détruire" des données.

    Si c'est juste pour éviter des "négligences", le code ci-dessous vous aidera.
    Par contre, il ne peux rien contre des êtres diaboliques et malveillants***.

    Un simple copié/collé d'une ligne vide sur une ligne de données suffit à contourner mon code.
    Dans ce cas, il est également possible d'intercepter le "Coller" (je vous l'ai mis dans le code), mais comment le traiter ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim C As String, I As Long
        If Target.Row > 1 And Target.Row < 10 Then    'EMPÊCHE LA SUPPRESSION DES LIGNES 2 à 9
            'on vérifie dans la barre d'outils
            With Application.CommandBars("Standard")
                'recherche de la liste de Undo
                I = .FindControl(ID:=128).Index
                'la dernière action qu'il est possible d'annuler
                C = .Controls(I).List(1)
            End With
            's'il s'agit d'un "Supprimer" ou Effacer (obtenu en faisant Ctrl+X puis Suppr) ==> on annule grâce à Undo
            If C = "Supprimer" Or C = "Effacer" Then
                'on annule
                With Application
                    'on désactive les événements sinon le Undo va déclencher à nouveau Worksheet_Change
                    .EnableEvents = False
                    .Undo
                    'réactivation des événements
                    .EnableEvents = True
                End With
            ElseIf C = "Coller" Then 
    '????????????
            End If
        End If
    End Sub
    Le plus simple est de protéger le classeur...

    Attention aussi à la désactivation des événements.
    Si, pour une raison ou une autre le code plante avant la réactivation (ici je ne vois pas de raison, mais...), les événements resteront inactifs jusqu'à la prochaine ouverture du classeur.

    EDIT :
    ***
    Le simple lancement de ce code va, non seulement effacer la seconde ligne, mais en plus faire un joli bug dans la macro événementielle Worksheet_Change() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Sub Macro1()
        Rows("2:2").Delete Shift:=xlUp
    End Sub
    Si tu penses qu'un utilisateur en est capable, il te faudra gérer l'erreur avant C = .Controls(I).List(1)

    Un code un peu plus compliqué à contourner serait celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim C As String, I As Long
        If Target.Row > 1 And Target.Row < 10 Then    'EMPÊCHE LA SUPPRESSION DES LIGNES 2 à 9
            'on vérifie dans la barre d'outils
            With Application.CommandBars("Standard")
                'recherche de la liste de Undo
                I = .FindControl(ID:=128).Index
                'Si suppression par macro, la ligne C = .Controls(I).List(1) va créer une erreur
                'En effet, tout déclenchement de macro vide la liste de Undo
                On Error GoTo Exception 'FERME LE CLASSEUR SANS ENREGISTRER
                'la dernière action qu'il est possible d'annuler
                C = .Controls(I).List(1)
                On Error GoTo 0
            End With
            's'il s'agit d'un "Supprimer" ou Effacer (obtenu en faisant Ctrl+X puis Suppr) ==> on annule grâce à Undo
            If C = "Supprimer" Or C = "Effacer" Then
                'on annule
                With Application
                    'on désactive les événements sinon le Undo va déclencher à nouveau Worksheet_Change
                    .EnableEvents = False
                    .Undo
                    'réactivation des événements
                    .EnableEvents = True
                End With
            ElseIf C = "Coller" Then
                GoTo Exception 'FERME LE CLASSEUR SANS ENREGISTRER
            End If
        End If
        Exit Sub
    Exception:
        MsgBox "Manipulation interdite", vbCritical + vbOKOnly, "EJECTION"
        ThisWorkbook.Close False
    End Sub
    Il empêche également la suppression via une macro en "éjectant" l'utilisateur (fermeture du classeur violente, sans enregistrement)...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Message d'erreur inattendue lors d'une suppression
    Par Just-Soft dans le forum Bases de données
    Réponses: 8
    Dernier message: 18/11/2008, 11h42
  2. Réponses: 3
    Dernier message: 13/04/2008, 02h40
  3. [JDOM] Problème d'iterateur lors d'une suppression
    Par romuluslepunk dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 07/01/2006, 15h00
  4. Probleme lors d'une suppression
    Par DrTank dans le forum Langage SQL
    Réponses: 5
    Dernier message: 21/04/2005, 17h38
  5. Combler les trous lors d'une suppression dans une table
    Par Billybongjoe dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 08/04/2004, 14h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo