Developpez.com - Rubrique Excel

Le Club des Développeurs et IT Pro

Apprendre VBA pour Excel par la pratique - Sixième partie : apprendre la programmation de nouvelles fonctions pour utilisateur

Un tutoriel de L. OTT

Le 2018-09-18 10:53:38, par laurent_ott, Rédacteur
Chers membres du club,

J'ai le plaisir de vous présenter ce sixième mémento qui va vous apprendre la programmation de nouvelles fonctions Excel pour l'utilisateur.

Ce sixième et dernier volet de cette hexalogie sur la programmation en VBA pour EXCEL explore un aspect qui n'a pas été souvent abordé dans les précédents mémentos : le développement de fonctions pour simplifier la vie des utilisateurs (et non plus des programmeurs).

Un vaste sujet dont on peut difficilement faire le tour en quelques pages.
Alors ici nous ne présenterons que le contour des techniques à utiliser. Rassurez-vous, il n'y a rien de bien compliqué, d'autant plus qu'Alice et Bob vous guideront au fil de votre lecture.
Bonne lecture et n'hésitez pas à apporter vos commentaires

Retrouvez les meilleurs cours et tutoriels pour apprendre Microsoft Excel
  Discussion forum
52 commentaires
  • laurent_ott
    Rédacteur
    Envoyé par maliano20

    Pourquoi vous avez préféré le IF au SELECT CASE? J'ai lu quelque part sur ce site que le second est plus rapide.
    Par habitude de programmation, tout simplement (et tout bêtement) !
    Je viens de tester et effectivement, SELECT CASE semble bien plus rapide que IF dans une boucle répétée plusieurs milliers de fois. Mais la différence est infime sur un appel ponctuel. En tout cas merci pour cette remarque, j'en tiendrai compte dans mes prochains programmes.

    Envoyé par maliano20

    Pourquoi avoir utiliser le / en lieu et place du \? Étant donné qu'on a besoin de la partie entière de la division, le second n'est il pas plus rapide?
    D'après mes tests, le second n'est pas plus rapide. Ici, comme la variable "Milieu" est déclarée Entier Long, la valeur calculée renvoyée sera toujours un entier (donc la partie entière), et donc pas besoin d'utiliser \ dans ce cas.
  • eriiic
    Membre expert
    Bonjour,

    Milieu = (Début + Fin) / 2
    Pourquoi avoir utiliser le / en lieu et place du \? Étant donné qu'on a besoin de la partie entière de la division, le second n'est il pas plus rapide?
    Attention que ces 2 opérateurs ne sont pas équivalents et substituables, les résultats peuvent être différents.
    Avec Début = 1 et Fin = 6, soit une somme impaire :
    (Début + Fin) / 2 = 3.5, qui sera arrondi à 4 lors de la conversion si Milieu est typé Entier
    (Début + Fin) \ 2 = 3, résultat de la division entière, et restera à 3.
    Il faut penser à en tenir compte.
    eric
  • Filippo
    Membre éclairé
    Bonjour Laurent,
    merci beaucoup pour ce mémento.
    C'est super.

  • maliano20
    Nouveau membre du Club
    Permettez-moi de vous remercier d'abord pour ces excellents documents.
    Code :
    1
    2
    If ValRecherchée <= TabDonnées(Début) Then TableauRecherchePosition = Début: Exit Function
    If ValRecherchée >= TabDonnées(Fin - 1) Then TableauRecherchePosition = Fin: Exit Function
    Pourquoi vous avez préférer le IF au SELECT CASE? J'ai lu quelque part sur ce site que le second est plus rapide.

    Code :
    Milieu = (Début + Fin) / 2
    Pourquoi avoir utiliser le / en lieu et place du \? Étant donné qu'on a besoin de la partie entière de la division, le second n'est il pas plus rapide?
  • maliano20
    Nouveau membre du Club
    Envoyé par laurent_ott
    Par habitude de programmation, tout simplement (et tout bêtement) !
    Je viens de tester et effectivement, SELECT CASE semble bien plus rapide que IF dans une boucle répétée plusieurs milliers de fois. Mais la différence est infime sur un appel ponctuel. En tout cas merci pour cette remarque, j'en tiendrai compte dans mes prochains programmes.

    D'après mes tests, le second n'est pas plus rapide. Ici, comme la variable "Milieu" est déclarée Entier Long, la valeur calculée renvoyée sera toujours un entier (donc la partie entière), et donc pas besoin d'utiliser \ dans ce cas.
    Merci pour votre prompt réaction.
  • laurent_ott
    Rédacteur
    À noter qu'il y a encore plus rapide que SELECT CASE, c'est WHILE .... WEND, ou encore DO UNTIL ... LOOP
    J'utilise parfois cela dans l'algorithme QuickRanking.
  • maliano20
    Nouveau membre du Club
    Bonsoir,
    J'ai quelques observations sur les triés.

    Dans la Function RechercheW() du Tome 6

    code 1:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
     ' Mémorise les données:
    Application.Cursor = xlWait
    
    For i = 1 To UBound(PlageDonnées())
    TabDonnées(i - 1) = PlageDonnées(i, ColRecherche).Value
    Next i
    
    ' Trie les données et retourne leur ordre de classement:
    Classement = QuickRanking(TabDonnées(), True, 2)
    Il est possible de faire l’économie de cette boucle en faisant :

    code 2:

    Code :
    1
    2
    3
    
    TabDonnées= PlageDonnées.Value
    Vous avez choisie le code 1 par préférence ou bien pour des considérations techniques?

    Dans la Function QuickRanking(), je pense qu'il est préférence de remettre une gestion pour annuler On Error Resume Next dans le code 3 ci-dessous

    code 3:

    Code :
    1
    2
    3
    4
    5
    6
    7
    ' Bornes du tableau des données d'origine :
    Dim TabDébut As Long, TabFin As Long
    
    On Error Resume Next ' Si aucune donnée à trier.
    TabDébut = LBound(TabDonnées)
    TabFin = UBound(TabDonnées)
    code 4:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ' Bornes du tableau des données d'origine :
    Dim TabDébut As Long, TabFin As Long
    
    On Error Resume Next ' Si aucune donnée à trier.
    TabDébut = LBound(TabDonnées)
    TabFin = UBound(TabDonnées)
    
    On Error GoTo FIN
    
    ..........
    
    FIN:
    Sinon, en cas d'erreur la boucle suivante risque de tourner indéfiniment:

    code 5:

    Code :
    1
    2
    3
    i = TabTps(Anc) ' Plus proche donnée inférieure connue.
    While Anc < MiniRac: MiniRac =Anc: Wend ' Plus rapide que If Anc < MiniRac Then MiniRac = Anc

    Si l'indice min du tableau (LBound(TabDonnées)) est différent de 0, la boucle suivante tourne indéfiniment.

    code 6:

    Code :
    1
    2
    While TabDonnées(TabTps(Début + 1)) < Tps: Début = Début + 1: Wend
  • Ar No
    Candidat au Club
    Envoyé par laurent_ott
    Chers membres du club,

    J'ai le plaisir de vous présenter ce sixième mémento qui va vous apprendre la programmation de nouvelles fonctions Excel pour l'utilisateur.

    Bonne lecture et n'hésitez pas à apporter vos commentaires

    Retrouvez les meilleurs cours et tutoriels pour apprendre Microsoft Excel

    Bonjour Laurent,

    J'ai commencé à faire du VBA en 'suivant' un Laurent (Longre) il y a longtemps, sur Excel 5 ...
    petitement, je suis simple utilisateurs de Excel
    J'imagine le temps passé sur c'est ouvrages.
    Merci donc
    Bonjour à Alice
  • laurent_ott
    Rédacteur
    Envoyé par boulser
    ...Snake est pour Excel 2003. Je travaille en Excel 2013 64 Bits. Je n'arrive pas à modifier pour cette version. auriez-vous une solution?
    Effectivement les API 32 bits ne sont pas toujours compatibles 64 bits, et leur mise à niveau est souvent fastidieuse.
    N'ayant pas la version 64 Bits d'Excel je ne me suis jamais lancé sur ce terrain.

    Mais Thierry GASPERMENT (arkham46) est un expert du sujet :
    https://arkham46.developpez.com/arti...ice/vba64bits/

    Et de la programmation en mode graphique :
    https://arkham46.developpez.com/arti...ice/clgdiplus/
  • herve38000
    Candidat au Club
    Merci Laurent pour ces documents vba . Moi aussi je code : Super site d'info : Merci à toutes les personnes pour repondre et partager vos connaissances. Pierre