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 :

Passer un tableau Variant/String en Variant/Long


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 2 266
    Par défaut Passer un tableau Variant/String en Variant/Long
    Bonjour à tous,

    J'ai une chaine de nombres que je splitte.
    Pour des raison de performance je voudrais passer le résultat en Long, mais malgré la boucle il reste obstinément en String (?).
    Au final je pense que je créerai un autre tableau() as Long pour un meilleur gain mais j'aimerai bien comprendre.
    Quelqu'un a une idée du pourquoi et si une autre écriture permettrai de réaliser ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Sub test2()
        Dim ref1 As Variant, i As Long
        ref1 = "1:2:3:4"
        ref1 = Split(ref1, ":")
        For i = 0 To 3
            ref1(i) = CLng(ref1(i))
        Next i
    End Sub
    A tout hasard j'ai tenté ref1(i) = ref1(i) + 0 mais même punition
    eric

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour eriiic,
    Teste avec val("2")

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 2 266
    Par défaut
    Bonne idée, mais non... C'est pareil :-)

  4. #4
    Rédacteur/Modérateur

    Avatar de Jean-Philippe André
    Homme Profil pro
    Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Inscrit en
    Juillet 2007
    Messages
    14 678
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Canada

    Informations professionnelles :
    Activité : Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 14 678
    Par défaut
    Salut,

    commence par simplifier ton code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ref1 = "1:2:3:4"
    ref1 = Split(ref1, ":")
    devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ref1 = Split("1:2:3:4", ":")
    Cycle de vie d'un bon programme :
    1/ ça fonctionne 2/ ça s'optimise 3/ ça se refactorise

    Pas de question technique par MP, je ne réponds pas

    Mes ouvrages :
    Migrer les applications VBA Access et VBA Excel vers la Power Platform
    Apprendre à programmer avec Access 2016, Access 2019 et 2021

    Apprendre à programmer avec VBA Excel
    Prise en main de Dynamics 365 Business Central

    Coffrets disponibles de mes ouvrages : https://www.editions-eni.fr/jean-philippe-andre
    Pensez à consulter la FAQ Excel et la FAQ Access

    Derniers tutos
    Excel et les paramètres régionaux
    Les fichiers Excel binaires : xlsb,

    Autres tutos

  5. #5
    Expert confirmé
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Par défaut
    Bonjour eriiic,
    Il n'est jamais bon de jouer avec le typage des variables en VBA
    la fonction Split induit pour VBA un typage en String, typage qu'il garde en mémoire et te "resert"
    Typer en Variant ne permet que de laisser à VBA le soin de décider du type. Une fois le type décidé, VBA n'en permet pas la modification (question de la gestion "idoine" d'occupation en mémoire)
    Je ne vois pas de solution vraiment totalement "saine" autre que du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Dim ref1 As Variant, ref2() As Long, i As Long
      ref1 = "1:2:3:4"
      ref1 = Split(ref1, ":")
      ReDim ref2(UBound(ref1))
       For i = 0 To 3
            ref2(i) = CLng(ref1(i))
        Next i
    MsgBox TypeName(ref1(0)) & vbCrLf & TypeName(ref2(0))
    Amitiés

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 2 266
    Par défaut
    @Jean-Philippe
    j'ai simplifié pour le forum, en fait ref1 est le résultat de plusieurs opérations de chaines.

    @unparia
    C'est ce que je me suis 'résolu' à faire, sans trop me forcer vu qu'un tableau Long sera le plus performant.
    Mais je m'étonne de ne pas avoir remarqué ça plus tôt.

    Une fois le type décidé, VBA n'en permet pas la modification
    ça n'a l'air qu'être que dans le cas d'un tableau résultant d'un Split.

    Si je dimensionne moi-même mon tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        Dim ref1(0 To 3) As Variant, i As Long
        ref1(0) = "1"
        ref1(0) = 1
    ou même un variant transformé 'automatiquement' en tableau pour se rapprocher du cas du Split
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        Dim v
        v = [A1:A4].Value 'chaines
        v(1, 1) = 1
    mes Variant/String se transforment bien en Variant/Integer
    Je dis bizarre ce tableau issu de Split... :-)

  7. #7
    Invité
    Invité(e)
    Par défaut
    En fait le cheval d'Henri IV était baie blanc c'était son nom.

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 2 266
    Par défaut
    Patrick le pb se pose plutôt ici :
    Nom : 2018-04-12_23-02-43.png
Affichages : 1170
Taille : 20,9 Ko

    Après passage dans la boucle on devrait avoir des Integer


    Mais ton intervention n'aura pas été inutile puisque c'est en faisant la capture que je me suis aperçu de la différence fondamentale qui explique ce comportement.

    Si on regarde la variable elle-même (Ref1 ici dans la capture) elle est de type Variant/String !
    Dans un tableau 'normal' où les valeurs peuvent passer de Variant/String <--> Variant/Long, la variable elle-même est de type Variant/Variant.

    Avec Split() on se retrouve donc avec une variable Variant ne pouvant pas varier :-s
    Drôle de concept qui me dépasse. Obélix dirait "Ils sont fous ces ricains" :-)
    Je pense qu'il faut se faire une raison.
    Merci à tous :-)
    eric

  9. #9
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut
    Bonjour !

    Citation Envoyé par eriiic Voir le message
    ça n'a l'air qu'être que dans le cas d'un tableau résultant d'un Split.
    Oui comme clairement indiqué dans l'aide VBA de Split !


    Citation Envoyé par eriiic Voir le message
    Après passage dans la boucle on devrait avoir des Integer
    Et non comme déjà évoqué juste au dessus et déjà précédemment par unparia (Salut !),
    la variable tableau résultant de Split étant déclarée soit en String soit en Variant/String par défaut
    comme du reste c'est clairement visible dans ta capture des fenêtres Espions & Variables locales

    Ce n'est donc pas une simple variable Variant mais une variable Variant/String.

    ___________________________________________________________________________________________________________
    Je suis Paris, Egypte, Nigeria, New-York, Mogadicio, Barcelone, London, Manchester, Stockholm, Istanbul, Berlin, Nice, Bruxelles, Charlie, …

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 2 266
    Par défaut
    Bonjour Marc-L

    ça n'a l'air qu'être que dans le cas d'un tableau résultant d'un Split.
    Oui comme clairement indiqué dans l'aide VBA de Split !
    rien vu sur le type de tableau retourné dans l'aide 2010.
    Qu'as-tu vu de si clair ?
    eric

  11. #11
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut

    Dans mon aide, il est indiqué plusieurs fois « sous-chaînes » et du reste comme sur MSDN,
    en lisant l'explication de chacun de ses arguments.

    Si l'aide apporte un doute, en cours d'exécution la consultation de la fenêtre Variables locales l'ôte …

  12. #12
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    re
    salut eriic

    Split, fonction

    Voir aussi Exemple Particularités
    Description
    Renvoie un tableau de base
    zéro à une dimension contenant le nombre spécifié de sous-chaînes.
    Syntaxe
    Split(expression[,
    delimiter[, limit[,
    compare]]])
    La syntaxe de la fonction Split comprend les arguments nommés suivants :

    souschaines!!!!!! donc string sinon ils auraient ecris nombres
    split est une fonction texte du debut a la fin
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  13. #13
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut
    Citation Envoyé par pijaku Voir le message
    Sauf pour le Split qui lui reste à 0.
    Salut Franck !     J'évoquais bien Array et non Split


    Citation Envoyé par eriiic Voir le message
    Quelqu'un a une idée si une autre écriture permettrai de réaliser ça ?
    On va pouvoir enfin entrer dans le vif du sujet : oui bien sûr, élémentaire mon cher Watson
    via le B-A-BA d'Excel comme déjà démontré sur ce forum (hein Patrick !) : Evaluate

  14. #14
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 903
    Billets dans le blog
    36
    Par défaut
    Bonjour

    Citation Envoyé par eriiic Voir le message
    Bonjour à tous,

    J'ai une chaine de nombres que je splitte.
    Pour des raison de performance je voudrais passer le résultat en Long, mais malgré la boucle il reste obstinément en String (?).
    eric
    Par curiosité, J'ai un peu changé ton code original.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Sub test2()
        Dim ref1 As Variant
        Dim i As Long
        Dim a As Long
        ref1 = "1:2:3:4"
        ref1 = Split(ref1, ":")
        For i = 0 To 3
            a = CLng(ref1(i))
            ref1(i) = CLng(ref1(i))
        Next i
    End Sub
    a est vraiment converti en Long. J'ai comme l'impression que c'est juste impossible de mettre dans un tableau en Variant, un élément individuel qui n'est pas du même type que le tableau.

    Et c'est aussi impossible de mettre un élément en string dans un tableau Integer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Sub test3()
        Dim a(2) As Integer
        a(0) = 0
        a(1) = 1
        a(2) = 2
        For i = 0 To 2
            a(i) = CStr(a(i))
        Next
    End Sub
    testé au pas-à-pas Excel 2016. a(1) reste Integer.

  15. #15
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    re
    Bonjour clement marcotte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    J'ai comme l'impression que c'est juste impossible de mettre dans un tableau en Variant, un élément individuel qui n'est pas du même type que le tableau.
     
     Et c'est aussi impossible de mettre un élément en string dans un tableau Integer
    j'ai l'impression que tu confond le tableau et ses items

    c'est pas tablo qui est en string mais ses item !




    ici c'est tablo qui a la propriété car ce n'est pas un tablo au depart c'est un variant et ses item seront des string puisque issus d' un split
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dim tablo as variant
    tablo=split("toto,titi",",")
    ici c'est pour les items la propriété variant et ca me me permet de lui injecter ce que je veux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Sub test3()
    Dim tablo(2) As Variant
    tablo(0) = "toto"
    tablo(1) = 2
    Debug.Print TypeName(tablo)
    Debug.Print TypeName(tablo(0))
    Debug.Print TypeName(tablo(1))
    End Sub
    autrement dit avec un tablo prédimentionné(dim tablo(x,y) as variant ) je peut mettre absolument tout ce que je veux ou presque

    il est evident que si tu declare un tablo dimentionné entres ses parentheses avec une propriété pour ses items tu ne poura pas mettre un autre type que celui declaré

    tout du moins tout ce qui est numerique sera considéré comme string si "as string" par exemple
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  16. #16
    Membre Expert
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 2 266
    Par défaut
    Bonjour,

    voilà.
    Lorsqu'on crée un tableau variant, la variable (et non ses éléments) est Variant/Variant.
    Chaque valeur peut être de n'importe quel type, il dépend de ce qu'on y met et peut donc changer.

    Lorsqu'un tableau variant est créé par Split il est Variant/String (voir capture au #10).
    Toutes ses valeurs sont toujours String. On peut y mettre n'importe quel numérique sans erreur de type mais il sera d'office converti en String.
    eric

  17. #17
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    Dans le cas présent quel est l'intérêt d'utiliser Evaluate?
    Si ce n'est pour gagner 3 lignes de code?

    La demande initiale est relative à un gain de temps d'exécution.
    Or Evaluate est, il me semble (en tout cas à la maison c'est le cas), plus lente qu'une boucle non?

    Excusez la relance, mais j'aime bien comprendre...


    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
    Option Explicit
     
    Private Const Max As Long = 100000
     
    Sub test5()
    Dim chaine As String, tablo As Variant, i As Long, t#
        t = Timer
        chaine = "1,2,3,4,5,6,7,8,9"
        For i = 1 To Max
            tablo = Evaluate("{" & chaine & "}")
        Next
        Debug.Print Timer - t '3,3203125 sec
    End Sub
     
    Sub Demo()
    Dim ref As Variant, i As Long, j As Long, t#
        t = Timer
        For j = 1 To Max
           ref = Array(Split("1:2:3:4:5:6:7:8:9", ":"))
           ReDim Preserve ref(0 To UBound(ref(LBound(ref)))) As Variant
           For i = LBound(ref) + 1 To UBound(ref)
              ref(i) = CLng(ref(LBound(ref))(i))
           Next i
           ref(LBound(ref)) = CLng(ref(LBound(ref))(0))
        Next
        Debug.Print Timer - t ' 1,20703125 sec
    End Sub
     
    Sub tansfert()
    Dim ref As Variant, t#, i As Long, l() As Long, j As Long
        t = Timer
        For j = 1 To Max
           ref = Split("1:2:3:4:5:6:7:8:9", ":")
           ReDim Preserve l(UBound(ref))
           For i = LBound(ref) To UBound(ref)
              l(i) = CLng(ref(i))
           Next i
        Next
        Debug.Print Timer - t ' 0,67578125 sec
    End Sub
    EDIT : après réflexion, Evaluate est plus rapide sur des chaînes plus longues.
    Gros inconvénient, Evaluate plante lorsque la taille de la chaîne atteint la limite de l'Integer (Len(chaine) = 32 767)

  18. #18
    Expert confirmé
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Par défaut
    Bonjour Franck
    Ta remarque est on ne saurait plus pertinente.
    La performance d'un code ne se mesure pas aux nombres de caractères qu'il utilise, mais à sa vitesse d'exécution et à la moindre occupation de l'espace mémoire. S'écarter de cet aspect fondamental est s'égarer.

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

Discussions similaires

  1. Passer un tableau de string à un dll c++
    Par marcus7 dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 08/11/2013, 13h53
  2. [COM] Convertion string en VARIANT
    Par themadmax dans le forum C++
    Réponses: 0
    Dernier message: 21/08/2007, 18h26
  3. Réponses: 5
    Dernier message: 04/06/2007, 17h07
  4. Réponses: 10
    Dernier message: 05/02/2007, 11h21
  5. Passer Tableau de String à une procedure.
    Par JFKen dans le forum Access
    Réponses: 3
    Dernier message: 02/08/2006, 16h26

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