Bonjour,

Suite à cette contribution, je m'interroge aujourd'hui sur la fonction Join.

En effet, celle-ci comporte des petits "manquements" :
  1. Elle ne traite que des Array de String,
  2. Elle ne traite que des Array à 1 dimension.


Traitons ces deux cas l'un après l'autre.

Test du passage, en paramètre de la fonction Join, d'un Array de type Long :
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
Option Explicit
 
Const MIN As Long = 5000
Const MAX As Long = 35000
Const SEP As String = " - "
 
Sub DemoJoin()
Dim i&, s$
   ReDim v(MIN) As Long
   For i = LBound(v) To UBound(v)
      v(i) = i
   Next
   On Error Resume Next
   s = Join(v, SEP)
   If Err.Number > 0 Then MsgBox Err.Description
   On Error GoTo 0
End Sub
Il nous faut donc convertir cet Array en String, pour cela il existe plusieurs méthodes de conversion.
J'en connais personnellement 3, mais peut-être en auriez-vous une (ou plusieurs) autre(s) plus performante(s).

  1. Via une variable de type String intermédiaire :
    Le principe :
    On boucle sur notre Array (de type Long) et on stocke, à chaque boucle, son contenu dans une variable String.
    Le code de démo :
    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
    Option Explicit
     
    Const MIN As Long = 5000
    Const MAX As Long = 35000
    Const SEP As String = " - "
     
    Sub TestViaString()
    Dim i&, j&, t#, s$
       Debug.Print "Méthode du String intermédiaire : "
       For j = MIN To MAX Step MIN
          ReDim v(j) As Long
          s = vbNullString
          For i = LBound(v) To UBound(v)
             v(i) = i
          Next
          t = Timer
          For i = LBound(v) To UBound(v)
             s = s & v(i) & SEP
          Next
          s = Left(s, Len(s) - Len(SEP))
          Debug.Print Right(s, Len(CStr(j))) & " ==> " & Timer - t & " sec. Lenght : " & Len(s)
       Next
    End Sub
    Les résultats :
    Méthode du String intermédiaire :
    5000 ==> 0,046875 sec. Lenght : 33894
    10000 ==> 0,201171875 sec. Lenght : 68895
    15000 ==> 0,494140625 sec. Lenght : 108895
    20000 ==> 0,9609375 sec. Lenght : 148895
    25000 ==> 1,611328125 sec. Lenght : 188895
    30000 ==> 2,595703125 sec. Lenght : 228895
    35000 ==> 6,689453125 sec. Lenght : 268895
    Conclusion :
    L'augmentation exponentielle de la durée d'exécution en fonction du nombre d'éléments à ajouter à notre variable String me fait conclure que cette manière de procéder n'est valable que sur de "petites" variables tableaux.

  2. La conversion en Array de String via CStr et utilisation de la fonction Join :
    Le principe :
    On passe les valeurs de notre Array de Long, dans un Array de String, en utilisant la fonction de conversion CStr.
    Une fois cette conversion réalisée, on utilise Join.
    Le code de démo :
    Ayant déjà testé, j'ai augmenté délibérément les valeurs des constantes MIN (de 5 000 à 500 000) et MAX (de 35 000 à 3 500 000).
    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
    Option Explicit
     
    Const MIN As Long = 500000
    Const MAX As Long = 3500000
    Const SEP As String = " - "
     
    Sub TestConversionCStr()
    Dim i&, j&, t#, str$
       Debug.Print "Méthode de conversion (CStr) : "
       For j = MIN To MAX Step MIN
          ReDim v(j) As Long
          str = vbNullString
          For i = LBound(v) To UBound(v)
             v(i) = i
          Next
          t = Timer
          ReDim s(j) As String
          For i = LBound(v) To UBound(v)
             s(i) = CStr(v(i))
          Next
          str = Join(s, SEP)
          Debug.Print Right(str, Len(CStr(j))) & " ==> " & Timer - t & " sec. Lenght : " & Len(str)
       Next
    End Sub
    Les résultats :
    Méthode de conversion (CStr) :
    500000 ==> 0,54296875 sec. Lenght : 4388896
    1000000 ==> 1,3046875 sec. Lenght : 8888897
    1500000 ==> 2,01953125 sec. Lenght : 13888897
    2000000 ==> 2,751953125 sec. Lenght : 18888897
    2500000 ==> 3,548828125 sec. Lenght : 23888897
    3000000 ==> 4,26171875 sec. Lenght : 28888897
    3500000 ==> 5,05078125 sec. Lenght : 33888897
    Conclusion :
    On voit, en utilisant cette méthode, que l'augmentation de la durée d'exécution n'est plus exponentielle comme dans notre premier essai.
    Les temps peuvent paraître long (plus de 5 secondes) mais il faut relativiser.
    En effet, il n'est pas fréquent de croiser des Array de plus de trois millions d'éléments.

  3. La conversion en Array de String SANS CStr et avec utilisation de la fonction Join :
    Le principe :
    On passe les valeurs de notre Array de Long, dans un Array de String.
    Une fois cette conversion réalisée, on utilise Join.
    Le code de démo :
    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
    Option Explicit
     
    Const MIN As Long = 500000
    Const MAX As Long = 3500000
    Const SEP As String = " - "
     
    Sub TestViaArrayString()
    Dim i&, j&, t#, str$
       Debug.Print "Méthode Array de String : "
       For j = MIN To MAX Step MIN
          ReDim v(j) As Long
          str = vbNullString
          For i = LBound(v) To UBound(v)
             v(i) = i
          Next
          t = Timer
          ReDim s(j) As String
          For i = LBound(v) To UBound(v)
             s(i) = v(i)
          Next
          str = Join(s, SEP)
          Debug.Print Right(str, Len(CStr(j))) & " ==> " & Timer - t & " sec. Lenght : " & Len(str)
       Next
    End Sub
    Les résultats :
    Méthode Array de String :
    500000 ==> 0,48828125 sec. Lenght : 4388896
    1000000 ==> 1,1640625 sec. Lenght : 8888897
    1500000 ==> 1,81640625 sec. Lenght : 13888897
    2000000 ==> 2,62890625 sec. Lenght : 18888897
    2500000 ==> 3,234375 sec. Lenght : 23888897
    3000000 ==> 4,609375 sec. Lenght : 28888897
    3500000 ==> 4,62109375 sec. Lenght : 33888897
    Conclusion :
    Les résultats des deux dernières méthodes sont équivalents.
    Cela m'amène à penser que l'une utilise l'autre en arrière-plan.
    Dans quel sens, cela je ne sait pas, et ça ne revêt pas un grand intérêt pour le sujet.


Après cette mini étude, je pencherais pour la méthode de conversion avec CStr pour remédier au souci n° 1.
J'ai également testé avec des Array de Double et de Date.
Un "poil" plus lent, mais c'est entièrement normal, du aux "poids" différents de ces types de variable.

2 questions donc :
  1. Verriez-vous une autre méthode?
  2. Les tests présentés ici (y compris ceux avec Double et Date) sont-ils suffisants?


Merci déjà rien que pour la lecture de ce long sujet...