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

SERIEUXETCOOL

XLDnaute Occasionnel
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.
 
Dernière édition:

Fred0o

XLDnaute Barbatruc
Re : Besoin d'un magicien pour mon problème^^

Bonjour SERIEUXETCOOL,

Voici un code qui fait ce que tu demandes an C1 :
VB:
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

Ce code est une procedure évènementielle à mettre dans le code de la feuille concernée.

A+
 

WDAndCo

XLDnaute Impliqué
Re : Besoin d'un magicien pour mon problème^^

Bonjour le Forum et SERIEUXETCOOL

Une piste, dans la colonne A:A la valeur de l'erreur
Puis un UserForm qui demande la valeur du graph en boucle avec X,
puis en B(X) = graph-A(x)

A essayer !

Edit : La réponse de FredOo est plus élégante !
 
Dernière édition:

SERIEUXETCOOL

XLDnaute Occasionnel
Re : Besoin d'un magicien pour mon problème^^

WDandCo merci pour ton aide. Néanmoins je pense que l'aide proposé par FredOo semble plus adapté à mon besoin.

En fait j'ai le sentiment que sa peut répondre parfaitement à mes envies. Mais je ne connaissais pas du tout ces procédures événementielles. Du coup après première essai, sa ne fonctionne pas. Rien ne s'est passé.

Mais sa doit venir de moi. Je vais chercher sur le net le fonctionnement de ces procédures événementielles.

Pour le moment j'ai copié le code Vba dans l'objet "feuil1" qui est la feuille sur laquelle je réalise mes tests. J'ai tapé une valeur en A1 et une autre en C1 mais rien ne s'est passé.

Je m'y prends mal ?
 

SERIEUXETCOOL

XLDnaute Occasionnel
Re : Besoin d'un magicien pour mon problème^^

Merci FredOo pour le fichier Excel.

J'avais finalement mis le code au bon endroit. Et en fait j'ai remarqué ce qui clochait. Ton code ne s'exécute qu'une seule et unique fois.

C'est à dire que je fixe une valeur en A1, et quand j'impose une valeur en C1 alors sa fonctionne. La différence se fait bien.

MAIS

Quand je tape une nouvelle valeur en C1 alors je perds le liens qui lie A1 ET C1.

Ne peut on pas rendre ce lien automatique ? Sinon sa ne m'est pas très utilise car si l'on se trompe en entrant la première valeur...ben on peut plus continuer.

Sa c'est la première remarque. La deuxième étant que si je change la valeur en A1, alors la valeur en C1 ne se change pas de manière automatique. C'est embêtant sa aussi. Car si je fait une erreur de 10 au premier coup, et si je décide de doubler cette erreur, alors la cellule C1 n'y vois que du feu.

Trop dommage sa aussi.

Il y aurait il moyen de résoudre ces 2 remarques ?

Merci déjà pour ton aide FredOo.

André
 

pierrejean

XLDnaute Barbatruc
Re : Besoin d'un magicien pour mon problème^^

Bonjour à tous

FredOo a commis une petite erreur lourde de consequences
2 fois Application.EnableEvents = False au lieu de 1 fois False 1 fois True
Du coup plus aucune evenementielle dans le fichier !!
Il faudra executer recup

Code:
Sub recup()
Application.EnableEvents = True
End Sub


Ensuite je propose (moins risquée) a mettre dans le module concerné


Code:
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
 
Dernière édition:

SERIEUXETCOOL

XLDnaute Occasionnel
Re : Besoin d'un magicien pour mon problème^^

Merci PierreJean 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é
 

Fred0o

XLDnaute Barbatruc
Re : Besoin d'un magicien pour mon problème^^

Re-bonjour SERIEUXETCOOL, Pierrejean.

En effet, honte à moi, je désactive les évènements et je les re-désactive au lieu de les réactiver. Ceci explique que la macro ne s'éxcute qu'une seule fois. Ensuite, voici le code modifié pour réagir à la fois à une modification de C1 et de A1.
VB:
Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, [A1]) Is Nothing Or Not Intersect(Target, [C1]) Is Nothing Then
        Application.EnableEvents = False
        [C1] = [C1] - [A1]
        Application.EnableEvents = True
    End If
End Sub

Malheureusement, si tu fais varier A1, la nouvelle erreur se retranchera de la cellule C1 qui contient une valeur diminuée de l'erreur précédente. Ce qui ne correspond sûrement pas à ce que tu attends.

A+
 

SERIEUXETCOOL

XLDnaute Occasionnel
Re : Besoin d'un magicien pour mon problème^^

En effet FredOo, tu as tout saisis. Ton dernier code fonctionne très bien dans un sens...Mais malheureusement dans l'autre sens sa pêche encore un peu.

Dans ton code par exemple, si je m'amuse simplement à faire varier la cellule A1 plusieurs fois et bien je change complètement la vrai valeur qui sera entrée en C1.

Sa n'a plus de sens.

Comment pourait'on faire ? Moi je pense qu'il faut imposer une condition supplémentaire en A1. C'est à dire que lorsque l'utilisateur change la valeur de A1, alors C1 change en ajoutant automatiquement l'ancienne valeur de A1 pour ratrapper la perte. Je ne sais pas si je suis clair ?

Puisque qu'a chaque fois que je change A1 la valeur se change en C1, alors l'idée c'est de refaire le zéro pour s’affranchir de la perte abusive.

Je vais voir si je trouve pas une petite formule mathématique pour automatiser le lien dans les 2 sens.
 

Fred0o

XLDnaute Barbatruc
Re : Besoin d'un magicien pour mon problème^^

Re bonjour,

J'ai trouvé une solution qui fonctionne. La seule contrainte est de créer un nom de plage nommé "Erreur". Ensuite, la macro gère automatiquement la valeur en lui affectant la valeur de A1. Elle se sert ensuite de cette valeur stocké dans la variable "Erreur" pour refaire des calculs justes de C1.

VB:
Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, [A1]) Is Nothing Or Not Intersect(Target, [C1]) Is Nothing Then
        Application.EnableEvents = False
        [C1] = [C1] - [A1] + [Erreur]
        ActiveWorkbook.Names.Add Name:="Erreur", RefersToR1C1:=[A1].Value
        Application.EnableEvents = True
    End If
End Sub

A+
 

pierrejean

XLDnaute Barbatruc
Re : Besoin d'un magicien pour mon problème^^

Re

Salut fredOo

Une autre solution

Code:
Public flag As Boolean
Public ancienA1
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
    If Target.Address = "$A$1" Then
      flag = True
        Range("C1") = Range("C1") + ancienA1 - Range("A1")
      flag = False
    End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Address = "$A$1" Then
  ancienA1 = Range("A1")
End If
End Sub
 

Si...

XLDnaute Barbatruc
Re : Besoin d'un magicien pour mon problème^^

Salut

même idée que pierrejean mais pas avec la même baguette*
Code:
Dim C As Single
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Address = "$A$1" Then C = [C1]
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
    If Target.Address = "$A$1" Then
      If IsNumeric(Target) Then [C1] = C - [A1] Else [A1] = ""
    End If
    If Target.Address = "$C$1" Then
      If IsNumeric(Target) Then [C1] = [C1] - [A1] Else [C1] = ""
    End If
    Application.EnableEvents = True
End Sub
Comme le souligne pierrejean, en cas d'erreurs (ici, saisies non numériques), Si... on ne gère pas celles-ci, les évènements seront désactivés par "Application.EnableEvents = False". Il faudra alors une autre procédure pour les réactiver.
 

SERIEUXETCOOL

XLDnaute Occasionnel
Re : Besoin d'un magicien pour mon problème^^

PierreJean 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.

FredOo ton code fonctionne mais le fait de devoir créer des choses en plus me gène un peu. La facilité m’obsède plus^^. Mais un grand merci pour ton code. Il est super aussi. Concis et répondant au problème.

Je garde donc ton code PierreJean 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 PierreJean 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é PierreJean.

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é
 

Discussions similaires

Statistiques des forums

Discussions
312 198
Messages
2 086 140
Membres
103 129
dernier inscrit
Atruc81500