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

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    ingénieur IAA
    Inscrit en
    juin 2018
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : ingénieur IAA
    Secteur : Industrie

    Informations forums :
    Inscription : juin 2018
    Messages : 3
    Points : 1
    Points
    1
    Par défaut retour function variable type personnalisé
    Bonjour à tous,

    Je travaille sur VBA Excel. Je fais une boucle pour parcourir 15 cuves et à chaque cuve j'interroge une base historisée. Je collecte ces données dans une variable type personnalisé qui est défini en variable public dans un autre module.
    Quand je compile mon code, j'ai une erreur: "incompatibilité de type: tableau ou type défini par l'utilisateur" sur selectionne_t_arempli(n)



    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
    For n = 0 To 14
     
    'cette boucle fait fonctionner pour ma cuve KA100 la boucle suivante
    'selectionne_t_aremplir_rempli = remplir_tableau(selectionne_t_aremplir, rs, TAG_EV_SIROPKA100, date_debut, date_fin)
     
        selectionne_t_rempli(n) = remplir_tableau(selectionne_t_aremplir(n), rs, selectionne_tag_utilise(n), date_debut, date_fin)
     
            bornesup = UBound(t_aremplir)
            borneinf = LBound(t_aremplir)
     
            For i = 0 To bornesup
            remp = 0
            eventreecuve = False
     
                Select Case i
                Case Is = 0 And t_aremplir(i).valeur = 1 And t_aremplir(i).statut = True
                Case Is = 0 And t_aremplir(i).valeur = 0 And t_aremplir(i).statut = True
                Case Is <> 0 And t_aremplir(i).valeur = 1 And t_aremplir(i).statut = True
                remp = t_aremplir(i).heure
                If t_aremplir(i).valeur = 1 Then eventreecuve = True Else eventreecuve = False
     
                Case Is <> 0 And t_aremplir(i).valeur = 0 And t_aremplir(i).statut = True
                remp = t_ev_laitmais_liqa(i).heure
                If t_aremplir(i).valeur = 1 Then eventreecuve = True Else eventreecuve = False
     
                End Select
     
            If remp = 0 Then
            Else
            ReDim Preserve intermed(j + 1)
            intermed(j).cuveKA100 = True
            intermed(j).evcuveKA100 = eventreecuve
                Select Case j
                Case Is = 0
                    intermed(j).modecuveKA100 = ""
                Case 0 To bornesup - 1
                    Select Case eventreecuve
                    Case Is = False And intermed(j - 1).evcuveKA100 = False
                    intermed(j).modecuveKA100 = "4nonrempf"
                    Case Is = False And intermed(j - 1).evcuveKA100 = True
                    intermed(j).modecuveKA100 = "3nonrempd"
                    Case Is = True And intermed(j - 1).evcuveKA100 = False
                    intermed(j).modecuveKA100 = "1rempd"
                    Case Is = True And intermed(j - 1).evcuveKA100 = True
                    intermed(j).modecuveKA100 = "2rempf"
                    End Select
                End Select
            j = j + 1
            ReDim Preserve intermed(j - 1)
            End If
     
            Next i
     
     Next n
    En plus dans la fonction "remplir_tableau" (qui fonctionne bien) j'appelle chaque argument passé en paramètre directement dans la fonction selectionne_t_rempli(n) et je force le résultat de ces functions en boolean pour
    selectionne_t_rempli(n) [fonction typée en retour variant] et en String pour selectionne_tag_utilise(n) [fonction typée en retour Variant]

    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
    Public Function selectionne_tag_utilise(ByVal i As Integer) As Variant
     
    Dim t_listecuvelu() As Variant
    ReDim t_listecuvelu(0 To 14, 0 To 3)
     
    t_listecuvelu(0, 0) = "KA"
    t_listecuvelu(1, 0) = "KB"
    t_listecuvelu(2, 0) = "KC"
    t_listecuvelu(3, 0) = "KD"
    t_listecuvelu(4, 0) = "KF"
    t_listecuvelu(5, 0) = "KG"
    t_listecuvelu(6, 0) = "KH"
    t_listecuvelu(7, 0) = "KI"
    t_listecuvelu(8, 0) = "BA"
    t_listecuvelu(9, 0) = "BB"
    t_listecuvelu(10, 0) = "BC"
    t_listecuvelu(11, 0) = "BD"
    t_listecuvelu(12, 0) = "BE"
    t_listecuvelu(13, 0) = "BF"
    t_listecuvelu(14, 0) = "BH"
     
    For i = 0 To UBound(t_listecuvelu)
     
    selectionne_tag_utilise = CStr("TAG_EV_SIROP" & t_listecuvelu(i, 0) & "100")
     
    Next
     
    End Function

    Je ne mets pas la function avec boolean car c'est équivalent au string.
    Par contre, je mets la troisième en type personnalisé et je n'arrive pas à retourner le résultat de cette function dans un type personnalisé
    Le type perso que j'utilise est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Type type_tag
        heure As Date   
        niveau As Boolean
        statut As Boolean
        valeur As Double
    End Type
    Même en retour type variant ça ne fonctionne pas.


    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
    Public Function selectionne_t_aremplir(ByVal i As Integer) As type_tag
     
    Dim t_listecuvelu() As Variant
    ReDim t_listecuvelu(0 To 14, 0 To 3)
     
    t_listecuvelu(0, 0) = "KA"
    t_listecuvelu(1, 0) = "KB"
    t_listecuvelu(2, 0) = "KC"
    t_listecuvelu(3, 0) = "KD"
    t_listecuvelu(4, 0) = "KF"
    t_listecuvelu(5, 0) = "KG"
    t_listecuvelu(6, 0) = "KH"
    t_listecuvelu(7, 0) = "KI"
    t_listecuvelu(8, 0) = "BA"
    t_listecuvelu(9, 0) = "BB"
    t_listecuvelu(10, 0) = "BC"
    t_listecuvelu(11, 0) = "BD"
    t_listecuvelu(12, 0) = "BE"
    t_listecuvelu(13, 0) = "BF"
    t_listecuvelu(14, 0) = "BH"
     
    For i = 0 To UBound(t_listecuvelu)
     
    t_aremplir = "t_ev_entree_" & t_listecuvelu(i, 0) & "100"
    t_aremplir =CType(("t_ev_entree_" & t_listecuvelu(i, 0) & "100"), type_tag)
    selectionne_t_aremplir = t_aremplir
     
    Next
     
    End Function
    Est-ce que quelqu'un pourrait m'aider à trouver une piste svp? J'aimerais vraiment faire la boucle pour éviter des tartines de codes.
    Est-ce que je devrait jouer au poupée russes sur mon type personnalisé avec plusieurs fonctions? j'aimerais éviter ça aussi.
    Merci d'avance,

    Emmanuel

  2. #2
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur informatique indépendant
    Inscrit en
    novembre 2003
    Messages
    14 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur informatique indépendant
    Secteur : Enseignement

    Informations forums :
    Inscription : novembre 2003
    Messages : 14 967
    Points : 41 331
    Points
    41 331
    Billets dans le blog
    62
    Par défaut
    Salut.

    Sauf erreur, je ne vois nulle part la déclaration de la variable selectionne_t_rempli. Or, il y a de fortes chances que ce soit là que réside le problème. Pourrais-tu nous donner sa ligne de déclaration et dans quel contexte tu l'emploies?

    En plus, je ne suis pas fan du tout des variables publiques. Normalement, il y a toujours moyen de s'en passer en utilisant les arguments de procédures/fonctions.


    Voici un exemple de l'utilisation d'une fonction qui renvoie une valeur d'un type personnalisé, valeur qui est poussée dans un tableau. Ca me semble coller à ton cas et cela pourra peut-être t'aider. L'exemple s'appuie sur le tableau structuré suivant
    Nom : 2020-01-14_054137.png
Affichages : 31
Taille : 3,7 Ko

    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
    Type Contact
      ID As Long
      FirstName As String
      LastName As String
    End Type
     
    Function getContact(ID As Long) As Contact
      Dim Result As Long
      Dim r As Range
     
        Result = Evaluate("iferror(match(" & ID & ",t_Contacts[ID],0),0)")
        If Result > 0 Then
          Set r = Range("t_Contacts").ListObject.ListRows(Result).Range
          With getContact
            .ID = ID
            .FirstName = r(r.ListObject.ListColumns("Prénom").Index).Value
            .LastName = r(r.ListObject.ListColumns("Nom").Index).Value
          End With
        End If
    End Function
     
    Sub Test()
      Dim Contacts(1 To 2) As Contact
     
      Contacts(1) = getContact(45)
      Contacts(2) = getContact(84)
    End Sub
    Nom : 2020-01-14_054117.png
Affichages : 29
Taille : 87,2 Ko
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Une fois pour toutes, je donne mon avis. Je ne vais pas le répéter à chaque message...
    Si je propose une solution générique sur votre solution spécifique, c'est parce que, fainéant de nature, je privilégie le réutilisable...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    ingénieur IAA
    Inscrit en
    juin 2018
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : ingénieur IAA
    Secteur : Industrie

    Informations forums :
    Inscription : juin 2018
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    merci Pierre pour ton conseil. Concernant selectionne_t_rempli il s'agit en fait d'une fonction qui me donne une boolean qui sert au retour de ma fonction remplir_tableau (celle qui fonctionne avec les variables écrites en dur).
    Je l'ajoute du coup pour montrer, je l'avais évincé pour ne pas alourdir le message.

    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
    Public Function selectionne_t_rempli(ByVal i As Integer) As Boolean
     
    Dim t_listecuvelu() As Variant
    ReDim t_listecuvelu(0 To 14, 0 To 3)
    Dim telcuve As String
     
    t_listecuvelu(0, 0) = "KA"
    t_listecuvelu(1, 0) = "KB"
    t_listecuvelu(2, 0) = "KC"
    t_listecuvelu(3, 0) = "KD"
    t_listecuvelu(4, 0) = "KF"
    t_listecuvelu(5, 0) = "KG"
    t_listecuvelu(6, 0) = "KH"
    t_listecuvelu(7, 0) = "KI"
    t_listecuvelu(8, 0) = "BA"
    t_listecuvelu(9, 0) = "BB"
    t_listecuvelu(10, 0) = "BC"
    t_listecuvelu(11, 0) = "BD"
    t_listecuvelu(12, 0) = "BE"
    t_listecuvelu(13, 0) = "BF"
    t_listecuvelu(14, 0) = "BH"
     
    For i = 0 To UBound(t_listecuvelu)
     
    selectionne_t_rempli = CBool("t_ev_entree_" & t_listecuvelu(i, 0) & "100_rempli")
     
    Next
     
    End Function
    A priori sur cette fonction pas de problème. Le compilateur ne mentionne rien.

    Pierre, j'ai bien vu comment remplir un tableau de type personnalisé. Merci pour ton exemple bien détaillé.
    J'identifie les choses comme ça: ta sub contacts correspond à ma fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t_rempli = remplir_tableau(t_aremplir, rs, tag_utilise, date_debut, date_fin)
    Si je l'écrit avec les variables toutes prêtes pour ma première cuve, j'ai ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t_ev_entree_KA100_rempli = remplir_tableau(t_ev_entree_KA100, rs, TAG_EV_SIROPKA100, date_debut, date_fin)
    t_ev_entree_KA100_rempli ,t_ev_entree_KA100, TAG_EV_SIROPKA100 toutes les trois des variables publiques qui fonctionnent correctement.

    C'est faire varier les caractères KA par KB pouis KA puis BA puis BB puis BC etc en conservant le type de chacune de ces variables qui me pose problème.

    Je force t_ev_entree_KA100_rempli en générique retour de la fonction selectionne_t_rempli en type boolean et ça a l'air de fonctionner.
    Je bloque juste sur le type personnalisé. En gros je souhaite générer ma variable de type personnalisé selon les caractères KA, KB etc
    car j'ai déclaré toutes ces variables public dans un module que je dédie à mes variables public.

    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
    Public t_ev_entree_KA100() As type_tag
    Public t_ev_entree_KB100() As type_tag
    Public t_ev_entree_KC100() As type_tag
    Public t_ev_entree_KD100() As type_tag
    Public t_ev_entree_KF100() As type_tag
    Public t_ev_entree_KG100() As type_tag
    Public t_ev_entree_KH100() As type_tag
    Public t_ev_entree_KI100() As type_tag
    Public t_ev_entree_BA100() As type_tag
    Public t_ev_entree_BB100() As type_tag
    Public t_ev_entree_BC100() As type_tag
    Public t_ev_entree_BD100() As type_tag
    Public t_ev_entree_BE100() As type_tag
    Public t_ev_entree_BF100() As type_tag
    Public t_ev_entree_BH100() As type_tag
    Sinon en terme de test j'ai essayé de faire tourner le code sur la function selectionne_t_rempli
    Il déroule le code et donne une erreur d'exécution '13': incompatibilité de type
    Idem si je force en CBool ma concatenation.

    Si je déclare dans la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim selectionne_t_t_rempli As boolean
    il met un message sur cette variable:
    erreur de compilation: Déclaration existant dans la portée en cours

    Si quelqu'un a une autre idée, je reste encore ouvert :-)

  4. #4
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur informatique indépendant
    Inscrit en
    novembre 2003
    Messages
    14 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur informatique indépendant
    Secteur : Enseignement

    Informations forums :
    Inscription : novembre 2003
    Messages : 14 967
    Points : 41 331
    Points
    41 331
    Billets dans le blog
    62
    Par défaut
    Dans le premier bloc de code de ton premier message, tu mets ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    selectionne_t_rempli(n) = remplir_tableau(selectionne_t_aremplir(n), rs, selectionne_tag_utilise(n), date_debut, date_fin)
    Tel que présenté là, selectionne_t_rempli ne peut pas être une fonction. VBA va considérer cela comme un tableau dont tu essaies de valoriser l'élement n° n. C'est donc normal que tu aies un souci sur cette ligne-là.

    Du coup, je ne comprends plus très bien le contexte dans lequel tu travailles.

    Au passage, tu peux remplacer ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim t_listecuvelu() As Variant
    ReDim t_listecuvelu(0 To 14, 0 To 3)
    par celui-ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Dim t_listecuvelu(0 To 14, 0 To 3)
    Car le redim ne sert que si tu utilises des variables pour le dimensionner.


    Tu parles de Sub Contacts mais je n'ai pas proposé une sub Contacts dans mon code. J'ai un type personnalisé, une fonction qui renvoie une variable de ce type et un tableau (le tableau Contacts) qui emmagasine les contacts renvoyés par GetContact...

    Je ne comprends pas les déclarations de ton bloc de code Public t_ev_entree_KA100() As type_tag et suivantes... Tu es sûr que tu dois déclarer des tableaux de type type_tag? Dans l'utilisation que tu essaies d'en faire sur la ligne qui pose problème, cela ne peut pas être un tableau. Je ne comprends toujours pas l'intérêt de les déclarer publiques.


    Ton code selectionne_t_rempli = CBool("t_ev_entree_" & t_listecuvelu(i, 0) & "100_rempli") va forcément générer une erreur puisque tu essaies de convertir en boolean une valeur de type texte (car ce qu'il y a entre les parenthèses sera bien évalué comme texte). Je suppose que tu veux tester la variable qui porte le nom qui est recréé dans les parenthèses, mais tu ne peux pas travailler avec un adressage indirect de variables en VBA pur. Ca n'existe pas, à ma connaissance.

    Tu peux travailler avec un tableau Clé/Valeur, une collection, voire un dictionnaire, pour pouvoir récupérer la valeur de l'élément du tableau/collection/dico en fonction de sa clé. A ce stade, la finalité de l'opération est toujours floue pour moi.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Une fois pour toutes, je donne mon avis. Je ne vais pas le répéter à chaque message...
    Si je propose une solution générique sur votre solution spécifique, c'est parce que, fainéant de nature, je privilégie le réutilisable...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    ingénieur IAA
    Inscrit en
    juin 2018
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : ingénieur IAA
    Secteur : Industrie

    Informations forums :
    Inscription : juin 2018
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Merci Pierre pour tes remarques,
    J'apprend que c'est de l'adressage de variable indirect ce que je veux faire et comme tu dis ce n'est pas possible en VBA pur...
    Dans cette macro j'ai un code principale qui a pour objet de piocher dans une BDD historisé des infos pour identifier quand une installation industrielle fonctionne et quelle cuve a-t-elle rempli.
    C'est ce qui me fait interroger de multiple cas différents que j'essaie au mieux de faire fonctionner en boucle... quand c'est possible!
    Dommage pour moi, je garderais mes tartines de code.
    Merci en tout cas pour cette éclairage.

  6. #6
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur informatique indépendant
    Inscrit en
    novembre 2003
    Messages
    14 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur informatique indépendant
    Secteur : Enseignement

    Informations forums :
    Inscription : novembre 2003
    Messages : 14 967
    Points : 41 331
    Points
    41 331
    Billets dans le blog
    62
    Par défaut
    Si tu ajoutes les initiales KA, KB, ... dans le type Type_Tag, tu pourrais créer une fonction qui recherche le type_tag basé sur les initiales. Ca résoudrait ton problème, il me semble.

    L'adressage indirect en VBA ne peut se faire, ou plutôt être simulé, que sur un tableau (ou une collection ou un dictionnaire, qui sont des tableaux Clé/Valeurs). Il te suffirait d'écrire une fonction qui récupère un type_tag selon ses initiales...
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Une fois pour toutes, je donne mon avis. Je ne vais pas le répéter à chaque message...
    Si je propose une solution générique sur votre solution spécifique, c'est parce que, fainéant de nature, je privilégie le réutilisable...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

Discussions similaires

  1. Réinitialiser une variable de type personnalisé
    Par rom1_am dans le forum Général VBA
    Réponses: 6
    Dernier message: 19/11/2008, 08h52
  2. Réponses: 9
    Dernier message: 27/10/2005, 19h15
  3. variable type tableau (vector) statique / constants
    Par Kaktus dans le forum SL & STL
    Réponses: 5
    Dernier message: 13/10/2005, 23h46
  4. Réponses: 1
    Dernier message: 27/07/2005, 18h08
  5. retour de variable d'une fonction
    Par thunderblade dans le forum ASP
    Réponses: 4
    Dernier message: 28/04/2005, 14h27

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