Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2016 VBA - CommandBars.OnUpdate - Comment identifier les évènements déclenchés

Dudu2

XLDnaute Barbatruc
Bonjour,

Je n'ai rien trouvé sur Internet à ce propos et je pense qu'il n'y a pas de réponse.
Néanmoins je soumets ce sujet au cas où une idée géniale émergerait.

Quand on lance un CommandBars.OnUpdate, on récupère tous les évènements d'interaction de l'utilisateur (sélection, déplacement, copier, coller, etc...)
Mais rien ne permet de savoir dans le code par un Tag, un numéro, une information quelconque, quel est l'évènement qui a déclenché le OnUpdate. Il n'y en a sans doute pas, mais je pose la question quand même.
 

Pièces jointes

  • Test_1c.xlsm
    24.9 KB · Affichages: 9

patricktoulon

XLDnaute Barbatruc
Bonjour @Dudu2
perso je m'en sert pour faire un minuteur de cet event (plus léger et moins gourmand qu'un do loop)
je pense pas que ce soit possible étant donné que cet event n'est pas implémenté a l'origine d'ailleurs il n'a pas d'argument

et pour info on ne récupère pas les déplacer ,coller ,etc.. il est simplement déclenché par les event des boutons et autre du ribbon qui se modifie en fonction de selection et autres

mais sait on jamais ;
regarde peut être du coté de la librairie IAccessible( a partir de 2013) que l'on utilise pour chopper un Control dans le ruban customUI
 

Dudu2

XLDnaute Barbatruc
Bonjour @patricktoulon,
En effet ce n'est pas possible, j'ai essayé toutes les propriétés de l'ActiveMenuBar et rien ne bouge.
Et si, on récupère les sélections, les copier, les coller, les supprimer, les déplacements flèches, les modifications de format et sans doutes d'autres petites choses.

Je me suis amusé à tracer un mix d'évènements OnUpdate(), Selection() et Change() dans ce fichier.
Essaie de maniper sur la feuille et tu verras.

Mon intention initiale était de créer un évènement pour les modifications de format de cellules non captées par l'évènement Change(). Je pense que c'est possible mais j'ai laissé tombé l'idée car pas de justification réelle et flemme.
 

Pièces jointes

  • Séquence des évènements.xlsm
    28.3 KB · Affichages: 5

Dudu2

XLDnaute Barbatruc
A noter que c'est grâce à cet évènement CommandBars.OnUpdate() que j'ai pu, très largement inspiré par un exemple du Web (d'ailleurs cité), intercepter les modifications des textes de Shapes pour les colorer selon une échelle de couleur dans ce sujet.

J'y ai ajouté la colorisation en cas de modification de l'échelle de couleur, mais seulement sur sa partie valeur avec l'évènement Change() et pas sur sa partie couleur évidemment puisque Change() n'est pas sensible aux modifications de format. D'où mon questionnement initial.
 

patricktoulon

XLDnaute Barbatruc
re
hihihihi !!
non c'est avec les events selection change que tu pointe (avec le traceOn certainement declenché par le update de la commandbar)
mais en aucun cas le ribbon ou un de ces control possède une fonction de ce type d'events
 

Dudu2

XLDnaute Barbatruc
Tu fais une fixette sur ton minuteur. Mais si tu te penchais réellement sur la question sans cet a priori, tu constaterais que ce que je décris est tout à fait réel. Mais bon, ça n'a pas d'importance.
 

patricktoulon

XLDnaute Barbatruc
re
je fixe rien du tout je reponds simplement a ta question de base
a savoir comment identifier les événements déclenchés

dans le update ou une eventuelle property du ribbon ou control ça n'existe pas

les events selection_change et sheet_change dans ton exemple suffisent puisqu'il sont fait pour ça

alors oui dans le update tu peux passer en revue tout ce que tu veux pour tester un éventuel changement
même pas besoins des des event du sheet d'ailleurs
mais en aucun cas l'event update possède une quelconque property de ce genre

en fait plus exactement j'ai répondu a cette question
Mais rien ne permet de savoir dans le code par un Tag, un numéro, une information quelconque, quel est l'évènement qui a déclenché le OnUpdate. Il n'y en a sans doute pas, mais je pose la question quand même.
 

Dudu2

XLDnaute Barbatruc
Je sais bien que tu as répondu à la question posée de l'identification de l'évènement lors d'un CommandBars.OnUpdate. La réponse est la même que celle que j'avais obtenue: on ne peut pas identifier l'évènement.

Ton timer basé sur un CommandBars.OnUpdate. n'est un timer que parce que lors du déclenchement initial de l'évènement (qui se fait dès qu'on Set le CommandBars), tu modifies la propriété Enabled du Control 2040 de l'Application.CommandBars ce qui provoque à nouveau l'évènement. Et on boucle jusqu'à plus soif sur un certain rythme qui est perçu comme un timer.

La question n'est pas là. Elle est dans le fait que tu dis:
en fait tu ne fait qu'un minuteur qui se déclenche avec le update et modifie la variable traceON
le reste c'est les events classique

Et que moi, sur la base du fichier du Post #3, je dis qu'un évènement CommandBars.OnUpdate se déclenche sur:
les sélections, les copier, les coller, les supprimer, les déplacements flèches, les modifications de format et sans doutes d'autres petites choses.
Sans qu'on puisse directement l'identifier. Mais dans certains cas, en ajoutant du traitement, on peut puisque, par exemple, dans ce sujet, il a été possible d'identifier la modification du texte d'un Shape. Et ce n'est qu'un exemple qui n'exploite même pas le bénéfice qu'on pourrait tirer des autres évènements Selection() et Change() qui viennent s'ajouter aux évènements CommandBars.OnUpdate.
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Il est vrai cependant que les évènements du CommandBars.OnUpdate sont assez peu exploitables sauf dans des cas particuliers. En effet il faut la plupart du temps exploiter la Selection au moment de l'évènement et la comparer à la Selection lors d'un évènement ultérieur.
Si la Selection est un Range, cela peut devenir problématique si sa taille est importante car pour la comparer à la suivante (ou l'une des suivantes) il faut la conserver, d'où des traitements potentiellement longs et une taille mémoire potentiellement importante. Mais dans certains cas, ça peut le faire.
 

patricktoulon

XLDnaute Barbatruc
re
en gros je dis minuteur mais en fait je m'en sert comme controleur répétitif
et tu peux controler ce que tu veux
le update est déclenché par a peu pres tout et même si tu fait rien de temps en temps il se déclenche quand même
Attention quand tu es en mode écriture(double click) dans les cells, il est bloqué un peu comme un userform modal qui bloque tout

quel est l'avantage de cette utilisation:
en premier la consommation car on utilise un events qui se répète et qui ne consomme pas(moins ) qu'un code vba (do/loop, etc...)
je l'utilisais dans mon casse brick et tetris

l'api settimer est encore plus Economique puisqu'elle exécute la macro en adressof
 

Dudu2

XLDnaute Barbatruc
Personellement, je n'ai pas constaté de déclenchement intempestif du OnUpdate. Y a toujours une action de l'utilisateur à la base y compris comme changer de feuille, d'application, basculer sur le Project VBA, faire un Scroll et un tas d'autres choses.

Je me suis essayé à créer un évènement de changement de format de cellule par l'interface (juste le Bold, la couleur de caractère et la couleur de fond à titre d'essai). Ce qui n'est pas le meilleur moyen puisque c'est bien plus facile de le faire à partir de la Pile des Undo combinée à l'évènement standard de Selection().

L'idée étant que si à l'évènement N+1 du OnUpdate, la Range de Selection est le même qu'à l'évènement N du OnUpdate, alors il faut comparer les formats du Range de Selection à N & N+1 et lancer l'évènement "artificiel" Workbook_SheetChangeFormat() si on trouve une différence.

Alors OK, ça marche mais ce n'est utilisable que dans un UsedRange de 30.000 - 40.000 cellules. Au-delà ça n'est pas très viable si la modification de format touche toutes les cellules.
Et puis le principe ne peut pas s'appliquer au VBA, car même si en modifiant la cellule (valeur ou format) en VBA cela déclenche un évènement OnUpdate, le principe de détection étant basé sur des sélections préalables, celles-ci n'ont pas lieu d'être en VBA quand on change le format d'une cellule par exemple. Et donc on ne peut pas savoir où a eu lieu le changement ni sa nature.
 
Dernière édition:
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…