Incompatibilité de type

Résolu/Fermé
Claire.Iz Messages postés 16 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 15 décembre 2014 - Modifié par pijaku le 10/12/2014 à 07:55
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 - 11 déc. 2014 à 15:00
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

pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 750
Modifié par pijaku le 10/12/2014 à 08:13
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
Claire.Iz Messages postés 16 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 15 décembre 2014
10 déc. 2014 à 11:07
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
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 750
10 déc. 2014 à 11:18
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
Claire.Iz Messages postés 16 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 15 décembre 2014
10 déc. 2014 à 11:35
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
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 750
10 déc. 2014 à 11:48
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
Claire.Iz Messages postés 16 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 15 décembre 2014
Modifié par pijaku le 10/12/2014 à 14:59
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
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 750
10 déc. 2014 à 15:02
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
Claire.Iz Messages postés 16 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 15 décembre 2014 > pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024
10 déc. 2014 à 15:17
Comment je peux mettre une pièce jointe dans mes messages?
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 750 > Claire.Iz Messages postés 16 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 15 décembre 2014
10 déc. 2014 à 15:43
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
Claire.Iz Messages postés 16 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 15 décembre 2014 > pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024
10 déc. 2014 à 22:11
https://www.cjoint.com/?DLkwqzbEUDF
Voilà le lien. Encore merci
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 750
11 déc. 2014 à 07:42
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
Claire.Iz Messages postés 16 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 15 décembre 2014
11 déc. 2014 à 14:58
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
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 750
11 déc. 2014 à 15:00
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