Dysfonctionnement fonction VBA arraySortAsc du Pack XLP

Bonjour

je joins un code (en .txt) qui me laisse dubitatif :

17fichiertexte.txt (618.00 Octets)

Ce code est sur la base du code fourni par XLP pour tester la fonction VBA arraySortAsc (du Pack XLP)

il semble que le seul fait de mettre l'argument de la fonction VBA arraySortAsc entre parenthèses ne donne pas le même résultat si l'argument est fourni sans ( ) !

Pour le moins surprenant, non ?

Qu'en pensez-vous ? Merci

Je me réponds à moi-même :

Ce "dysfonctionnement" est certainement dû à :

- une question de portée de variable

- la façon dont le compilateur interprète les ( )

Quand on débute dans un langage comme VBA, on doit passer de joyeux moments à résoudre ces problèmes.

Je vais également fouiner dans la doc que le site EXCEL-PRATIQUE fournit.

Ce "dysfonctionnement" est certainement dû à :

Je pense que le mieux serait de demander confirmation à la personne qui vous a répondu cela.

Ce que tu me dis ne m'avance pas beaucoup, puisque c'est moi-même qui me faisait une réponse.

Cela dit, si tu en sais plus, je suis preneur.

Cordialement.

Comme rapporté dans les messages précédents, j'ai fouiné dans les divers doc, dont celle de EXCEL-PRATIQUE, sur la question de portée des variables.

Le code (par ailleurs très simple) que j'avais donné est correct sur la question de portée.

Par contre, j'ai "amélioré" le code de l'instruction

arraySortAsc (Tableau) 'Tri du tableau

en le remplaçant par :

Call arraySortAsc (Tableau) 'Tri du tableau

Dans ce cas, le programme fonctionne très bien.

Ce que je ne comprends toujours pas est :

  1. pourquoi le compilateur n'a pas signalé une erreur de syntaxe sur arraySortAsc (Tableau) 'Tri du tableau
  2. pourquoi l'exécution du code a quand même abouti en fournissant un résultat comme quoi le tableau n'était pas trié !

Ca m'intéresserait d'avoir une explication possible, car ce genre de "bizarrerie" est susceptible de se retrouver dans un autre contexte de codage.

Par avance merci.

bonjour le fil,

avez-vous un lien vers ce pack ou vers la documentation ou le code de l'arraySortAsc

Bonjour,

Tu trouveras ce pack en page racine du site, rubrique : Pack de fonction XLP

Cordialement

Cependant, le problème que j'ai exposé ne doit pas être lié à ce pack.

J'ai exposé le problème à ChatGPT ; après plusieurs échanges, j'ai extrait les réponses qui correspondent à mon problème :

============== infos fournies par Chatgpt =====================

Appel de Fonction avec Parenthèses

Quand vous appelez une fonction en VBA et que vous utilisez des parenthèses autour des arguments, VBA évalue d'abord l'argument avant de le passer à la fonction. Cette évaluation crée une copie temporaire de l'argument, ce qui signifie que votre fonction arraySortAsc travaille sur une copie du tableau et non sur le tableau original. Par conséquent, les modifications apportées à ce tableau temporaire ne sont pas reflétées dans le tableau original.

Appel de Fonction sans Parenthèses

Quand vous appelez une fonction sans parenthèses autour des arguments, VBA passe les arguments par référence. Cela signifie que la fonction travaille directement sur le tableau original et que toutes les modifications apportées par la fonction sont reflétées dans le tableau original.

===============================================================

Je retiens que lors de l'appel à une procédure, la mise en parenthèses des arguments ne provoque pas d'erreur de compilation, contrairement à ce que l'on peut lire tant chez Microsoft que dans d'autres sources ; bien au contraire, le compilateur va créer une copie des arguments puis les communiquer à la procédure. Cette copie fait que la procédure de tri ne s'exécute pas sur le tableau d'origine.

En conclusion :

Lors de l'appel d'une procédure :

  • si on ne veut pas mettre les arguments entre parenthèses => pas de pb
  • si on veut mettre les arguments entre parenthèses => il est impératif d'appeler la procédure par Call ; si on oublie ce Call, le compilateur ne donne pas d'erreur, mais le résultat est imprévisible.

Et je remercie ChatGPT.

En complément de ma réponse précédente, j'ai soumis le même cas à COPILOT de Microsoft.

Les explications fournies par COPILOT sont similaires à celles de ChatGPT, à ceci près que COPILOT ajoute :

La raison pour laquelle le compilateur n’a pas signalé d’erreur est que l’utilisation de parenthèses autour d’un argument de procédure est valide en VBA. Cependant, dans ce cas, cela modifie le comportement de la fonction.

Alors là, je me gausse : Selon Microsoft (a priori mieux placé que OpenAI pour répondre à des questions sur VBA), c'est valide de mettre les ( ) en VBA mais le comportement de la fonction est altéré !!!!!!!!

Ce n'est pas terrible qu'un compilateur modifie le comportement d'une fonction !!!

Bonjour,

Dans cette ligne, tu peux voir que "Tableau" est un argument de type ByRef (sans quoi "Tableau" ne serait pas modifié) :

arraySortAsc Tableau 'Tri du tableau

Je pense que le problème vient de là ... En ajoutant des () tu ne passes pas directement le tableau en argument, donc le "Tableau" dans ton code n'est pas modifié (même si le tableau dans arraySortAsc a été correctement trié, j'ai vérifié).

Cordialement,

Bonjour Sébastien,

Tout à fait d'accord avec toi : pas de pb dans la fonction arraySortAsc qui a dans ses specs de trier le tableau fourni lors de l'appel (d'où l'indispensable ByRef).

Le problème est dans la syntaxe de l'appel !

  • arraySortAsc table = > ça trie
  • arraySortAsc (table) = > ça trie pas

Avoue qu'un langage de programmation qui selon la syntaxe d'appel à une fonction est susceptible de donner des résultats différents, il y a un petit pb de conception, non ?

Mais il faut faire avec.

Cordialement

Je pense que tu n'as pas compris ce que je voulais dire.

arraySortAsc table = > ça trie

Ca trie car le tableau est passé directement en argument.

arraySortAsc (table) = > ça trie pas

Ca ne trie pas car le tableau n'est pas passé directement en argument.

En ajoutant les () ça va envoyer le résultat du contenu entre les (), soit une copie du tableau, cette copie du tableau sera ensuite triée, mais comme il s'agit d'une copie du tableau, le tableau original reste inchangé (comme si c'était passé en ByVal), d'où l'impression que ça ne fonctionne pas alors que la fonction arraySortAsc a correctement effectué le tri (j'ai vérifié) mais sur la copie du tableau.

Voila un exemple simple pour illustrer ce que je viens de t'expliquer :

Sub incrementer(valeur)
    valeur = valeur + 1
End Sub

Sub test()

    valeur = 5
    incrementer valeur
    MsgBox valeur 'Renvoie 6

    valeur = 5
    incrementer (valeur)
    MsgBox valeur 'Renvoie 5

End Sub

Dans le premier cas, c'est la référence de la variable qui est passée en argument :

incrementer valeur

Dans le second cas, c'est le résultat du contenu entre () qui est passé en argument, soit 5 (ça ne modifie donc pas la valeur de la variable) :

incrementer (valeur)

Avoue qu'un langage de programmation qui selon la syntaxe d'appel à une fonction est susceptible de donner des résultats différents, il y a un petit pb de conception, non ?

C'est un comportement normal bien que déroutant s'il n'est pas compris

Bonjour Sébastien

Merci pour tes explications.

Il reste que le fonctionnement du compilateur que tu expliques très bien, peut s'avérer être un véritable piège (dans lequel je suis tombé à pieds joints) au programmeur.

Sans doute qu'un autre délimiteur d'arguments/paramètres que la virgule eut été moins ambigüe (mais il y aurait eu peut-être d'autres complications ailleurs).

Dans le cadre de tes excellentes présentations d'EXCEL et de VBA je te suggère d'avertir le lecteur sur l'intérêt de consulter (et de respecter à 100 %) les spécifications du langage et de joindre un exemple à l'appui.

Sur la problématique exposée et expliquée dans ce fil, je joins un autre petit exemple (déroutant (?) mais explicable) de ce type de piège :

Sub test()

    valeur1 = 100
    valeur2 = 3

    MsgBox "Valeur1=" & valeur1 & "Valeur2=" & valeur2    ' sans call et sans ( ) ET avec une expression consciemment programmée
                                                          ' en une "expression de chaine" => affiche Valeur1=100 Valeur2=3   => OK

    MsgBox ("Valeur1=" & valeur1 & "Valeur2=" & valeur2)  ' avec call et sans ( ) ET avec une expression consciemment programmée
                                                          ' en une "expression de chaine" => affiche Valeur1=100 Valeur2=3   => OK

    MsgBox valeur1, valeur2         ' sans Call   et sans ( ) et non respect "fonctionnel" des paramètres de la fonction MsgBox
                                    ' MAIS sans erreur de compilation => Affiche 100 ET 3 boutons (à cause de valeur2=3 !) => donc PIEGE
   ' MsgBox (valeur1, valeur2)       ' sans Call   et avec ( ) => erreur compilation donc pas de piège
   ' Call MsgBox valeur1, valeur2    ' avec Call   et sans ( ) => erreur compilation donc pas de piège
    Call MsgBox(valeur1, valeur2)   ' avec Call   et avec ( ) et non respect "fonctionnel" des paramètres de la fonction MsgBox
                                    ' MAIS sans erreur de compilation => Affiche 100 ET 3 boutons (à cause de valeur2=3 !) => donc PIEGE

End Sub

Le cours VBA je l'ai avant tout fait pour des personnes débutantes et expliqué de manière à le rendre accessible justement à ceux qui débutent ... Ce type d'explication est à mon sens trop pointu pour un cours comme celui-ci.

Mais j'ajouterai peut-être une astuce à ce sujet dans "Astuces VBA"

Rechercher des sujets similaires à "dysfonctionnement fonction vba arraysortasc pack xlp"