" J'ai deux événements.
J'ai essayé de copier les deux dans le même Worksheet_Change, mais Excel devient berzerk et plante.
Range 1:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim acr As Range
Set acr = Range("C9:G9")
For Each Cell In acr
Cell.Value = LCase(Cell)
Next Cell
End Sub
4 Réponses :
Comme ça, vous pouvez faire les deux choses dans le même événement
Vous devez ajouter Application.EnableEvents = False au début pour éviter la condition de concurrence.
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Dim ccr As Range, acr as Range
Set ccr = Range("C6")
For Each Cell In ccr
Cell.Value = LCase(Cell)
Next Cell
Set acr = Range("C9:G9")
For Each Cell In acr
Cell.Value = LCase(Cell)
Next Cell
Application.EnableEvents = True
End Sub
Je vous remercie! Cela le corrige
Le problème principal est que la modification d'une valeur de cellule Cell.Value déclenchera immédiatement un autre Worksheet_Change . Vous devez Application.EnableEvents = False pour éviter cela.
Je recommande également de travailler avec Intersect pour que le code ne fonctionne que sur les cellules qui sont réellement modifiées.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim AffectedRange As Range
Set AffectedRange = Intersect(Target, Target.Parent.Range("C6, C9:G9"))
Application.EnableEvents = False 'pervent triggering another change event
On Error GoTo ERR_HANDLING
If Not AffectedRange Is Nothing Then
Dim Cel As Range
For Each Cel In AffectedRange.Cells
Cel.Value = LCase$(Cel.Value)
Next Cel
End If
On Error GoTo 0
'no Exit Sub here!
ERR_HANDLING:
Application.EnableEvents = True
If Err.Number <> 0 Then
Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End If
End Sub
En plus du commentaire de @Frank Ball, y compris la gestion des erreurs:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim AffectedRange As Range
Set AffectedRange = Intersect(Target, Target.Parent.Range("C6, C9:G9"))
If Not AffectedRange Is Nothing Then
Application.EnableEvents = False 'pervent triggering another change event
Dim Cel As Range
For Each Cel In AffectedRange.Cells
Cel.Value = LCase$(Cel.Value)
Next Cel
Application.EnableEvents = True 'don't forget to re-enable events in the end
End If
End Sub
Les deux événements Worksheet_Change sont assez identiques, ils sont une boucle autour d'une plage, renvoyant LCase () . Ainsi, c'est une bonne idée de créer un Sub séparé pour lui comme ceci:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("C6"), Range("C9:G9")) Is Nothing Then Exit Sub
Application.EnableEvents = False
FixRangeLCase Range("C6")
FixRangeLCase Range("C9:G9")
Application.EnableEvents = True
End Sub
Ensuite, faites-lui référence à l'événement Worksheet_Change. Dans la mesure où l'événement Worksheet_Change est assez "cher", en cours d'exécution toujours, il est judicieux de ne l'exécuter que lorsqu'une cellule cible spécifique est modifiée et sinon quittez la procédure - If Intersect ( Target, Range ("C6"), Range ("C9: G9")) Is Nothing Then Exit Sub
Le Application.EnableEvents = False est nécessaire pour désactiver les événements. À la fin, il est remis à Vrai .
Sub FixRangeLCase(rangeToFix As Range)
Dim myCell As Range
For Each myCell In rangeToFix
myCell.Value2 = LCase(myCell.Value2)
Next myCell
End Sub
Vous pouvez également utiliser:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range, cell As Range
Application.EnableEvents = False
If Not Intersect(Target, Range("C6")) Is Nothing Or Not Intersect(Target, Range("C9:G9")) Is Nothing Then
Set rng = Range("C9:G9", "C6")
For Each cell In rng
cell.Value = LCase(cell.Value)
Next
End If
Application.EnableEvents = True
End Sub
Ce n'est pas correct car cela ne change que la cellule cible
Cette Target.Value = LCase (Target.Value) échoue si Target est une plage de plusieurs cellules. LCase ne peut pas gérer un tableau de valeurs Target.Value .
@newguy ce que vous mentionnez n'est pas un problème ici car seules les cellules Target ont réellement changé, les autres sont donc déjà en minuscules (et n'ont pas besoin d'être converties à nouveau). • Le problème ici serait qu'il fonctionnerait sur toutes les cellules modifiées, même en dehors de la plage donnée, non seulement sur les cellules de C6, C9: G9 (mais en fait, il échoue car de la raison que j'ai mentionnée ci-dessus).
@Error Lors de l'utilisation de l'événement Worksheet_Change , gardez toujours à l'esprit que Target peut être une Range collée non seulement une seule cellule.
@ Pᴇʜ je crois avoir compris le point et j'ai modifié la réponse. Est-ce correct?
Réponse @newguy modifiée. toutes autres suggestions ou corrections sont les bienvenues!
Mieux vaut ne pas planter parce que Target est une plage. Mais notez que si, par exemple, seule la cellule C10 est éditée, le rng complet est converti en minuscules alors que seul C10 a changé et il suffirait de convertir cette cellule uniquement. Pour éviter cela, consultez ma réponse où j'ai utilisé AffectedRange = Intersect (Target, Target.Parent.Range ("C6, C9: G9")) pour obtenir uniquement les cellules modifiées de la plage souhaitée. Donc tu finirais avec ce que j'ai répondu.
À quoi sert .parent?
Si l'événement est déclenché alors qu'une autre feuille de calcul a le focus, je ne suis pas sûr sur quelle feuille de calcul Range serait par défaut Target.Parent donne la feuille de calcul où la plage Target code> se trouve. Cela garantit que Range ("C6, C9: G9") pointe vers la même feuille de calcul que celle vers laquelle pointe Target . Juste pour être sauvé et ne pas laisser Excel décider de quelle feuille je veux dire.
Mettez simplement le code dans un seul événement.
Les réponses fournies sont toutes bonnes sauf qu'elles n'ont pas de gestion des erreurs. Donc, si votre code échoue entre les instructions "Application.EnableEvents = False" et "Application.EnableEvents = True", alors vous venez de quitter Excel est un mauvais état où aucun événement ne se déclenchera. Chaque fois que vous utilisez "Application.EnableEvents", "Application.ScreenUpdating", etc. utilisez toujours la gestion des erreurs pour vous assurer qu'en cas d'échec de votre code, ces types de paramètres sont réinitialisés à ce qu'ils doivent être. Je suis un développeur .NET / C # (VBA = Megablocks, C # = Lego Technic) et la gestion des erreurs est un must.
@FrankBall Bon, en a ajouté un dans ma réponse.