IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBA Discussion :

Créer une fonction avec un tableau en argument


Sujet :

VBA

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2013
    Messages : 5
    Points : 1
    Points
    1
    Par défaut Créer une fonction avec un tableau en argument
    Bonjour à tous,

    Je me suis mis à VBA tout récemment dans le cadre d'un projet pour mes études.
    Seulement, j'ai encore beaucoup de difficultés à appréhender ce langage notamment dans la déclaration des variables.
    Dans le cas présent, je veux calculer une erreur quadratique à partir de 2 tableaux à 1 dimension (des colonnes).

    Je commence donc par créer 2 variables en Public car elles vont me servir dans tout le code :

    Public TabR(1 To 372, 1 To 18) As Double
    Public TabExp(1 To 372, 1 To 18) As Double


    Puis je remplis ces 2 tableaux avec les données excel :

    Sub Creation_Tableau_R_et_Exp()
    For i = 1 To 372
    For j = 1 To 18
    TabR(i, j) = Cells(i + 2, j + 2)
    TabExp(i, j) = Cells(i + 2, j + 22)
    Next
    Next
    'MsgBox TabR(372, 18)
    End Sub


    C'est là que je crée une fonction qui va prendre en argument 2 tableaux quelconque et faire le calcul voulu :

    Function EQmin(T1 As Range, T2 As Range)
    Dim T1 As Variant, T2 As Variant
    Dim x As Double
    Dim T(1 To 372) As Double
    'x est la sommes des erreurs au carrés pour un t et un i fixé
    For i = 1 To 372
    x = 0
    For j = 1 To 18
    x = (T1(i, j) - T2(i, j)) ^ 2 + x
    Next
    T(i) = x
    Next
    EQmin = T
    End Function


    Enfin j'essaie de voir ce que ça donne en évaluant la 1ère case :

    Sub Test_de_EQmin()
    Dim x As Double
    x = EQmin(TabR, TabExp)(1)
    MsgBox x
    End Sub


    Et là rien n'y fait j'ai un message d'erreur "type d'argument Byref incompatible" ... quelqu'un pourrait me dépanner et m'expliquer pourquoi?

    Merci d'avance !

    PS : je sais que je pourrais tout faire directement sans passer par une fonction mais je vais par la suite utiliser le solveur et je ne vois pas du tout comment faire si je ne passe pas par une fonction ...

  2. #2
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    465
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 465
    Points : 549
    Points
    549
    Par défaut
    bonjour,
    Ta ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x = EQmin(TabR, TabExp)(1)
    me semble drôle.

    si x est un nombre, je m'attends à voir ta fonction EQmin définie comme retournant un nombre. Donc quand tu as créé ta fonction EQmin(....) tu aurais pu écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function EQmin(T1 As Range, T2 As Range) as double
    Function EQmin(T1 As Range, T2 As Range) as string
    Function EQmin(T1 As Range, T2 As Range) as boolean
    si tu t'attends à ce que ta fonction te renvoie un nombre (double) ou une chaine de caractères ou une valeur logique Vrai/Faux.

  3. #3
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    465
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 465
    Points : 549
    Points
    549
    Par défaut
    Puisque tu parles de définition de variable et que tu débutes en VBA, puis-je te conseiller d'utiliser l'option EXPLICIT ?

    Tout en haut de ton écran VBA, là où tu avais écrit Public TABr(...., tu commences par écrire Cela te forceras à définir toutes tes variables. Tu devras rajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim i as integer
    Dim J a integer
    C'est plus propre, facilitera la maintenance. Cela permettra à d'autres personnes de lire plus facilement ton code et de t'aider. Cela t'évitera des fautes.
    Bonne continuation.

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2013
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Merci de ta réponse.
    En fait le EQmin prend en argument deux tableaux (de dimensions n lignes m colonnes) et est censé renvoyer un tableau (de dimension n ligne et 1 colonne).
    Le truc c'est que j'ai défini 2 tableaux au préalable (que j'ai appelé TabR et TabExp), et lorsque j'essaie d'appliquer ma fonction EQmin à ces 2 tableaux, (j'écris EQmin(TabR, TabExp)(1) par exemple pour avoir le 1er élément du tableau EQmin(TabR,TabExp) ) je reçois un msg d'erreur "incompatibilité de type"... je bloque dessus depuis un moment

  5. #5
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    465
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 465
    Points : 549
    Points
    549
    Par défaut
    Encore un petit commentaire, si tu le permets.
    dans ta ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x = EQmin(TabR, TabExp)(1)
    que veux-tu faire avec ce " (1) " ?

    Lorsque tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x = EQmin(TabR, TabExp)
    , tu dis déjà en VBA "Mettez dans la variable x le résultat de la fonction EQmin en utilisant les données TabR et TabExp".
    Je ne vois pas ce que ce (1) vient faire ici.


    Autre chose :
    tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Function EQmin(T1 As Range, T2 As Range)
    Dim T1 As Variant, T2 As Variant
    En compilant to code, VBA te dira qu'il y a une définition double de T1 et T2. La ligne "Dim T1 As Variant, T2 As Variant" est inutile parce que tu dois déjà avoir défini plus haut tes valeurs T1 et T2 pour pouvoir les utiliser dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Function EQmin(T1 As Range, T2 As Range)

  6. #6
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    465
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 465
    Points : 549
    Points
    549
    Par défaut
    Tu as défini x comme un nombre double et tu as définis EQmin comme un tableau de nombres. C'est ça qui cloche.
    essaye
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function tatatat()
    Dim x(27) As Double
    MsgBox EQmin(Range("c3:d4"), Range("e5:g6"))(1)
    end function

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2013
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    hmm non ça ne marche toujours pas..
    En fait je me demande si le problème n'est pas la fonction EQmin car quand je fais le débogage, il surligne le passage "EQmin = T" et m'annonce EQmin = Nothing

  8. #8
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    465
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 465
    Points : 549
    Points
    549
    Par défaut
    pour tester tes questions, voici ce que j'ai copié/coller (puis modifié) dans une feuille Excel 2007
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    Function test_EQmin()
        Dim x(27) As Double
        MsgBox EQmin(Range("c3:d4"), Range("e5:g6"))(1)
    End Function
    Function EQmin(T1 As Range, T2 As Range)
    'Dim T1 As Variant, T2 As Variant
    Dim i As Integer
    Dim j As Integer
    Dim x As Double
    Dim T(1 To 37) As Double
     
    'x est la sommes des erreurs au carrés pour un t et un i fixé
     
    For i = 1 To 37
        x = 0
        For j = 1 To 18
            x = (T1(i, j) - T2(i, j)) ^ 2 + x
            Debug.Print "i=" & i, "j=" & j, x   'Cela permet de voir l'évolution des valeurs t s'assurer que la boucle tourne.
        Next
        T(i) = x
    Next
    EQmin = T
     
    End Function
    Est-fort différent de ce que tu as ?

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2013
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    j'ai malheureusement toujours la même erreur au niveau de "EQmin = T" avec le débogage qui m'annonce 'EQmin = Nothing'

  10. #10
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    465
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 465
    Points : 549
    Points
    549
    Par défaut
    Si on se base toujours sur ton code original
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Function EQmin(T1 As Range, T2 As Range)
    Dim T1 As Variant, T2 As Variant
    Dim x As Double
    Dim T(1 To 372) As Double
    'x est la sommes des erreurs au carrés pour un t et un i fixé
    For i = 1 To 372
    x = 0
    For j = 1 To 18
    x = (T1(i, j) - T2(i, j)) ^ 2 + x
    Next
    T(i) = x
    Next
    EQmin = T
    End Function
    Je comprends pourquoi il n'aime pas ton EQmin = T
    Au Début de ta fonction, tu as écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Function EQmin(T1 As Range, T2 As Range)
    c'est à dire que la fonction EQmin fait quelque chose avec deux données(tableaux).
    A la fin de ta fonction, tu dis "EQmin = un tableau". Pour faire cela, tu dois avoir défini EQmin comme étant un tableau. Et cela tu ne l'as pas fait.

    Prenons un exemple simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Function BlahBlah() As String
    Dim strTexte As String
    strTexte = "Picasso fut un grand artiste"       'Je travaille avec une variable de type texte.
    'La fonction BlahBlah prend pour valeur le contenu de strTexte qui est du texte.  Tous les deux sont du même format : texte / string.
    blahblah = strTexte
    End Function
     
    Function Blah()
      MsgBox BlahBlah
    End Function
    Dans cet exemple, j'ai défini la fonction BlahBlah comme retournant une valeur texte. Donc, lorsque tu exécutes la fonction Blah, la ligne avec le MsgBox va fonctionner comme si elle affichait une valeur texte.

    Il ne reste plus qu'à faire comme dans cet exemple simple mais avec un tableau plutôt que du texte.....

  11. #11
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2013
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    c'est exactement ça !!!

    Je le faisais avec EQmin (...) as Range depuis tt a l'heure ça ne marchait pas
    mais la j'ai remplacé Range par Double() et ça marche nickel!!
    Par contre si tu pouvais m'expliquer la différence entre le fait d'écrire Range ou Double()?

    En tout cas merci beaucoup ;-)

  12. #12
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    465
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 465
    Points : 549
    Points
    549
    Par défaut
    il faudrait donc que tu commences ta fonction par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function EQmin (T1,T2) as Array
    Le probleme, c'est que il n'est pas possible de définir une fonction pour qu'elle te retourne un tableau. Voir Help : "Although a procedure can't return an array, it can return a Variant that contains an array. To simulate a Public array in a class module, use a set of Property procedures that accept and return a Variant containing an array." Il faudra donc aller un pas plus loin pour définir un Variant avec un tableau mais cela c'est une autre histoire et il faut que je cherche.

  13. #13
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    465
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 465
    Points : 549
    Points
    549
    Par défaut
    En attendant, tu peux verifier le contenu de ton tableau EQmin en affichant toutes les valeurs du tableau en utilisant un debug.print ou dans une feuille Excel.

  14. #14
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    465
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 465
    Points : 549
    Points
    549
    Par défaut
    Je crois que hier nous étions en train d'écrire nos réponses en même temps et nos messages se sont croisés.

    Différence entre Range et Double
    Double est utilisé pour un nombre réel. Un et un seul nombre. Par exemple 7.65 . Double est utilisé dans les VBA (MS Excel, MS Access, ...) de la suite MS Office.
    Range est typique à MS Excel. Cela représente une zone sur ta feuille Excel. cette Zone rectangulaire peut être plus ou moins grande. Cette zone peut contenir une seule cellule ou plusieurs cellules. Dans Excel, une cellule peut contenir du texte, une date, un nombre : n'importe quoi et ça c'est merdique.
    (d'autres diront "c'est de la flexibilité") parcque Excel a tendance à 'enjoliver' les infos et le code 01 sera changé en 1 parce que Excel croit que c'est un nombre et laisse tomber le zéro.

Discussions similaires

  1. [v8.3] Créer une fonction avec un argument "tableau de composites" ?
    Par pierredesproges dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 30/05/2008, 14h49
  2. Créer une fonction avec nom de DB en argument ?
    Par ctobini dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 03/12/2007, 23h29
  3. [String] formater une chaine avec un tableau d'argument
    Par jakouz dans le forum Collection et Stream
    Réponses: 6
    Dernier message: 14/04/2006, 15h19
  4. créer une fonction avec parametre optionnel
    Par maximenet dans le forum Langage
    Réponses: 2
    Dernier message: 29/01/2006, 20h51
  5. Réponses: 6
    Dernier message: 10/08/2005, 11h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo