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 :

Appel de tableau par appel indirect


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Inscrit en
    Juillet 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 239
    Par défaut
    Bonjour ,

    J’ai un grand nombre de tableau correspondant à des articles de catégories différentes.
    Ex Articles_alimentaires_Cat1 , Articles_Ménager _Cat2 …

    Ces différents tableaux d’articles ont une structure équivalente ce qui me permet d’implémenter des fonctions communes

    Ex : Calcul_stock_dispo , Calcul_dimension_stock , Calcul_prix_stock , Revaloriser_prix_articles .

    Je voudrais pouvoir modifier les tableaux par groupe sans passer par un appel direct du type Calcul_stock_dispo (Articles_alimentaires_Cat1 )


    J’ai pensé à des structures du type :

    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
     
    Array   Livraison_Mardi  = (Articles_alimentaires_Cat1  , Articles_alimentaires_Cat3  ) 
    Array  Livraison_Mardi (Articles_alimentaires_Cat4  , Articles_alimentaires_Cat3  ) 
    Le problème c’est que ça ne marche pas . 
     
    J’ai implémenter une méthode du type :
     
    Public   Articles_alimentaires_Cat1 ( ) as string
    Public   Articles_alimentaires_Cat2 ( ) as string
    Public   Articles_alimentaires_Cat3 ( ) as string
     
    Sub def_structure 
    Dim MyClasses_M As New Collection
        MyClasses_M.Add Articles_alimentaires_Cat3
           MyClasses_M.Add Articles_alimentaires_Cat1
            MyClasses_M.Add Articles_alimentaires_Cat3
     
    For each catégorie in  MyClasses_M
    Ret =  Revaloriser_prix_articles (  catégorie  , 2.5  )
    Next 
    End sub

    Ca marche pour les procédures qui lisent les valeurs ( ex calcul de stock ) mais pour les fonctions qui modifient les valeurs , le tableau public Articles_alimentaires_CatN n’est pas modifié. Catégorie correspond bien à la copie de Articles_alimentaires_CatN mais la variable globale n’est pas modifés.

    Je précise que ma fonction Revaloriser_prix_articles est définie de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Public function Revaloriser_prix_articles (  byref tab_articles  as variant , augmentation as single )
     
    For N = 1 to ubound (   tab_articles )
    tab_articles ( N  , 4) =  tab_articles ( N  , 4) *  augmentation
     
    Next 
    Revaloriser_prix_articles =  « « 
     
    End function
    Pour une fonction qui ne fait que lire les données sans les modifier ça marche : ex

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Public function  Volumes_stock  ( tab_articles  as variant ) as single
    Volumes_stock   = 0
     
    For N = 1 to ubound (   tab_articles )
    Volumes_stock  = Volumes_stock    +  (     tab_articles ( N  , 6)  *  tab_articles ( N  , 4) *  tab_articles ( N  , 3) *    tab_articles ( N  , 8 ))
     
    Next 
     
    End function
    Pour reformuler ma question,

    est il possible de construire un tableau , une structure , une collection qui contiendrait des nom de Tableaux défini ailleurs?

  2. #2
    pgz
    pgz est déconnecté
    Expert confirmé Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Par défaut
    Bonsoir.

    j'imagine 2 façons de faire. La première, puisque tes tableaux sont de structures identiques, c'est de ne faire qu'un grand tableau, avec une dimension supplémentaire : la catégorie, traduite en index.

    La seconde est d'utiliser une collection, comme dans cet exemple
    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
    Sub subColTableaux()
    Dim Tab1(1 To 2) As String
    Dim Tab2(0 To 1) As Single
    Dim colTab As Collection
     
    Set colTab = New Collection
     
    Tab1(1) = "Bonjour!"
    Tab1(2) = "Bonsoir"
    Tab2(0) = 3.5
    Tab2(1) = 5
     
    colTab.Add Tab1(), "tableau chaînes"
    colTab.Add Tab2(), "tableau numérique"
     
    MsgBox colTab("Tableau chaînes")(1) 'affiche "Bonjour!"
     
    Set colTab = Nothing
    Erase Tab1
    Erase Tab2
    End Sub
    Je rectifie : on peut aussi faire un tableau de tableaux, comme dans cet exemple
    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
    Sub subTabDeTableaux()
    Dim Tab1(1 To 2) As String
    Dim Tab2(0 To 1) As Single
    Dim v(1 To 2) As Variant
     
    Tab1(1) = "Bonjour!"
    Tab1(2) = "Bonsoir"
    Tab2(0) = 3.5
    Tab2(1) = 5
     
    v(1) = Tab1()
    v(2) = Tab2()
     
    MsgBox v(1)(2) 'affiche "Bonsoir"
     
    Erase v
    Erase Tab1
    Erase Tab2
    End Sub
    Cette fois, par contre, on ne travaille qu'avec des index et c'est peut-être moins parlant que les noms de clés de la collection.

    Cordialement,

    PGZ

  3. #3
    Membre expérimenté
    Inscrit en
    Juillet 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 239
    Par défaut
    Bonjour,

    Effectivement on peut faire v(1) = Tab1() ; OK .
    Par contre , comme j'ai tenté de l'expliqué dans mon post , si je veux appeler le tableau Tab1 de façon indirecte ( par ce que l'appel d'un tableau donné se fait d'après 'une combinatoire donnée' à l'instant T ), on ne peut travaillé sur le tableau lui même , on travaille sur une copie qui peut être utilisable pour la lecture mais pas en modification .
    C'est pour ça que dans mon post , je dis que dans une structure de type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    For each catégorie in  MyClasses_M
    Ret =  Revaloriser_prix_articles (  catégorie  , 2.5  )
    Next
    Comme la fonction doit modifier les valeurs du tableau , le résultat n'est pas atteint ( idem si je fais : for each tab_ in array ( Tab1 , tab2 ))
    La seule méthode que j'ai trouvé c'est de donner un numéro à mes tableaux . J'appelle ma fonction en faisant : for each tab in array ( 1 , 2, 3)
    et dans chaque fonction , je dois implémenter une structure case

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    case num_fic = 1 
    Revaloriser_prix_articles (  Tab1  , 2.5  )
    case num_fic = 2 
    Revaloriser_prix_articles (  Tab2  , 2.5  )
     
    case num_fic = 3
    Revaloriser_prix_articles (  Tab3  , 2.5  )
    C'est ce que je voulais simplifer ..Sans succès jusqu'à maintenant.

  4. #4
    pgz
    pgz est déconnecté
    Expert confirmé Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Par défaut
    Bonjour.

    Et pourquoi l'emploi d'une collection ne te convient-il pas?

    PGZ

  5. #5
    Membre expérimenté
    Inscrit en
    Juillet 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 239
    Par défaut
    Bonjour ,

    Je n'ai rien contre les collections mais ça ne resoud pas mon problème si la procédure ou la fonction appelée doit modifier les données ; Le tableau global n'est pas modifié. Si le traitement doit seulement lire les données c'est OK ; Les modifier ça ne marche pas .

    Pour t'en convaincre , exécute l'exemple simple suivant
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
     
    Public TAB1() As String
    Public TAB2() As String
    Public TAB3() As String
     
     
     
    Public Sub Test_Tableaux()
     
    Dim retour() As String
     
    ReDim TAB1(1 To 3)
    ReDim TAB2(1 To 4)
    ReDim TAB3(1 To 5)
     
    TAB1(1) = "Articles Design.1"
    TAB1(2) = "45"
    TAB1(3) = "7"
     
    TAB2(1) = "Articles Design.2"
    TAB2(2) = "40"
    TAB2(3) = "72"
    TAB2(4) = "Rouge"
     
    TAB3(1) = "Articles Design.3"
    TAB3(2) = "60"
    TAB3(3) = "452"
    TAB3(4) = "Rouge"
    TAB3(5) = "1.0"
     
     Dim MyClasses As New Collection
     
               MyClasses.Add TAB1()
               MyClasses.Add TAB2()
                MyClasses.Add TAB3()
     
                liste = "":
                For Each taby In MyClasses
     
                            Mettre_à_jour_tableau (taby)
                Next
     
        MsgBox "En Sortie de la fonction appelante  : " & TAB1(1) & " : " & TAB1(2) & " : " & TAB1(3) & " ; "
     
    End Sub
     
    Public Sub Mettre_à_jour_tableau(ByRef tableau As Variant)
     
    If tableau(2) < 50 And tableau(3) > 4 Then
        tableau(2) = tableau(2) + 50
        tableau(3) = tableau(3) - 1
    End If
     
    If tableau(2) > 40 And tableau(3) > 0 Then
        tableau(1) = tableau(1) & "  Revalorisé " & Date
        tableau(2) = 1
    End If
     
       MsgBox "En sortie Procédure  : " & tableau(1) & " : " & tableau(2) & " : " & tableau(3) & " ; "
     
    End Sub

    Dans l'exemple , on voit que TAB1 n'est pas affecté par les modifications.

    Avec le For Each taby In MyClasses , on fait une copie de TAB1 pour le mettre dans Taby et c'est la copie qui est affecté !

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Par défaut
    Bonsoir,

    Utilise plutôt des dictionnaires.
    Dans VB, la valeur par défaut pour le passage des arguments est "ByRef" (ce qui parfois pose problème si on n'y fait pas attention ! Ce qui n'est pas le cas en VB.Net). Teste ce qui 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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    Public Dico1 As Object
    Public Dico2 As Object
    Public Dico3 As Object
     
    Public Sub Test_Tableaux()
     
    Dim Dic As Object
    Dim Col As New Collection
     
    Set Dico1 = CreateObject("Scripting.Dictionary")
    Set Dico2 = CreateObject("Scripting.Dictionary")
    Set Dico3 = CreateObject("Scripting.Dictionary")
     
    'Attention, la clé doit être unique (ici 0, 1, 2, etc...)
    Dico1.Add 0, "Articles Design.1"
    Dico1.Add 1, "45"
    Dico1.Add 2, "7"
     
    Dico2.Add 0, "Articles Design.2"
    Dico2.Add 1, "40"
    Dico2.Add 2, "72"
    Dico2.Add 3, "Rouge"
     
    Dico3.Add 0, "Articles Design.3"
    Dico3.Add 1, "60"
    Dico3.Add 2, "452"
    Dico3.Add 3, "Rouge"
    Dico3.Add 4, "1.0"
     
    Col.Add Dico1
    Col.Add Dico2
    Col.Add Dico3
     
    For Each Dic In Col
     
        Mettre_à_jour_Dico Dic
     
    Next
     
    For Each Dic In Col
     
        MsgBox "En Sortie de la procédure appelante (Test_Tableaux)  : " & vbCrLf & Dic(0) & vbCrLf & Dic(1) & vbCrLf & Dic(2)
     
    Next
     
     
     
    End Sub
     
    Public Sub Mettre_à_jour_Dico(Dico As Object)
     
        Dico(0) = Dico(0) & "  Revalorisé le " & Date
        Dico(1) = Dico(1) + 50
        Dico(2) = Dico(2) - 2
     
     
       MsgBox "En sortie Procédure (Mettre_à_jour_Dico)  : " & vbCrLf & Dico(0) & vbCrLf & Dico(1) & vbCrLf & Dico(2)
     
    End Sub
    Hervé.

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

Discussions similaires

  1. Diaporame par appel d'images par xml OK mais irrégulier en 2ème lecture
    Par jo99GOD dans le forum ActionScript 1 & ActionScript 2
    Réponses: 0
    Dernier message: 09/08/2013, 18h09
  2. Appel de Webservice par URL: passage de tableau
    Par JScorcho dans le forum Services Web
    Réponses: 0
    Dernier message: 28/04/2011, 23h02
  3. [VB6] Appeler une procedure par son nom.
    Par kenn dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 24/05/2006, 09h29
  4. Réponses: 1
    Dernier message: 15/05/2006, 18h43
  5. Appel de procédure par contenu de variable
    Par lil_jam63 dans le forum Langage
    Réponses: 9
    Dernier message: 13/09/2004, 08h05

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