Figer un caractère dans une cellule
Bonjour à tous,
Voici le sujet qui me pose un problème à ce jour:
En cellule A1je souhaiterais ce qui suit:
1) Seul le caractère X (lettre) soit permis en écriture
2) Si un autre caractère est écrit ce dernier se transforme automatiquemnt en lettre X
3) Si rien n'est écrit alors cellule vide (Logique)
Ceci dit je suis conscient qu'entre ce que je souhaite et ce qui est faisable il peut y avoir un certain décalage 😉
Donc, je remercie d'ores et déjà tous ceux qui pourront m'apporter leur aide que ce soit en positif ou en négatif, car toute explication
serait la cerise sur le gâteau afin de toujours parfaire ses connaissances. 😊
Très bonne soirée a tous
Bonsoir Tiago
Code VBA à mettre dans le module de code de la feuille concernée :
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect([A1], Target) Is Nothing Then If [A1] <> "" Then If [A1] <> "X" Then [A1] = "X"
End SubBonsoir Tiago,
Voici une proposition
Oups, bonsoir mafraise, on se bouscule, pas vu
Bonsoir mafraise, bonsoir Jacky,
Merci à vous deux de votre prompte réponse et surtout de la qualité de la réponse qui fonctionne à merveille.
Je ne voudrais pas abuser de votre temps, mais j'aurais souhaité avoir un déscriptif des lignes afin de ne pas mourir idiot.
Cela bien entendu dès que votre temps vous le permettra et si vous en avez envie.
Si non je vous reitère tous mes remerciments et attends vos réponses afin de cloturer le sujet.
Très bonne fin de soirée
En ce qui concerne ma proposition c'est tout simple
If Range("A1").Value <> "X" Then Range("A1").Value = " "Je regarde ce que contient la cellule A1
S'il s'agit d'un "X" parfait
Sinon on remplace le ou les caractères que cette cellule contient par du vide " "
Re,
Comme c'est demandé gentiment...
1) On vérifie d'abord si la cellule A1 fait partie des cellules qui ont été modifiées.
Pour cela on calcule la plage de l'intersection des cellules qui ont été modifiées (Target) et de la cellule A1. Cela se fait par Intersect([A1], Target)
Si l'intersection est égale à rien (Nothing) c'est que A1 n'a pas été modifiée et on ne poursuit pas le IF... Then
If Not Intersect([A1], Target) Is Nothing Then ...
2) On sait que A1 a été modifiée et on vérifie si A1 est maintenant vide ( A1 <>"" ). Si A1 est vide on ne poursuit pas le IF. Si A1 n'est pas vide on va continuer le IF...
If Not Intersect([A1], Target) Is Nothing Then If [A1] <> "" Then
3) On sait que A1 a été modifié et que A1 n'est pas vide. On va se demander si A1 est différent de "X" ( [A1] <> "X" ). Si A1 est égal à "X", on arrête là le IF. Sinon on met dans A1 la valeur "X".
If Not Intersect([A1], Target) Is Nothing Then If [A1] <> "" Then If [A1] <> "X" Then [A1] = "X"
4) En français cela donne : Si A1 a été modifiée alors si A1 est différent de vide alors si A1 est différent de" X", on met "X" dans A1
Si d'autres explications sont nécessaires, n'hésitez pas me les demander.
...
...
Note importante :
Vous remarquez que si on saisit quelque chose dans A1 différent de vide et "X", on termine la procédure évènementielle en mettant "X" dans la cellule.
En faisant cela, Excel va détecter que la cellule A1 a changé et va ré-exécuter la procédure Worksheet_Change tout en n'étant pas sorti du premier appel à cette procédure. On a un phénomène de récursivité. La procédure s'appelle elle-même (phénomène des poupées russes).
C'est dangereux. Car si ce n'est pas contrôlé on peut très vite saturer la mémoire d'Excel et devoir terminer avec un Ctrl+Alt+Supp pour tuer la tâche Excel.
Comment s'en sortir ?
Par logique (pas toujours possible) : il faut s'assurer qu'à un moment donné une des procédures appelée récursivement se termine normalement et qu'ensuite les appelantes se terminent aussi normalement. Ici :
- on modifie A1
- Worksheet_Change est appelée une première fois
- si A1 est vide, on ne modifie pas A1 et la procédure se termine normalement
- si A1 = "X", on ne modifie pas A1 et la procédure se termine normalement
- Si A1 n'est pas vide, on met "X" dans A1. La cellule A1 est donc modifiée. La procédure Worksheet_Change est appelée une 2° fois à partir de la première. Mais cette fois ci A1 vaut x, donc on ne fait rien et la seconde procédure se termine normalement et redonne la main à la première procédure. La première procédure qui était à la fin de sa série de IF se termine normalement. C'est gagné.
...
Une autre manière de faire est de bloquer l'appel de toutes les procédures évènementielles pendant son exécution :
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' on bloque l'exécution de toutes les procédures évènementielles
Application.EnableEvents = False
' on fait nos petites affaires
If Not Intersect([A1], Target) Is Nothing Then If [A1] <> "" Then If [A1] <> "X" Then [A1] = "X"
' on réactive l'exécution de toutes les procédures évènementielles
Application.EnableEvents = True
End SubTrop cool!!!
Merci pour ces explications claires et précises...
Avoir le résultat c'est vraiment le but recherché, mais comprendre comment cela fonctionne est bien plus intéressant.
Merci à vous deux car cela me permet d'apprendre et de parfaire mes maigres connaissances.
Encore une fois un grand merci et vous souhaite une excellente fin de journée