Besoin d'un magicien pour mon problème^^

Résolu
Signaler
Messages postés
336
Date d'inscription
dimanche 3 avril 2011
Statut
Membre
Dernière intervention
12 juin 2012
-
Messages postés
94
Date d'inscription
vendredi 13 mai 2005
Statut
Membre
Dernière intervention
30 octobre 2011
-
Bonjour à tous, bonjour le Forum

Et bien comme je l'indique sur le titre, j'aurais besoin d'un coup de génie pour réaliser mon besoin.

Voici expliqué ci-après ce que je souhaite faire :

-Prenons 3 cellules simples d'une même feuille Excel. Prenons par exemple les cellules A1, B1, et C1.

-Dans la cellule, A1 je rentre la valeur 10. Il s'agit d'une constante qui est fixe la plus part du temps. Cette valeur correspond à l'erreur que je commet durant un essai.

-Dans la cellule B1, j'entre une valeur au hasard pour le moment : 50. Cette valeur correspond en fait à une lecture de Graph. Je lis un Graph, je récupère une valeur et je note cette valeur dans la cellule B1.

-Enfin dans la cellule C1, je réalise une opération qui est la suivante : C1 (B1-A1). Traduction française, C1 reçoit la valeur que je lis dans le Graph moins l'erreur que je commet de manière globale. C'est une correction que j’effectue la. Donc C1 40.

Jusque la, tout vas bien. J'impose l'erreur que je commet en A1, je note la valeur lue sur mon graph en B1 et enfin je fais la correction en C1.

Maintenant les remarques :

-Si je fixe mon erreur à 0 (en A1) alors B1 = C1. Et dans ce cas la, j'ai une colonne qui ne me sert plus à rien car elle sera doublée.

-Mon objectif est de passer de 3 cellules à UNIQUEMENT 2 cellules !!! Je désire m'affranchir de la cellule B1. En gros je voudrais noter la valeur lue du graphique en C1 ET que la cellule C1 affiche non pas la valeur que je viens de lui entrer MAIS la valeur que je viens d'entrer MOINS la valeur de la cellule A1.

Je ne sais pas si je suis clair ? Prenons un exemple simple :

A1 10. Alors si j'entre la valeur 50 en C1, C1 affiche 50-10. Donc C1 40 bien que j'ai tapé 50 en faisant entrée !

Je ne pense pas que sa sois bien possible, mais je préfère demander avant de me résigner. Et puis rien n'est impossible dis t'on . Si ce que je demande n'est pas directement possible, alors il doit y avoir des alternatives pour contourner le problème. Évidement je ne veux pas de solution qui fasse intervenir 3 cellules car je souhaite m'en affranchir justement^^. Je reste preneur de vos brillantes idées.

Cordialement,

André

PS : Je suis sur Excel 2007, et je demande un code VBA car je souhaite intégrer ceci à ma Macro générale.

16 réponses

Messages postés
336
Date d'inscription
dimanche 3 avril 2011
Statut
Membre
Dernière intervention
12 juin 2012
1
Bien vu GG72 !

Merci pour la correction. Très utile car sa fonctionne mieux en effet.

Voici ci-après les 2 codes qui fonctionnent très bien pour le moment :

Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, [C1]) Is Nothing Then
Application.EnableEvents = False
Target = Target - [A1]
Application.EnableEvents = True
End If
End Sub


Et aussi :

Public flag As Boolean
Private Sub Worksheet_Change(ByVal Target As Range)
If flag Then Exit Sub
If Target.Address = "$C$1" Then
flag = True
Target = Target - [A1]
flag = False
End If
End Sub


Mais malgré tout, ces deux codes on un point en commun qui ne fonctionne pas. Si la valeur en A1 change, alors la nouvelle valeur en C1 ne se met pas automatiquement à jour. Du coup si je change seulement A1, alors le risque de faire n'importe quoi est grand car la valeur en C1 ne se met pas à jour et on ne parlera pas de la même chose au final.

La question qui subsiste est la suivante : Comment faire en sorte que si l'utilisateur change la valeur en A1 alors C1 se mette à jour directement et automatiquement ???

André
Messages postés
94
Date d'inscription
vendredi 13 mai 2005
Statut
Membre
Dernière intervention
30 octobre 2011

Tu peux essayer comme ceci:

Dim X As Integer

Private Sub Worksheet_Change(ByVal Target As Range)
  If Target.Address = "$C$1" Then
    Application.EnableEvents = False
    Range("C1").Value = Range("C1").Value - Range("A1").Value
    Application.EnableEvents = True
  End If
  If Target.Address = "$A$1" Then
    Application.EnableEvents = False
    Range("C1").Value = Range("C1").Value - Range("A1").Value + X
    Application.EnableEvents = True
  End If
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Address = "$A$1" Then
  X = Target.Value
Else
  X = 0
End If
End Sub


Dans mon premier code j'avais fait une erreur dans la valeur à tester pour Target.Address.
Messages postés
14832
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
5 décembre 2021
157
Bonjour,

En regardant un événement Change des Cellules (macro sur feuille de calcul), ensuite, il faudra faire attention aux boucles infinies.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS et aussi ce lien[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
Mon site
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
240
Bonjour,

Bien complexe car il faut éviter que l'on en arrive à la situation d'un chien qui se mord la queue.
L'évènement change n'est certes pas celui à utiliser pour faire cette soustraction, car le résultat de cette dernière provoquerait à nouveau le change, etc .. etc ...
Il ne faut donc l'utiliser que comme tremplin (mémorisation de la cellule modifiée) et utiliser l'évènement selection_change pour faire l'opération !
Voilà le principe . Exemple :
Private anc As Range '====>> absolument indispensable dans la partie générale du code

Private Sub Worksheet_Change(ByVal Target As Range)
  Set anc = Target
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  If Not anc Is Nothing Then
    If anc = Range("C1") Then
      Range("C1").Value = Range("C1").Value - Range("A1").Value
    End If
  End If
End Sub

Commence par cet essai.
Nous tâcherons ensuite de voir quel stratagème mettre en place pour "généraliser" sans trop de douleurs à plusieurs cellules à ainsi modifier !



____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
240
ensuite, il faudra faire attention aux boucles infinies.

Comme on se rejoint, NHenry !


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Messages postés
14832
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
5 décembre 2021
157
Bonjour,

Ou alors avec un verrou, comme une variable static ou attribut pour ne passer qu'une seule fois.

On évite ainsi de faire 2 fonctions :
Private Sub Worksheet_Change(ByVal Target As Range)
    Static lsLock as Boolean
    If Target.Address="C1" And Not lsLock Then
        lsLock =True
        Target.Value=Target.Value- Range("A1").Value
        lsLock =False
    End If
End Sub


---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS et aussi ce lien[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
Mon site
Messages postés
336
Date d'inscription
dimanche 3 avril 2011
Statut
Membre
Dernière intervention
12 juin 2012
1
Bien bien me voila déjà en possession de plusieurs pistes qui me paraissent être bonnes.

Je ne connaissais pas ces procédures événementielles. Je vais tacher d'en apprendre un peu plus sur leur manipulation.

Je fait un retour sur vos idées, dès que j'aurais compris comment les mettre en œuvre.

A très vite.

Merci déjà pour votre soutient !

André

Ps : Ucfoutu commence à bien me connaître. Il s'agit en effet ici d'un simple exemple pour comprendre le principe. La suite étant quelque peu plus complexe mais rien de méchant je pense. Le plus dur étant de faire fonctionner la base.
Messages postés
336
Date d'inscription
dimanche 3 avril 2011
Statut
Membre
Dernière intervention
12 juin 2012
1
Alors voila le premier retour :

-NHenry j'ai testé ton code et malheureusement rien ne s'est passé pour moi. En fait il doit fonctionner, et c'est moi qui n'est pas compris ton code sans doute.

-Ucfoutu, ton code à bien fonctionné pour moi. En effet sa marche assez bien pour un premier essai. Il reste tout de même un souci, à chaque fois que je clique sur une cellule d'Excel la cellule C1 vois son contenu changer. Excel interprète mon "clique" sur une cellule comme étant un ordre pour faire la fameuse soustraction. Du coup ben sa tourne en boucle comme vous le disiez.

Il faudrait essayer de bloquer l'action UNIQUEMENT quand je change la valeur de C1 et pas des autres cellules.

De plus j'ai remarqué également que lorsque je change la valeur de la cellule A1 (représentant mon erreur), et bien la cellule C1 ne se met pas à jour automatiquement. C'est à dire que si A1 change de valeur, alors C1 doit se remettre à jour au niveau de sa soustraction. En gros A1 et C1 doivent être constamment en interaction.

Je ne sais même pas si c'est réalisable ce que je demande. Peut être est-on obligé de passer par une tierce colonne finalement...sniff

Sa ferrait une colonne qui ne me sert strictement à rien. Quand même dommage sa.

Je poursuis mes recherches
Messages postés
94
Date d'inscription
vendredi 13 mai 2005
Statut
Membre
Dernière intervention
30 octobre 2011

Bonjour à tous.

Et en utilisant
Application.EnableEvents 


comme ceci

Private Sub Worksheet_Change(ByVal Target As Range)
  If Target.Address = "C1" Then
    Application.EnableEvents = False
    Range("C1").Value = Range("C1").Value - Range("A1").Value
    Application.EnableEvents = True
  End If
End Sub
Messages postés
336
Date d'inscription
dimanche 3 avril 2011
Statut
Membre
Dernière intervention
12 juin 2012
1
GG72 j'ai utilisé une solution similaire à la tienne qui fonctionne uniquement la première fois. Ensuite elle deviens inutile.

Voici le code :

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, [C1]) Is Nothing Then
        Application.EnableEvents = False
        Target = Target - [A1]
        Application.EnableEvents = False
    End If
End Sub


Avec ton code GG72, je ne parviens même pas à faire réaliser la soustraction une seule fois. Sa dois venir de moi je pense.

André
Messages postés
94
Date d'inscription
vendredi 13 mai 2005
Statut
Membre
Dernière intervention
30 octobre 2011

Normal, il faut remettre Application.EnableEvents à True
et non à False comme tu l'as fait
Messages postés
336
Date d'inscription
dimanche 3 avril 2011
Statut
Membre
Dernière intervention
12 juin 2012
1
GG72 c'est super ce que tu as fait !

Sa marche très bien. Je pensais vraiment pas que l'on pouvait faire ce genre de choses sous Vba. Et bé ! Voila une bonne nouvelle.

Je garde donc ton code GG72 pour la suite. En parlant de suite...

Maintenant que la base du code est posée, j'aimerais l'adapter à mon véritable problème qui est un poil plus complexe que sa.

Voici le contexte :

Je pars d'un classeur Excel qui est vide à la base (une seule feuille vide). La Macro que j'ai mis au point supprime toujours les feuilles et vide la dernière feuille restante de son contenu de manière à partir toujours sur la même base.
Ensuite ma Macro créer diverses feuilles au cours de son cheminement. Une fois arrivé sur la feuille numéro 7, j'obtiens une colonne qui contient des valeurs (c'est l'équivalent de la cellule C1, sauf qu'au lieu d'avoir une cellule on a une plage). C'est sur cette colonne que je vais vouloir faire une soustraction par une autre valeur.
Cette fameuse valeur se trouve sur la feuille numéro 5. Il y a une cellule nommée "Erreur" qui contient une certaine valeur (c'est l'équivalent de la cellule A1. Il s'agit d'une seule cellule).

Ce que moi j'aimerais faire maintenant, c'est insérer dans ma Macro, donc dans mon module et non pas dans ma feuille le code qui va bien. En effet je ne peut pas placer le code de GG72 dans la feuille concernée car elle n'existe pas encore ! Elle se créer au cours de la Macro. Du coup, j'aimerais pouvoir insérer ce bout de code au moment voulu pour que le programme remplace toutes les valeurs de la colonne de la feuille 7 par la différence de la cellule se trouvant dans la feuille 5.
Évidement, j'aimerais que lorsque que je change la valeur de la cellule de la feuille 5, toutes la colonne de la feuille 7 change instantanément. De même lorsque que je rentre une valeur dans la colonne de la feuille 7 et bien cette valeur sois soustraite de la valeur de la feuille 5.

Sa fait un peu brouillons dis comme sa, mais sa reste très simple. Ce n'est rien de plus qu'une petite extension du code qu'a développé GG72.

Sauf que la sa va chercher des valeurs entre plusieurs feuilles, et sur une plage de données au lieux d'une seule cellule.

Est-ce possible d'améliorer le code existant ?

Merci encore.

André
Messages postés
336
Date d'inscription
dimanche 3 avril 2011
Statut
Membre
Dernière intervention
12 juin 2012
1
Grgrgrgr, je ne parviens pas à placer le code dans mon module principal sans passer par une "private sub " liée à une feuille.

Un conseil ?

André
Messages postés
94
Date d'inscription
vendredi 13 mai 2005
Statut
Membre
Dernière intervention
30 octobre 2011

Déjà un petit bug dans mon code:

Si on quitte le classeur alors que la cellule A1 est sélectionnée, et si on modifie cette même cellule dès la réouverture, la cellule C1 ne sera pas modifiée correctement puisque l'ancienne valeur de A1 sera considérée à 0.

Il faudra en tenir compte pour toute évolution.

Je vais étudier ton nouveau problème et reviens vers toi si je trouve la solution (elle existe forcément) à moins qu'un autre membre du forum soit plus rapide.

Bonne continuation.
Messages postés
336
Date d'inscription
dimanche 3 avril 2011
Statut
Membre
Dernière intervention
12 juin 2012
1
Merci GG72

Je poursuis de mon coté aussi alors.
Messages postés
94
Date d'inscription
vendredi 13 mai 2005
Statut
Membre
Dernière intervention
30 octobre 2011

Voici un code vite fait et qui demande certainement quelques améliorations et à adopter suivant tes besoins:

Private Sub Workbook_Open()
  On Error Resume Next
  X = Worksheets("Feuil5").[Erreur].Value
  On Error GoTo 0
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)

Dim Cell As Range
  
  Select Case Sh.Name
    Case "Feuil5"
      If Target.Address = [Erreur].Address Then
        DernLig = Worksheets("Feuil7").Range("C65536").End(xlUp).Row
        Application.EnableEvents = False
        For Each Cell In Worksheets("Feuil7").Range("C1:C" & DernLig)
          Cell.Value = Cell.Value - Worksheets("Feuil5").[Erreur].Value + X
        Next
        Application.EnableEvents = True
      End If
    Case "Feuil7"
    If Not Intersect(Target, [Resultats]) Is Nothing Then
        Application.EnableEvents = False
        Target.Value = Target.Value - Worksheets("Feuil5").[Erreur].Value
        Application.EnableEvents = True
      End If
  End Select

End Sub

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)

  If Sh.Name "Feuil5" And Target.Address Worksheets("Feuil5").[Erreur].Address Then
    X = [Erreur].Value
  End If
  
End Sub


et dans un module:
Public X As Integer