| Bonjour,
En supposant que la colonne A constitue un index dans la feuille
et que la colonne B contitue la colonne avec la valeur variable à initiliser à "NON" ou a rien !
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Region As Range, Position As Long
Application.ScreenUpdating = False
Position = Range("A1:A65535").End(xlDown).Row
Set Region = Application.Intersect(Range("B1:B" & Position), Target)
If Region Is Nothing Then
'MsgBox "La cible n'est pas dans la plage visé."
Else
If (Target.Value = "NON") Then
Target.EntireRow.Select
Selection.Interior.ColorIndex = 6
'MsgBox "La cible est dans la plage visé."
Target.Offset(1, 0).Select
End If
End If
Application.ScreenUpdating = True
End Sub
'
Il vous faudra adapter !
Lupin Répondre à Lupin.A | Bonjour Lupin,
je m'inspire de ton code pour une de mes applications.
Mais le problème, c'est que cela fonctionne quand on quitte une cellule de la colonne B, et pas sans partir de la cellule.
Pour être plus claire, dans mon cas, je voudrais que quand le user écrit quelquechose en colonne B, un userform s'affiche avec une zone de texte. Il complète la zone de texte qui doit agrémenter la colonne C, soit un ActiveCell.Offset(0,1).Select.
Mais si par exemple il saisie en cellule B2, si en quittant la cellule, il utilise la flèche du haut, il est en B1, le userform s'affiche, il saisie son blabla, ActiveCell.Offset(0,1) --> le texte s'affiche en C1, alors que je le voulais en C2. S'il quitte la cellule B2 en utilisant la flèche du bas, après userform, le texte va arriver en C3...
Or je ne peux pas dans mon code VB lui dire "va dans C2", car ce code doit fonctionner pour toute la colonne B (et accesoirement pour les colonnes E, H...).
Alors je me suis dit que j'allais faire une recherche dans la colonne C, et que s'il y avait un nombre dans la colonne B et rien sur la même ligne dans la colonne C, alors c'est ici que le texte doit aller (car je vais interdire une saisie dans B sans blabla dans la colonne C). Ben oui, mais s'il utilise les flèches de gauche ou de droite quand il quitte B2, comment va-t-il deviner dans quelle colonne chercher?
Bref, y-a-t-il une solution? Ai-je un esprit trop tordu?
Merci Répondre à Ludivine50 | Bonjour Ludivine,
Alors voici une solution possible :
Dans un module standard, il te faut déclarer un variable globale
à ton projet de cette façon :
Option Explicit
Public strAdresse As String
voici le code de détection du changement, légèrement modifié :
Option Explicit
'
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Region As Range, Position As Long
Application.ScreenUpdating = False
Application.EnableEvents = False
' Capture de l'adresse du changement
strAdresse = Target.Address
Position = Range("A1:A65535").End(xlDown).Row
Set Region = Application.Intersect(Range("B1:B" & Position), Target)
If Not (Region Is Nothing) Then
uf_Saisie.Show
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
'
et le code qui devra être placé derrière un bouton de validation
de ton [ UserForm ]
Private Sub cmd_Xfr_Click()
With ActiveSheet
.Range(strAdresse).Offset(0, 1).Value = Me.tbx_Valeur.Text
End With
End Sub
'
Voilà, j'espère avoir bien compris ton dilème !
Lupin Répondre à Lupin.A | Merci Lupin, je pense que ça doit répondre à ma problématique, le code est intéressant. Malheureusement, je n'arrive pas à tester car il ne fait rien, rien de rien du tout. Même pas ouvrir mon userform (dont j'ai bien changé le nom). Répondre à Ludivine50 | Re:
Il te faudra faire attention ici, car les évènements sont désactivés par la ligne :
Application.EnableEvents = False
Si la routine ne s'exécute pas jusqu'a la fin -> Application.EnableEvents = True
Il n'y auras plus d'évènement [ Worksheet_Change ]
Dans un module standard, place cette routine :
Sub ActiveEvenement()
Application.EnableEvents = True
End Sub
Tu pourras ainsi réactiver les évènements du classeur.
De plus cette routine s'accroche sur la colonne A pour déterminer
la plage à surveiller en colonne B, avais-tu compris cette approche ?
Connais tu les points d'arrêts ?, le mode "pas à pas" ?
Lupin Répondre à Lupin.A | Merci Lupin de ta réponse.
C'était effectivement le fait qu'après un premier plantage, il était resté en
Application.EnableEvents = False.
Je voulais justement te demander par la suite que voulait dire cette commande, ben du coup, c'est déjà fait ;-)
Et à propos, en me renseignant, j'ai découvert que Application.ScreenUpdating = False permet une exécution plus rapide... Dans un fichier j'avais une macro qui durait 20 secondes (pour 100 lignes!), et après ajout de ce code, ben ça dure 0,002 secondes!!!! Lupin, je t'adore!!!!!!!!!
Concernant la notion d'index, j'ai compris que s'il y a quelquechose dans la colonne A et quelquechose dans la colonne B, alors il doit afficher mon userform, ce qui évite qu'il mouline à chercher dans toute la feuille. Dans mon cas, je n'aurais pas vraiment ce fonctionnement, car le nombre de ligne n'est pas infini. Je lui demanderais probablement d'arrêter le traitement à une ligne précise. Mais j'hésite, pourquoi pas une colonne genre index. Il devra chercher dans la ligne 10, puis 11, puis 13, 14, 16, 19..... Mais bon, est-ce plus long de chercher dans 50 lignes, que dans 20 lignes? Je ne pense pas (surtout depuis que j'ai découvert Application.ScreenUpdating = False).
Pour les points d'arrêts et le mode pas à pas, je viens de me renseigner sur ces forums (et je suis tombée sur un de tes messages ;-) ). Je ne m'étais jamais renseignée du pourquoi il y a des gros points marrons quand je clique sur la gauche! !-))))) Excellente découverte! Je vais m'en servir!
Bref, je vais m'endormir moins bête ce soir! (et c'est toujours cela de gagné)
Bonne soirée SUPERLupin, merci pour tout! Répondre à Ludivine50 | Bonjour Ludivine,
Ton enthousiasme de la découverte fait plaisir à voir et tu as effectivement la chance d'avoir un "SUPERLupin" (sic) pour t'aider : profites en bien (c'est en bonne voie !) car tout est bon dans ce qu'il va te donner comme conseils.
PS : un grand bonjour à mon ami Lupin.A avec toute sa pédagogie méthodique.
Toujours zen Répondre à gbinforme |
| Bonjour Ludivine et gbinforme,
Je ne crois pas mériter tous ces éloges, j'en ai plutôt peur!
Ceci dit, lorsqu'un évènement est déclenché, il y a interruption
pour répondre immédiatement à l'évènement.
En entrant dans la routine :
Private Sub Worksheet_Change(ByVal Target As Range)
...
End Sub
dans tous les cas de figure, si tu dois écrire sur la même
feuille qui a déclenché cet évènement, tu dois d'abord
désactiver les évènements sinon, il y a risque de récursivité
du à l'évènement [Worksheet_Change].
dans le cas ici présent, c'est le uf_Saisie qui va écrire,
c'est la même chose, c'est pourquoi j'ai introduit cette
instruction.
Position = Range("A1:A65535").End(xlDown).Row
Cet instruction permet de connaitre la première celulle vide sur la colonne A.
Set Region = Application.Intersect(Range("B1:B" & Position), Target)
Target est ici la cellule ciblé par l'évènement,
Range("B1:B" & Position) est la plage de détection.
Si tu n'as que certaines cellules, tu peux les énumérés ainsi :
Dim strPlage As String
Dim rngCible As Range
strPlage = "C7,C10,C13,C16"
Set rngCible = Range(strPlage)
Set Region = Application.Intersect(rngCible, Target)
Voilà !
à mon tour, je vais aller m'amuser sur mes classes dérivées en vbnet :-)
Lupin Répondre à Lupin.A | Bonjour Lupin,
J'ai un soucis sur le code que tu m'as proposé concernant ce problème:
lorsque la personne saisie quelque chose dans la colonne, un userform s'affiche pour lui demander de saisir des informations. Il saisit notamment une cellule numérique. Lorsqu'il clique sur le bouton de validation du userform, les données saisies dans le userform se copient sur le fichier excel, mais la cellule numérqiue se copie en format caractère dès qu'il y a des virgules.
En gros: je saisie un nombre numérique dans la colonne qui réceptionne l'info, le format est bien numérique.
Je saisie par le userform un nombre à virgule, il est copié en format texte dans la colonne qui réceptionne l'info.
Voici mon code lors de la saisie dans une cellule:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim Region As Range, Position As Long
Dim rngCible As Range
Set rngCible = Range("F9:F200,J9:J200,N9:N200,R9:R200,V9:V200,Z9:Z200,AD9:AD200")
' Capture de l'adresse du changement
strAdresse = Target.Address
Set Region = Application.Intersect(rngCible, Target)
If Not (Region Is Nothing) Then
If Range(strAdresse).Value <> "" Then
' Effacement des variables
USF_HEURES.HEURES= 0
' Appel du formulaire
USF_HEURES.Show
Else
Range(strAdresse).Offset(0, 1).Value = ""
MsgBox ("La justification a été effacée!")
End If
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
A noter que quand on saisit un numérique avec des décimales, il faut le saisir avec une virgule, le point ne passe pas (dû à mon contrôle sur le type de données).
Derrière mon bouton de validation du userform, il y a cela:
If IsNumeric(HEURES.Value) Then
With ActiveSheet
.Range(strAdresse).Offset(0, 1).Value =HEURES.Value
End With
USF_HEURES_A_JUSTIFIER.Hide
Else
If Not IsNumeric(HEURES.Value) Then
MsgBox ("Les heures doivent être un nombre, non un caractère!")
End If
End If
End Sub
En espérant que tu pourras m'aider,
Ludivine Répondre à Ludivine50 | Bonjour Ludivine,
Je suis de retour de vacances et je n'ai pas touché un clavier pour coder depuis plus
de 3 semaines. Ceci dit, je ne participe plus au forum pour des raisons personnels,
par contre je ferai une exception pour toi car tu m'as toujours démontrer que tu
appréciais mes interventions même si elles ne sont pas parfaite.
Alors quelques questions :
Je déduis que la variable [ HEURES ] est un champ sur le formulaire !
Mais quel type de champs !
S'il s'agit d'un textbox ou d'un combobox, la propriété d'affectation/lecture est [ .Text ] et non [ .Value ].
Deplus, puisque tu entrepose une valeur de type [ Heure ] dans un contrôle de type [ Text ], il faut
gérer la mise en forme lors de l'écriture et de la lecture !
ex. de lecture d'un textbox et de l'écriture sur une feuille:
Private Sub cmd_Valide_Click()
Dim Lheure As String
Dim Boite As Variant
If IsNumeric(HEURES.Text) Then
With ActiveSheet
.Range("C4").Offset(0, 1).NumberFormat = "hh:mm;@"
Boite = Split(HEURES.Text, ",")
Lheure = Boite(0) & ":" & Boite(1) & ":00"
Lheure = Format(Lheure, "h:m;@")
.Range("C4").Offset(0, 1).Value = 0
.Range("C4").Offset(0, 1).Value = Lheure
End With
Else
' Le second IF placé ici est implicite. Il n'est pas nécessaire de l'écrire.
MsgBox ("Les heures doivent être un nombre, non un caractère!")
End If
End Sub
Michel
~L'essentiel est invisible pour les yeux~
~On ne voit bien qu'avec le coeur~ Répondre à Lupin.A | 25 ori05, le 26 aoû 2009 à 10:12:38Bonjour, je me permets d'intervenir dans cette discussion, car j'ai un petit soucis concernant à peu près le même sujet : j'ai le code suivant
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If (ActiveCell.Value = "NOK") Then
MsgBox "Add a comment"
End If
End Sub
Mon problème est que la valeur NOK est disponible dans un menu déroulant(donées->validation->liste) OK/NOK.
Du coup quand la personne choisit NOK dans la liste le message ne s'affiche pas. Il ne s'affiche que si on clique n'importe où dans le classeur et qu'ensuite on reclique sur cette cellule.
Je cherche une solution qui me permettrait d'avoir directement le message...
Merci beaucoup ! Répondre à ori05 | Bonjour
Pourquoi tu n'utilises pas plutôt, car c'est au moment où la cellule est modifiée que c'est utile, non ?
Private Sub Worksheet_Change(ByVal Target As Range)
If (Target.Value = "NOK") Then
Toujours zen Répondre à gbinforme |
| 27 ori05, le 26 aoû 2009 à 10:40:04Effectivement c'était bien Worksheet_change et non Worksheet_selectionchange qu'il fallait que j'utilise !
merci beaucoup je cherchais mille et une facon et évidemment je n'ai pas pensé à ça !!
encore merci !!! Répondre à ori05 |
|
|
|
|
|
|
|
|
|
|