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

Macros et VBA Excel Discussion :

Problème avec tableaux Variant et X.rows.count sous VBA [XL-2003]


Sujet :

Macros et VBA Excel

  1. #1
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 60
    Par défaut Problème avec tableaux Variant et X.rows.count sous VBA
    bonsoir à tous,

    Voilà j'essai de programmer une fonction sous VBA qui me servira à calculer les résidus d'une régression. Ma fonction ci dessous s'exécute bien et j'utilise des tableaux pour les calculs:

    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
     
    option base 1
    Function OLSStderror(Y As Variant, X As Variant)
    '   Computes OLS Standard Error under the equation Y = a + B1(t)+...+Bk(t)
    '   Works for Simple and Multiple Regression
        '
        '# of Rows & # of columns
        Dim nr, nc As Integer
        nr = X.rows.Count
        nc = X.Columns.Count
        '
        Dim Xb(), betas(), Xbetas(), residuals() As Variant
        ReDim Xb(1 To nc + 1, 1 To nr), betas(1 To nc + 1, 1 To 1), Xbetas(1 To nr, 1 To 1), residuals(1 To nr, 1 To 1) As Variant
        Xb = RegMatrix(X)
        betas = OLS(Y, X)
        Xbetas = Application.MMult(Xb, betas)
        Debug.Print TypeName(Xbetas)
        '
        residuals = MAdd(Y, Xbetas, -1)
        '
    End Function
    comme vous pouvez le constater, j'ai bien essayé de déclarer comme il se doit les arguments des tableaux. Cependant pour Calculer les "residuals", j'ai créer une fonction Madd (addition de matrice) comme suit:

    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
    25
    26
    27
    28
    29
    30
     
    Function MAdd(X As Variant, Y As Variant, Coeff As Single) As Variant
    '   Add or Substract two matrix depending on coeff(-1,1)
    '   The usual matrix addition is defined for two matrices of the same dimensions
        '
        'Check if the two Matrix have the same size
        If X.rows.Count = Y.rows.Count Then
            If X.Columns.Count = Y.Columns.Count Then
            Else: MAdd = "Discrepancy in # C"
                Exit Function
            End If
        Else: MAdd = "Discrepancy in # R"
            Exit Function
        End If
        '
        Dim nr, nc, i, j As Integer
        nr = Y.rows.Count
        nc = Y.Columns.Count
        Dim Temp As Variant
        ReDim Temp(nr, nc)
            '
            'Compute Matrix
            For i = 1 To nr
                For j = 1 To nc
                  Temp(i, j) = X(i, j) + Coeff * Y(i, j)
                Next j
            Next i
            '
        MAdd = Temp
    End Function
    Or la procédure s'arrête à ce niveau (ci dessous au moment du dénombrement) dans la fonction Madd et je ne trouve pas pourquoi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        'Check if the two Matrix have the same size
        If X.rows.Count = Y.rows.Count Then
    D'ailleurs, la fonction Madd fonctionne très bien si je sélectionne des range sous Excel. Pourquoi ne fonctionne t'elle pas avec des tableaux sous VBA? Sachant que lorsque je lui demande le type de variable de Xbetas il me donne bien un variant et il m'affiche que le vartype est 8204 ce qui correspond à une array.


    Any ideas?

    Merci d'avance

    Anthony

  2. #2
    Expert confirmé
    Avatar de Didier Gonard
    Homme Profil pro
    Formateur Office et développeur VBA en freelance
    Inscrit en
    Février 2008
    Messages
    2 805
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Formateur Office et développeur VBA en freelance

    Informations forums :
    Inscription : Février 2008
    Messages : 2 805
    Par défaut
    Bonjour,

    si je comprends bien, tu veux appliquer Rows.count à un array ?

    vois le mode de fonctionnement des variables tableaux ici :

    http://silkyroad.developpez.com/vba/tableaux/

    cordialement,

    Didier

  3. #3
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 60
    Par défaut
    Oui j'ai bien essayé d'utiliser Ubound comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        'Check if the two Matrix have the same size
        If Ubound(X,1)= Ubound(Y,1)Then
            If Ubound(X,2)=  Ubound(Y,2) Then
    mais dans ce cas il m'affiche que la variable X est incompatible avec Ubound. Elle provient d'une range sous Excel. alors que Y est calculée dans la fonction précédente et compatible avec Ubound.
    En fait Ubound fonctionne pour les tableaux VBA seulement alors que X.rows.count fonctionne seulement pour les range provenant d'excel.
    Pas très reglementaire de mettre Ubound sur une variable et .rows/columns.count sur l'autre. N'y a t'il pas un moyen de formaliser les deux?

    Merci de ta réponse quand même Didier

  4. #4
    Expert éminent Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Par défaut
    Bonsoir,
    Tout d'abord, si tu peux déclarer et renommer tes variables convenablement, tu peux t'apercevoir de ce qu'est range et ce qui est tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Function OLSStderror(Y As Range, X As Range)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Function MAdd(W As Range, Z As Variant, Coeff As Single)
    ...etc

  5. #5
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 60
    Par défaut
    J'ai bien compris ton point et je te remercie mais le problème est que j'ai programmé ces fonctions pour deux utilités.

    La première vise à pouvoir les utiliser sous excel directement ce qui nécessite d'utiliser "As range" et "X.rows.count" par exemple. Elles deviennent inutilisables sous VBA directement.

    La seconde est que je veux les utiliser dans des procèdures de types macros qui font intervenir de nombreuses matrices recalculées (tableaux) ce qui nécessite d'utiliser "As variant" et "Ubounb(X,1)". Elles deviennent inutilisables sous excel directement.

    Ne peut-on pas les uniformiser?

    il me reste l'option de mettre une fonction préablable qui transforme les range en tableaux VBA mais qui va sérieusement alourdir le temps de calcul. :s

    Merci de ton aide quand même

  6. #6
    Expert confirmé
    Avatar de Didier Gonard
    Homme Profil pro
    Formateur Office et développeur VBA en freelance
    Inscrit en
    Février 2008
    Messages
    2 805
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Formateur Office et développeur VBA en freelance

    Informations forums :
    Inscription : Février 2008
    Messages : 2 805
    Par défaut
    Bonjour,

    ces fonctions pour deux utilités.
    Donc soit tu programmes 2 fonctions différentes, un filtre dans l'appelante décidant qui appeler, soit tu les construit de façon que suivant un filtre donné ce ne soit pas les même lignes de code qui interagissent, le tronc commun étant identique ?

    Tu peux avoir un select case dans une fonction sans problème....

    Soit encore dans ton code si la source est un range, tu le traduit en array et l'appel de la fonction qui ne traite alors que des array se fait derrière...

    cordialement,

    Didier

  7. #7
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 60
    Par défaut
    Merci Didier pour tes conseils.

    Soit encore dans ton code si la source est un range, tu le traduit en array et l'appel de la fonction qui ne traite alors que des array se fait derrière...
    t'as une petite idée de comment je pourrais faire ça? Est ce qu'on peut directement traduire une range en array? sinon je peux faire un filtre du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if vartype(X) = "Range" then
    'change to an array
    end if
    Merci

    Anthony

  8. #8
    Expert confirmé
    Avatar de Didier Gonard
    Homme Profil pro
    Formateur Office et développeur VBA en freelance
    Inscrit en
    Février 2008
    Messages
    2 805
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Formateur Office et développeur VBA en freelance

    Informations forums :
    Inscription : Février 2008
    Messages : 2 805
    Par défaut
    Bonjour,

    Est ce qu'on peut directement traduire une range en array? sinon je peux faire un filtre du style:
    Oui, c'est tout l'intérêt de la chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Sub ContTab()
    Dim tboExemple As Variant
     
    tboExemple = Range("A1:D100").Value
    End Sub
    te retourne un tab à 2 dimentions

    dans le même ordre d'idée, si tu mets ceci à la suite, tu as l'inverse tout aussi pratique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Range("F1:I100").Value = tboExemple
    cordialement,

    Didier

  9. #9
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 60
    Par défaut
    Merci Didier,

    You are a VBA Wizzard!!!

    Du coup j'ai fait ce petit bout de code en amont:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    '
    Function createMatrix(Z As Range)
    '   Create an array matrix from a range
        Dim nr, nc As Integer
        nr = Z.rows.Count
        nc = Z.Columns.Count
        Dim X As Variant
        ReDim X(nr, nc) As Variant
        X = Z.Value
        createMatrix = X
    End Function
    Merci pour ton aide et joyeuse année à toi!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec tableaux
    Par jockyboss777 dans le forum Langage
    Réponses: 4
    Dernier message: 12/06/2009, 22h39
  2. Problème avec tableaux associatifs
    Par carnifex dans le forum Langage
    Réponses: 6
    Dernier message: 01/07/2008, 16h17
  3. Problème avec SQL dans un tableadapter (select count())
    Par webgig2002 dans le forum VB.NET
    Réponses: 6
    Dernier message: 02/06/2008, 15h08
  4. problème avec tableaux html
    Par pas30 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 20/05/2007, 17h36
  5. Problème avec tableaux dynamiques et procédure
    Par K20 dans le forum Langage
    Réponses: 11
    Dernier message: 06/01/2006, 20h51

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