XL 2016 VBA - Génération spontanée de l'évènement Worksheet_SelectionChange() avec SpecialCells

Dudu2

XLDnaute Barbatruc
Bonjour,

Pasteur n'en reviendrait pas !
Dans ce fichier, le simple appel à une fonction de sommation des cellules visibles sur une feuille filtrée provoque la génération spontanée d'un évènement Worksheet_SelectionChange().

Certes je parcours les Target.SpecialCells(xlCellTypeVisible).Areas pour en extraire les valeurs, mais à aucun moment je ne provoque de sélection.
Alors comment faire cette foutue somme si ça part en Worksheet_SelectionChange() récursif à chaque fois ?

Faites le test !
 

Pièces jointes

  • Classeur1.xlsm
    17.5 KB · Affichages: 11
Dernière édition:

Dudu2

XLDnaute Barbatruc
J'ai bien une solution de contournement qui consiste à placer un flag booléen lorsque la sommation est en cours indiquant qu'il faut ignorer l'évènement spontané. Mais j'aimerais avoir une autre option plus déterministe.
 

Pièces jointes

  • Classeur2.xlsm
    18.1 KB · Affichages: 3

Dudu2

XLDnaute Barbatruc
Bonjour @RyuAutodidacte,
Dans le cadre d'une application je maintiens des informations en Status Bar (ou plutôt dans un UserForm qui est placé à cet endroit mais peu importe) sur la valeur / somme numérique de la sélection. Je n'avais pas prévu le cas des feuilles filtrées et l'utilisateur en a besoin. J'ai donc fait une modif simple pour ne prendre que les cellules visibles. Ça paraissait hyper-trivial. Réglé en 10 secondes. Et je me suis retrouvé face à ce truc totalement inattendu.
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonjour à tous :),

En cherchant sur Gogole, le phénomène est connu (personnellement, je ne le connaissais pas).

Essayez ceci:
VB:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
   MsgBox "SommeRange(" & Target.Address(0, 0) & ") = " & SommeRange(Target)
End Sub

Private Function SommeRange(Rng As Range) As Double
Dim xrg, xcell, x, somme As Double
 
   If Rng.Count = 1 Then
      Set xrg = Rng
   Else
      Application.EnableEvents = False
      On Error Resume Next
      Set xrg = Rng.SpecialCells(xlCellTypeVisible)
      Application.EnableEvents = True
      On Error GoTo 0
   End If
   For Each xcell In xrg
      x = xcell.Value
      If x <> "" And IsNumeric(x) And Not IsDate(xcell) Then somme = somme + x
   Next xcell
   SommeRange = somme
End Function
 
Dernière édition:
C

Compte Supprimé 979

Guest
J'ai bien une solution de contournement qui consiste à placer un flag booléen lorsque la sommation est en cours indiquant qu'il faut ignorer l'évènement spontané. Mais j'aimerais avoir une autre option plus déterministe.
Bonjour le fil

Dudu2, une option plus "déterministe" 🤔
VB:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  Application.EnableEvents = False
  MsgBox "SommeRange(" & Target.Address(0, 0) & ") = " & SommeRange(Target)
  Application.EnableEvents = True
End Sub

A+
 

Dudu2

XLDnaute Barbatruc
@mapomme, @BrunoM45,
Que n'y ai-je pensé ! Heureusement que vous êtes là pour indiquer le bon chemin.
Merci à tous les deux. Et Bravo !
Merci aussi à @RyuAutodidacte pour sa proposition.
En cherchant sur Gogole, le phénomène est connu
Franchement, je sais pas quels critères tu as cités pour retrouver ça dans le fatras Excel VBA mais tu as toute mon admiration.
 

Dudu2

XLDnaute Barbatruc
Excel specialcells and Worksheet_SelectionChange event
OK. Bien vu.

Ceci dit j'ai encore des ennuis sur les Areas quand je ne sélectionne qu'une seule cellule.
Il me sort 2 Areas des lignes entières non filtrées de toute la feuille !

Exemple: Je sélectionne B5. Les lignes 6 et 7 son masquées.
Il me trouve 2 Areas 1:5 et 8:1048576 !

J'ai bien vu que tu avais ré-écrit la fonction de somme, mais j'aimerais plutôt exploiter les tableaux des valeurs des Areas plutôt que les valeurs des cellules individuellement pour aller plus vite.

Faut juste que je trouve la parade à ce nouveau problème qui doit être de simplement tester le .Cells.Count du Range passé en argument du calcul de somme.

@patricktoulon,
la seule solution que je connaisse c'est de bloquer les events
Oui c'est ce que @mapomme et @BrunoM45 ont indiqué.
 

Pièces jointes

  • Classeur3.xlsm
    19.9 KB · Affichages: 0
Dernière édition:

patricktoulon

XLDnaute Barbatruc
maintenant il y a bien une autre solution
on se passe de specialcells et des areas
en fait c'est simple

tu veux récupérer l'adresse de selection sans les ligne caché par le filtre ou autre et faire la somme de celles ci
nous allons donc utiliser une variable que je vais injecter vide dans la fonction pour récupérer l'adresse
on injectera alors deux arguments dans la fonction qui du coup sert a faire la somme et recupérer l'address de plage
voilà de cette manière tu n'aura pas le phénomène "d'event propagation"
l'event selectionchange
VB:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim adresse, som
    som = RangeSomme(Selection, adresse)
    MsgBox "Worksheet_SelectionChange Target = " & adresse & vbCrLf & som
End Sub

la fonction
VB:
Function RangeSomme(rng As Range, adresse)
   Dim somm#, rng2 As Range
   For Each cel In Selection.Columns(1).Cells
        If IsNumeric(cel) And Not IsDate(cel) And cel.EntireRow.Hidden = False Then
        somm = somm + cel.Value
        If rng2 Is Nothing Then Set rng2 = cel Else Set rng2 = Union(rng2, cel)
   End If
   Next
    adresse = rng2.Address
    RangeSomme = somm
End Function
et voilà tu a l'adresse non contiguë de ta plage filtré et la somme ;)
 

Dudu2

XLDnaute Barbatruc
Bonjour à tous,

@patricktoulon, 2 soucis dans ton code:
- tu limites la somme à la 1ère colonne de la sélection (il faudrait d'ailleurs que ce soit sur l'argument rng),
- tu testes et éventuellement totalises des valeurs de cellules, y compris celles qui sont filtrées.

Dans le Post #12, le code que j'ai finalement peu amendé pour traiter les 2 problèmes cités, garde le traitement des Areas qui permet de charger des tableaux sur lesquels est faite la somme. Ça ne change pas grand chose pour de petites sélections, je suis d'accord, mais mon utilisateur fait de grandes sélections avec des tonnes de valeurs numériques.
 

RyuAutodidacte

XLDnaute Impliqué
Supporter XLD
Bonjour,

Il peut y a voir aussi, si cela convient, la feuille tremplin qui peut être créée à la volé si voulu (puis supprimer une fois fini … à voir), sur laquelle (dans le cas où les paramètre de filtre son aisé … à voir …) y faire un filtre élaboré permettant d'avoir un résultat escompté avec aucune lignes masquées et donc les valeurs des cellules en contigües, permettant une sélection toujours aisée et aussi la simplification du code, évitant alors la problématique de l'event avec le SpecialCells(xlCellTypeVisible) … à voir
 
Dernière édition:

Statistiques des forums

Discussions
312 493
Messages
2 088 955
Membres
103 989
dernier inscrit
jralonso