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 :

Surveiller 2 zones différentes


Sujet :

Macros et VBA Excel

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 73
    Par défaut Surveiller 2 zones différentes
    Bonjour,

    J'ai la macro suivante:
    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
    Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Err_SelectionChange
    Dim Plage As Range
    Dim Plage2 As Range
     
    Application.ScreenUpdating = False
    Set Plage = Range("I4:I700")
     
    'Sort de la routine si ce n'est pas une cellule de produit
    If Application.Intersect(ActiveCell, Plage) Is Nothing Then _
             GoTo Sort_SelectionChange
     
    'Vérifie qu'une seule cellule est sélectionnée
    If Target.Count > 1 Then
        MsgBox "Veuillez ne sélectionner qu'une seule cellule"
        GoTo Sort_SelectionChange
    End If
     
    'Lance la macro pour copier le produit choisi
    Call Incorporer_Ventes
     
    Sort_SelectionChange:
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    Exit Sub
    Err_SelectionChange:
    MsgBox Err.Description, vbCritical + vbOKOnly, "ERREUR EXCEL N°" & Err.Number
    Resume Sort_SelectionChange
    End Sub
    Mon problème est le suivant: la macro actuelle surveille bien la zone Range("I4:I700") en lançant la macro "Incorporer_Ventes", mais je n'arrive pas à modifier celle-ci pour quelle me surveille une deuxième zone sur la même feuille, à savoir la zone Range("C4:C700"). Pour résumer je souhaiterais que si le contenu de la première zone change, la macro "Incorporer_Ventes" soit lancée et si le contenu de la deuxième zone change la macro "Incorporer_Ventes2" soit lancée.

    Merci par avance de votre aide.

    NB.: est-il possible de récupérer la valeur de la cellule avant changement, par exemple si le contenu de la cellule est "1" et que je la modifie en "2" j'arrive à récupérer la valeur "2" mais je ne sais pas comment récupére le "1".

    Jarault

  2. #2
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Par défaut
    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
    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Plage As Range
    Dim Plage2 As Range
        'Vérifie qu'une seule cellule est sélectionnée
        If Target.Count > 1 Then
            MsgBox "Veuillez ne sélectionner qu'une seule cellule"
            Exit Sub
        End If
        Set Plage = Range("I4:I700")
        Set Plage2 = Range("C4:C700")
        Application.ScreenUpdating = False
        Application.EnableEvents = False
        'On exécute la routine si c'est pas une cellule de produit
        If Not Application.Intersect(ActiveCell, Plage) Is Nothing Then
            'Lance la macro pour copier le produit choisi
            Call Incorporer_Ventes
           ElseIf Not Application.Intersect(ActiveCell, Plage2) Is Nothing Then
            Incorporer_Ventes2
        End If
        Application.EnableEvents = True
        Application.ScreenUpdating = True
    End Sub
    Si tu as des erreurs, ce sera dans les procédures appelées, tu n'as donc pas à les gérer ici où tu dois les régler autrement qu'avec un on error goto. Ce n'est qu'un conseil.
    Bonne journée

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 73
    Par défaut
    Merci Ouskel'n'or,

    Ton code fonctionne parfaitement.
    Une idée pour récupérer l'ancienne valeur ?
    Jarault

  4. #4
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Par défaut
    Une idée ? Oui mais je ne vais pas avoir le temps d'approfondir. Y fait beau, je pars
    L'idée : Consiste à mémoriser la valeur placée dans la cellule au moment où on entre dans cette cellule.
    Pour ça, tu dois déclarer une variable public.
    Dans SelectionChange, si tu rentres dans la cellule (tu vérifies donc l'adresse qui doit être la bonne ici) tu mémorises la valeur. Tempo = Target (*)
    Mais cet événement se produit quelque soit la cellule sélectionnée. Donc, quelle qu'elle soit, tu vérifies que la valeur dans la cellule à tester est la même que dans la variable Tempo. Si elle est différente, tu fais ce que tu as à faire, et tu mets à jour la variable Tempo. Sinon, tu bouge pas.
    (*) Attention, tu dois mettre à jour Tempo seulement après avoir vérifié le changement.
    Donc, si tu pars d'une cellule vide, le test sera positif pour la première valeur saisie... Donc, tu y penses et si ça pose problème, tu réfléchis mais il y a un moyen avec if tempo = "" then... Tu devrais trouver... J'y vais !
    Bonne journée
    Bon trip
    Bon courage
    M...de ! Le soleil vient de se planquer !
    A+

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 73
    Par défaut
    Je suis d'accord avec toi sur le principe, je venais d'y penser, il ne me reste plus qu'a faire mes premiers essais, on verra çà ce soir. Merci encore

    C'est sans doute la facilité mais si je rajoutais çà:
    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
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim Plage3 As Range
    Set Plage3 = Range("C4:C700")
     
    Application.ScreenUpdating = False
    Application.EnableEvents = False
     
        'On exécute la routine si la cellule sélectionnée se trouve dans la colonne C quantité de produit
        If Not Application.Intersect(ActiveCell, Plage3) Is Nothing Then
            'Copie la valeur de quantité produit avant changement
            ActiveCell.Offset(0, 20) = ActiveCell.Value
        End If
     
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    End Sub
    Après il ne me reste plus qu'a utiliser la valeur de la cellule ActiveCell.Offset(0, 20)
    Jarault

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 364
    Par défaut
    Bonsoir,

    Sans monopoliser une cellule, à tester :
    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
    Dim Original 'Public dans un Module, si utilisée ailleurs que dans cette feuille
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
      If Target.Count > 1 Then Exit Sub
      If Not Application.Intersect(Target, Range("I4:I700,C4:C700")) Is Nothing Then
        Original = Target.Value
      End If
    End Sub
    Private Sub Worksheet_Change(ByVal Target As Range)
        If Target.Count > 1 Then
            MsgBox "Veuillez ne sélectionner qu'une seule cellule"
            Exit Sub
        End If
        Application.EnableEvents = False 'entraîne un changement de sélection
        If Not Application.Intersect(Target, Range("I4:I700,C4:C700")) Is Nothing Then
          If Target.Column = 9 Then
            MsgBox "Vers 1, original = " & Original 'à rétablir : Incorporer_Ventes
          Else
            MsgBox "Vers 2, original = " & Original  'à rétablir : Incorporer_Ventes2
          End If
       End If
       Application.EnableEvents = True
    End Sub

  7. #7
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Par défaut
    Bonsoir à tous,
    Dans mon idée, le test devrait se faire quand la donnée a été changée dans la cellule, donc da Selection_change.
    Citation Envoyé par OrDonc
    Application.EnableEvents = False 'entraîne un changement de sélection
    Non ! Empêche de sélectionner une autre cellule dans la plage "critique" pendant le déroulement d'une macro, ce qui ferait planter le système
    Je regarde le code.

    J'ai besoin d'une précision : Tu veux lancer tes macros si l'une des données de la plage a changé ou si elle n'a pas changé ? cé papa reil...

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 73
    Par défaut
    Citation Envoyé par ouskel'n'or Voir le message
    J'ai besoin d'une précision : Tu veux lancer tes macros si l'une des données de la plage a changé ou si elle n'a pas changé ? cé papa reil...
    Les macros ne doivent être lancées que si la valeur des cellules changent.

  9. #9
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Par défaut
    T'as cru que je t'avais abandonné
    J'ai essayé d'écrire ça et t'ai donné les explications sur les pourquoi des choses
    Le principe est que, quand on entre dans une cellule on ne sait pas si son contenu a changé.
    Si on change le contenu d'une cellule, on ne sait pas s'il sera différent de ce qu'il était avant... avant de sortir de la cellule.
    Donc, si on entre dans une cellule des deux plages intéressantes, on ne mémorise que l'adresse dans Worksheet_Change
    Une fois sorti de cette cellule, si cette cellule était dans l'une des deux plages (range(adres) dans plages) on vérifie que la valeur qu'elle contenait "avant" (truc) a été modifiée. Ceci dans Worksheet_SelectionChange.
    Le reste, je te l'ai mis en commentaires

    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
    Public adres As String, truc
     
    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Plage As Range
    Dim Plage2 As Range
        If Target.Count > 1 Then
            MsgBox "Veuillez ne sélectionner qu'une seule cellule"
            Exit Sub
        End If
        Set Plage = Range("I4:I700")
        Set Plage2 = Range("C4:C700")
        If Not Application.Intersect(Target, Plage) Is Nothing Then
            adres = Target.Address
        End If
    End Sub
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim Plage As Range
    Dim Plage2 As Range
    Dim NewTruc
        'Vérifie qu'une seule cellule est sélectionnée et si adres <> ""
        If Target.Count > 1 Or adres = "" Then Exit Sub
     
        'On change de cellule : Si elle était dans plage ou plage2
        'on mémorise la valeur
        Set Plage = Range("I4:I700")
        Set Plage2 = Range("C4:C700")
        If Not Application.Intersect(Target, Plage, Plage2) Is Nothing Then
            NewTruc = Range(adres).Value
        End If
     
        'Vérifie que l'adres et le contenu de la cellule a changé
        '-> Si la donnée et l'adresse n'ont pas changé, on sort
        'Explication :
        '1 - On est dans la cellule, donc on n'a pas la nouvelle valeur
        '2 - la donnée n'a pas changé, on n'a rien à faire
        If Not (adres <> Target.Address And truc <> Target) Then Exit Sub
     
        'Si les deux ont changé, c'est qu'on est sorti de la cellule et
        'que la donnée a été modifiée. Donc, on traite, où qu'on soit
        Application.ScreenUpdating = False
        Application.EnableEvents = False
     
        'Selon que la cellule qui a changé est de l'une ou l'autre plage
        'on lance la macro correspondante
        If Not Application.Intersect(Range(adres), Plage) Is Nothing Then
            'Lance la macro pour copier le produit choisi
            MsgBox "Donnée = " & truc
            'Incorporer_Ventes
           ElseIf Not Application.Intersect(Range(adres), Plage2) Is Nothing Then
            MsgBox "Donnée = " & truc
            'Incorporer_Ventes2
        End If
     
        'On sait que la valeur a changé, on affecte la nouvelle valeur à truc
        truc = NewTruc 'ou = Range(adres).Value
        'adres ne change pas ici
        Application.EnableEvents = True
        Application.ScreenUpdating = True
    End Sub
    Reste plus qu'à tester. Tu peux faire ça pour moi ?
    J'aurai forcément une ou deux choses aux-quelles je n'aurai pas pensé...
    A+

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 73
    Par défaut
    Merci pour ton aide ouskel'n'or, j'essaye dès que possible et je te tiends au courant.
    N.B.: j'avais cru comprendre que tu ne lachais jamais l'affaire

    Edit: je me rends compte au fur et à mesure de mes post que vous avez beaucoup de mérite car les demandes sont souvent incomplètes en information et cela ne doit pas être facile pour vous de répondre précisement à des questions sans avoir l'intégralité des données qui peuvent rentrer en compte.
    En ce qui me concerne tous mes post en ce moment concerne un logiciel de stock, j'en suis en ce moment à la phase de déstockage automatique (actuellement tout est fait manuellement). Au quotidien je dois faire face à plusieurs problèmes tels que:
    _Le classeur est partagé et mes collègues de travail ont des connaissances plutôt basiques d'excel ce qui signifie que leur intervention se limite à rentrer des chiffres et cliquer sur des boutons.
    _Je suis commercial et je n'ai que de rares moments pour travailler sur ces macros, ce qui explique parfois le manque d'information (je fais souvent plusieurs choses à la fois et le temps me manque pour poser toutes les informations et contraintes), d'ailleurs la pluspart du temps je travaille sur ces macros pendant mon temps personnel.
    _Lorsque je commence une macro j'ai un peu tendance à partir sur une vision parfaite de l'utilisation de celle-ci, mais malheureusement mes collègues me surprendrons toujours dans la façon dont ils utilisent excel, ce qui régulièrement me rajoute des contraintes qu'il faut que j'intègre dans mes macros.

    Enfin bref, tout çà pour dire que vous avez beaucoup de mérite et je souhaiterais vous remercier une fois de plus pour la patience dont vous faites preuve, votre expérience m'est précieuse et me fait économiser beaucoup de temps et surtout elle me permet de rester motivé pour continuer à avancer.

    Jarault

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 73
    Par défaut
    Je suis désolé ouskel'n'or mais je ne m'en sort pas avec ta dernière idée.
    Pour info, voilà ou j'en étais hier sachant que tout avait l'air de fonctionner:
    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
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim Plage3 As Range
    Set Plage3 = Range("C4:C700")
     
    Application.ScreenUpdating = False
    Application.EnableEvents = False
     
        'On exécute la routine si la cellule sélectionnée se trouve dans la colonne C quantité de produit
        If Not Application.Intersect(ActiveCell, Plage3) Is Nothing Then
            'Copie la valeur de quantité produit avant changement
            ActiveCell.Offset(0, 20) = ActiveCell.Value
        End If
     
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    End Sub
    et
    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
    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Plage As Range
    Dim Plage2 As Range
     
    Set Plage = Range("I4:I700")
    Set Plage2 = Range("C4:C700")
        Application.ScreenUpdating = False
        Application.EnableEvents = False
     
        'On lance les routines si on est dans la colonne C ou I
        If Not Application.Intersect(ActiveCell, Plage) Is Nothing Then
            'Si un dépot est choisi ou change lance la macro
            Call Incorporer_Ventes
           ElseIf Not Application.Intersect(ActiveCell, Plage2) Is Nothing Then
            'si la valeur dans la colonne c change lance la macro
            Call Incorporer_Ventes2
        End If
     
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    End Sub
    Cela ne me pose pas vraiment de problème d'utiliser une colonne pour "noter" l'ancienne valeur de la colonne C, sachant que tous les soir j'ai une macro d'impression et de remise à zéro du stock qui en profiterais pour effacer le contenu de cette colonne.

    Penses-tu que j'aurais ultérieurement des problèmes en utilisant cette technique ?

    N.B. Le changement de valeur n'est vraiment important que pour la colonne C.
    Si la cellule de la colonne C était vide rien ne se passe (sauf si un produit est déjà sélectionné dans la colonne E), si la quantité initiale est modifiée alors une macro de mise à jour se lance. Pour la colonne I la macro se lance à partir du moment ou sa valeur change car je part du principe que l'on ne va pas volontairement modifier la cellule pour re-rentrer dans la meme opération la meme valeur.

    Jarault

  12. #12
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 364
    Par défaut
    Bonsoir,

    Codes modifiés pour récupérer le contenu dans une variable, variable utilisable dans le composant de la feuille:
    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
     
    Dim Original, Ancien
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
      If Target.Count > 1 Then Exit Sub
      If Not Application.Intersect(Target, Range("I4:I700,C4:C700")) Is Nothing Then
          Original = Target.Value
      End If
    End Sub
    Private Sub Worksheet_Change(ByVal Target As Range)
        If Target.Count > 1 Then Exit Sub
        If Not Application.Intersect(Target, Range("I4:I700,C4:C700")) Is Nothing Then
          If Target.Column = 9 Then
            MsgBox "Vers 1" 'à rétablir : Incorporer_Ventes
          Else
            MsgBox "Vers 2"  'à rétablir : Incorporer_Ventes2
          End If
       End If
       Ancien = Original
    End Sub
     
    Sub test()
      'Touche Ctrl + g
      MsgBox "Au debut, il y avait ...  " & Ancien
    End Sub
    Fichiers attachés Fichiers attachés

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 73
    Par défaut
    Merci OrDonc, j'essaye çà dès que possible (je crois que je vais être retardé par le match de ce soir ...)

    Ton système à l'air de parfaitement fonctionner, je vais essayer de finaliser çà , si cela marche je poste mon code final dès que possible.

    Jarault

Discussions similaires

  1. saisie simultanée dans deux zones différentes
    Par Ruyneau dans le forum Tkinter
    Réponses: 25
    Dernier message: 16/01/2012, 09h55
  2. Impression de zones différentes sur plusieurs feuilles
    Par Loki83 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 02/12/2008, 09h32
  3. Réponses: 3
    Dernier message: 16/11/2006, 17h06
  4. Faire apparaitre un DIV dans une zone différente
    Par ThomasH dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 23/10/2006, 14h45
  5. Acess2k3: Bande noire sur zone de liste différente
    Par uloaccess dans le forum Access
    Réponses: 5
    Dernier message: 28/10/2005, 17h57

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