Incompatibilité de type

Résolu
Claire.Iz Messages postés 16 Statut Membre -  
pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour,
J'essaye de créer un programme sous VBA mais je rencontre quelques difficultés avec mes tableaux. J'ai créé un nouveau type mais je n'arrive pas à l'utiliser dans mes fonctions
Voici mon code:

Public Type categorieBD
    Nom As String
    indexmin As Integer
    indexmax As Integer
End Type

Function TabSuperFam() As categorieBD
    Dim TabSF() As categorieBD
    TabAliments = RemplissageTabAlim()  ' appel de la fonction, remplissage de tab
    Dim i As Integer    'ligne TabAlim
    i = 0
    Dim j As Integer    'index TabSuperFamille
    j = 0
    'pour tableau index inf = 0, sauf si code contient instruction Option Base 1
    While i < UBound(TabAliments)
            TabSF(j).Nom = TabAliments(i, 1)
            TabSF(j).indexmin = i
            While TabAliments(i, 1) = TabSF(j).Nom 'different de s'ecrit <>
                i = i + 1
            Wend
            TabSF(j).indexmax = i - 1
        j = j + 1
    Wend

    TabSuperFam = TabSF
End Function


Lorsque je compile j'ai une erreur "incompatibilité de type" qui surligne TabSuperFam de l'avant dernière ligne et je ne comprends pas pourquoi puisque ma fonction est déclarée en categorieBD. J'ai tout essayé: avec, sans parenthèses, en déclarant ma fonction comme Variant... Je n'y arrive pas.
Merci d'avance
Claire

5 réponses

  1. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
     
    Bonjour,

    Le problème vient du fait que TabSF est un array de categoryBD, tandis que, de la manière qu'elle est déclarée, ta fonction TabSuperFam n'est pas un array. D'où l'incompatibilité de type.

    Pour pallier à cela, déclare ta fonction comme un array de categoryBD.
    Comment?
    Simplement comme ceci : [parenthèses en fin de ligne]
    Function TabSuperFam() As categorieBD()


    Ensuite, dans ton code, tu va avoir des soucis car ton tableau TabSF n'est ni dimensionné, ni redimmensionné... Il te faudra ajouter, dans le code : ReDim Preserve (voir l'aide sur ces mots clés), comme ceci :

    Function TabSuperFam() As categorieBD()
        Dim TabSF() As categorieBD
        TabAliments = RemplissageTabAlim()  ' appel de la fonction, remplissage de tab
        Dim i As Integer    'ligne TabAlim
        i = 0
        Dim j As Integer    'index TabSuperFamille
        j = 0
        'pour tableau index inf = 0, sauf si code contient instruction Option Base 1
        While i < UBound(TabAliments)
            ReDim Preserve TabSF(j)
            TabSF(j).Nom = TabAliments(i)
            TabSF(j).indexmin = i
            While TabAliments(i, 1) = TabSF(j).Nom 'different de s'ecrit <>
                i = i + 1
            Wend
            TabSF(j).indexmax = i - 1
            j = j + 1
        Wend
    
        TabSuperFam = TabSF
    End Function 


    Nota : [Tu en tiendras compte après avoir régler d'autres petits soucis éventuels] Lorsque l'on utilise des variables tableaux, on peut s'attendre à avoir des grandes "tailles". C'est pourquoi les indices sont le plus souvent déclarés As Long :
        Dim i As Long    'ligne TabAlim
        i = 0
        Dim j As Long    'index TabSuperFamille
        j = 0


    🎼 Cordialement,
    Franck 🎶
    0
  2. Claire.Iz Messages postés 16 Statut Membre
     
    Bonjour,
    Merci de prendre le temps de m'aider mais ça ne marche toujours pas, maintenant à la compilation j'ai une erreur "l'indice n'appartient pas à la sélection" sur la ligne
    TabSF(j).Nom = TabAliments(i)
    (j'ai remplacé i=0 et j=0 par un car j'ai rajouté option base 1 au début de mon code mais même sans ça, ça ne compile pas)

    De plus, ça me pose problème d'utiliser des array , déjà parce que je ne sais pas les manipuler mais aussi parce que j'utilise d'autres tableaux qui ne sont pas des arrays dans mon programme (notamment TabAlim). Y a -t-il incompatibilité entre tableaux et array ou puis-je transférer des données de l'un à l'autre sans problème?

    Merci d'avance
    0
    1. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      de rien.
      1- tu n'as pas tenu compte de ma seconde remarque. "l'indice n'appartient pas à la sélection" est du au fait que tu ne dimensionnes ni ne redimensionnes tes variables tableaux (tableau = array. C'est la même chose en Anglais).
      Donc, regarde mon code donné précédemment. Il te faudra ajouter, dans le code : ReDim Preserve (voir l'aide sur ces mots clés)...
      '....
      While i < UBound(TabAliments)
              ReDim Preserve TabSF(j)
              TabSF(j).Nom = TabAliments(i)
              '...
      0
  3. Claire.Iz Messages postés 16 Statut Membre
     
    Si, j'en ai tenu compte, j'ai fais un copier coller du code que vous m'avez donné, donc avec ReDim Preserve mais ça ne marche pas...
    0
    1. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      Si la ligne :
      TabSF(j).Nom = TabAliments(i) 
      te renvoie une erreur l'indice n'appartient pas à la sélection c'est soit que :
      - tu n'as pas redimensionné TabSF(j)
      - TabAliments(i) n'existe pas.

      Sans le fichier difficile de continuer à t'aider.
      0
  4. Claire.Iz Messages postés 16 Statut Membre
     
    Voilà mon code en entier (j'ai pas mis la fin parce que je refais la dernière fonction deux fois avec d'autres colonnes de TabAlim.

    Option Explicit
    Option Base 1
    
    Public TabAliments As Variant
    
    Public Type categorieBD
        Nom As String
        indexmin As Integer
        indexmax As Integer
    End Type
    
    Public Type aliment
        SuperFam As String
        Fam As String
        SousFam As String
        Nom As String
        Energie As Single
        Prot As Single
        Glu As Single
        Lip As Single
    End Type
    
    Public TabFamille As categorieBD
    Public TabSousFamille As categorieBD
    Public TabSuperFamille As categorieBD
    
    
    
    
    Function RemplissageTabAlim() As Variant
    
        Dim TabAlim As Variant
        Worksheets("Tableaux").Select
        'attention, cette méthode fait que l'indice min du tableau est 1, plus 0
        TabAlim = Range("A2:H710").Value
        Worksheets("Donnees").Select
        If Range("E6").Value Like "*Végétarien*" Then
            Dim TabTemp() As Variant
            Dim i As Integer
            Dim j As Integer
            Dim k As Integer
            i = 1
            k = 1
            Do While i <= UBound(TabAlim, 1)
               If TabAlim(i, 2) Like "*Viande*" Then
                i = i + 1
               End If
               If TabAlim(i, 2) <> "Viande" Then 'If (TabAlim(i,2) Like"*Viande*")=False?
                Exit Do
               End If
            Loop
            While i <= UBound(TabAlim, 1)
                j = 1
                While j <= UBound(TabAlim, 2)
                    ReDim Preserve TabTemp(k, j)
                    TabTemp(k, j) = TabAlim(i, j)
                    j = j + 1
                Wend
                i = i + 1
                k = k + 1
            Wend
            ReDim TabAlim(k, j)
            TabAlim = TabTemp
        End If
        RemplissageTabAlim = TabAlim
    End Function
      
      Function TabSuperFam2() As categorieBD()
        Dim TabSF() As categorieBD
        TabAliments = RemplissageTabAlim()  ' appel de la fonction, remplissage de tab
        Dim i As Long    'ligne TabAlim
        i = 1
        Dim j As Long    'index TabSuperFamille
        j = 1
        'pour tableau index inf = 0, sauf si code contient instruction Option Base 1
        While i < UBound(TabAliments)
            ReDim Preserve TabSF(j)
            TabSF(j).Nom = TabAliments(i, 1)
            TabSF(j).indexmin = i
            While TabAliments(i, 1) = TabSF(j).Nom 'different de s'ecrit <>
                i = i + 1
            Wend
            TabSF(j).indexmax = i - 1
            j = j + 1
        Wend
    
        TabSuperFam2 = TabSF
    End Function
    


    Merci encore
    0
    1. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      1- Lorsque vous placez du code sur notre forum, merci d'utiliser les balises code à votre disposition.
      Le mode d'emploi (au cas ou) est ICI.

      2- si j'ai demandé le classeur c'est également pour avoir accès aux données de remplissage des variables tableaux...
      Là, tes codes ne me donnent pas trop d'indications...
      0
      1. Claire.Iz Messages postés 16 Statut Membre > pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention  
         
        Comment je peux mettre une pièce jointe dans mes messages?
        0
      2. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773 > Claire.Iz Messages postés 16 Statut Membre
         
        Pour transmettre un fichier, il faut passer par un site de pièce jointe tel que cjoint.com

        Va sur ce site : https://www.cjoint.com/
        Clic sur parcourir,
        Cherche ton fichier,
        clic sur ouvrir,
        Clic sur "Créer le lien cjoint",
        Copier le lien,
        Revenir ici le coller dans une réponse...
        0
      3. Claire.Iz Messages postés 16 Statut Membre > pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention  
         
        https://www.cjoint.com/?DLkwqzbEUDF
        Voilà le lien. Encore merci
        0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
     
    Bonjour Claire.Iz, le forum,

    Pas mal de petites choses à revoir. Notamment concernant les variables tableaux. Je t'invite à relire quelques tutoriels à ce sujet et notamment celui-ci :
    https://silkyroad.developpez.com/vba/tableaux/

    Dans ta fonction
    RemplissageTabAlim()
    , tu redimensionnes ton tableau temporaire en incrémentant la première dimension :
    ReDim Preserve TabTemp(k, j)
    j est "fixe" car il ne peut prendre des valeurs que de 1 à 8. k par contre est dynamique car tu ne sais pas combien de valeurs lui attribuer. Or, dans une variable tableau dynamique, seule la seconde dimension peut être dynamique.
    Donc, il convient d'utiliser :
    ReDim Preserve TabTemp(1 To j, 1 To k) 

    Comme on sait que j maxi est égal à 8, il te faut l'écrire comme ceci :
    ReDim Preserve TabTemp(1 To 8, 1 To k) 


    Tu te rends alors compte que la variable tableau est inversée en lignes et colonnes. C'est comme cela que fonctionnent les tableaux. Pour l'obtenir dans le même "sens" que la mise en forme dans une feuille excel, il te faut utiliser la fonction Excel Transpose. Tu peux le faire au moment de la restitution :
    ReDim TabAlim(j, k)
    TabAlim = TabTemp

    devient donc :
    ReDim TabAlim(k, j)
    TabAlim = Application.Transpose(TabTemp)


    Deuxièmement, dans ta fonction
    TabSuperFam2()
    tu boucles
    While TabAliments(i, 1) = TabSF(j).Nom
    et tu incrémentes i. Que se passe t'il si les deux éléments TabAliments(i, 1) et TabSF(j).Nom sont toujours identiques? i s'incrémente tout le temps... Jusqu'à ce que i soit supérieur à UBound(TabAliments). A ce moment là, VBA te renvoie l'erreur "l'indice n'appartient pas à la sélection". Comment pallier à cela?
    Il te faut tester si i est supérieur à UBound(TabAliments), si c'est le cas, on sort de la boucle.
    Essaye donc en remplaçant :
    While TabAliments(i, 1) = TabSF(j).Nom 'different de s'ecrit <>
        i = i + 1
    Wend

    par :
    Do While TabAliments(i, 1) = TabSF(j).Nom 'different de s'ecrit <>
        i = i + 1
        If i > UBound(TabAliments) Then Exit Do
    Loop


    Voici, en prime, ton fichier corrigé : https://www.cjoint.com/c/DLlhXgbg0Xt
    0
    1. Claire.Iz Messages postés 16 Statut Membre
       
      Merci infiniment, c'est vraiment très gentil d'avoir fait tout ça pour m'aider. J'étais complètement bloquée (par des détails peut être très simples pour les initiés mais comme mon prof d'info a décidé qu'on était assez grands pour apprendre VBA tous seuls en un mois sans nous donner de cours bah, voilà le résultat...) . Merci encore, même si je crois que ce n'est pas la fin de mes ennuis avec Excel.
      0
    2. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      Si ton sujet est résolu, indique le comme tel (dans ton premier message clique sur "Marquer comme résolu".

      Sinon, de rien et...
      @+
      0