Fonction Join - Conversion d'un Array de type Long ou Double ou Date (etc) en Array de String
Bonjour,
Suite à cette contribution, je m'interroge aujourd'hui sur la fonction Join.
En effet, celle-ci comporte des petits "manquements" :
- Elle ne traite que des Array de String,
- 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:
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).
- 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:
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 :
Citation:
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.
- 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:
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 :
Citation:
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.
- 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:
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 :
Citation:
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 :
- Verriez-vous une autre méthode?
- 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...