Vous utilisez un navigateur obsolète. Il se peut que ce site ou d'autres sites Web ne s'affichent pas correctement. Vous devez le mettre à jour ou utiliser un navigateur alternatif.
Bonsoir
Quel serait pour vous le code le plus simple pour récupérer en vba une partie de nom de fichier
j'ai x fichiers dont le nom est
Jeux Liste 1 - 20.xlsx
Jeux Liste 21 - 40.xlsx
Jeux Liste 41 - 60.xlsx
.....
Jeux Liste 121 - 140.xlsx
Il me faudrait récupérer en temps que string la partie par exemple "1 - 20" ; "41 - 60" , "121 - 140" ..etc
Vu que c'est variable en longueur entre 6 et 9 .. ??? avec les espaces plus les digits de 1 à 3
Vous me direz on peut retirer les espaces .. Oui , mais pas les digits !!
je pense que cela ira plus vite avec vos avis
merci
Function Extract_Donnees$(ByVal Nom_Fichier$)
Dim Compteur%, t$
For Compteur = 1 To Len(Nom_Fichier)
If IsNumeric(Mid(Nom_Fichier, Compteur, 1)) Then t = Mid$(Nom_Fichier, Compteur): Exit For
Next Compteur
Extract_Donnees = Left(t, Len(t) - (Len(t) - InStrRev(t, ".") + 1))
End Function
ou bien
VB:
Function Extract_Donnees$(ByVal Nom_Fichier$)
Dim Compteur%, t$
t = Nom_Fichier
For Compteur = 1 To Len(Nom_Fichier)
If Not (Mid(t, Compteur, 1)) Like "[0-9|-]" Then Mid(t, Compteur, 1) = " "
Next Compteur
Extract_Donnees = Trim(t)
End Function
et pour reprendre l'exemple de @Yeahou a savoir ne faire que 9 tours de boucle maxi (1 to 9)
on simplifie l’après boucle
VB:
Function Extract_Donnees$(ByVal Nom_Fichier$)
Dim Compteur%, t$, debut&, x&
t = Nom_Fichier: debut = Len(t)
For Compteur = 0 To 9
x = InStr(1, t, Compteur): If x < debut And x > 0 Then debut = x
Next Compteur
Extract_Donnees = Left(Mid$(t, debut), InStr(1, Mid$(t, debut), ".") - 1)
End Function
Function Extract_Donnees$(ByVal Nom_Fichier$)
Dim Compteur%, Compteur2 As Byte
Compteur = Len(Nom_Fichier)
For Compteur2 = 0 To 9
' calcul l'index de debut de la chaine numerique avec instr +app.min + 2d instr
If InStr(1, Nom_Fichier, Compteur2) Then Compteur = Application.Min(Compteur, InStr(1, Nom_Fichier, Compteur2))
Next Compteur2
'restitution de la chaine avec mid et les index debut et fin par le instr "." +calcul - compteur
Extract_Donnees = Mid$(Nom_Fichier, Compteur, InStr(Compteur, Nom_Fichier, ".") - Compteur)
End Function
Function Extract_Donnees$(ByVal Nom_Fichier$)
Dim Compteur%, t$, debut&, x&
t = Nom_Fichier: debut = Len(t)
For Compteur = 0 To 9
' calcul l'index de debut de la chaine numerique avec instr tout court
x = InStr(1, t, Compteur): If x < debut And x > 0 Then debut = x
Next Compteur
'restitution de la chaine avec le left du mid et les index debut et fin par le instr "."
Extract_Donnees = Left(Mid$(t, debut), InStr(1, Mid$(t, debut), ".") - 1)
End Function
1° ma ligne de calcul debut est donc moins lourde car app.min est plus lourd qu'un test "< que" et tu utilise deux fois le calculateur avec instr dans ta ligne de calcul(1 fois pour le instr de i et une fois pour le app.min)
2° ma ligne de restitution ne recalcule pas le instr "." - compteur
j'utilise le left de la chaîne a partir de l'index début et non la chaîne entière par le mid
il est vrai que si on voulais parfaire et éviter les double calculs on devrait variabiliser
En l’occurrence ici on réutilise la variable "t"
COMME SUIT
VB:
Function Extract_Donnees$(ByVal Nom_Fichier$)
Dim Compteur%, t$, debut&, x&, Res$
t = Nom_Fichier: debut = Len(t)
For Compteur = 0 To 9
' calcul l'index de debut de la chaine numerique avec instr tout court
x = InStr(1, t, Compteur): If x < debut And x > 0 Then debut = x
Next Compteur
t = Mid$(t, debut):Extract_Donnees = Mid$(t, 1, InStr(1, t, ".") - 1)
End Function
de même que pour encore plus alléger on pourrait ne pas allouer de mémoire supplémentaire avec "T" et utiliser nom_fichier qui est déjà alloué en mémoire (comme tu le fait )
comme suit (j'ai raccourci le nom de l'argument)
VB:
Function Extract_Donnees$(ByVal NF$)
Dim Compteur%, debut&, x&
debut = Len(NF)
For Compteur = 0 To 9
x = InStr(1, NF, Compteur): If x < debut And x > 0 Then debut = x
Next Compteur
NF = Mid$(NF, debut): Extract_Donnees = Mid$(NF, 1, InStr(1, NF, ".") - 1)
End Function
si je devais merger nos deux ecritures ce serait serait alors comme suit
VB:
Function Extract_Donnees$(ByVal NF)
Dim Compteur%, t$, debut&, x&, Res$
debut = Len(NF)
For Compteur = 0 To 9
x = InStr(1, NF, Compteur): If x < debut And x > 0 Then debut = x
Next Compteur
Extract_Donnees = Mid$(NF, debut, InStr(1, NF, ".") - debut)
End Function
il est vrai que la boucle sur le instr 0-9 sera plus performante sur des chaînes plus longues car !!! maxi on boucle 9 fois
sur des chaines ou le premier chiffre est placé a moins de 9 caractères avec 9 comme premier caractère numérique elle serait alors moins véloce que q'une boucle sur le len
c'est un choix cornélien
l’économie est là me semble til
tu test if instr pour zapper le zéro(non trouvé) + un re test avec instr(le meme test) + app.min
alors q'il est moins lourd (me semble t il de tester if x>0
VB:
If InStr(1, Nom_Fichier, Compteur2) Then Compteur = Application.Min(Compteur, InStr(1, Nom_Fichier,
ici je fait qu'un seul test instr et je test un numérique > 0 et < que le debut
VB:
x = InStr(1, NF, Compteur): If x < debut And x > 0 Then debut = x
nous savons très bien tout les deux que le plus gourmand en VBA c'est bien le travail sur des chaînes en string
mon écriture est aussi plus accessible a un novice je pense
Merci Patrick pour tes explications détaillées.
Tu as raison pour l'optimisation de la boucle et la variabilisation.
C'est toujours un plaisir de discuter performance de code.
Bonjour
Merci bien à tous , hier soir un peu fatigué j'ai pas tout testé
Je viens de reprendre , en fait cela fonctionne depuis le #7
Finalement j'ai opté pour un des derniers de Patrick que j'essaie de comprendre ( le principe)
Question : pourquoi les $ en fin de variable même dans celui de Function ?
pour obliger une chaine texte, non un variant, en retour de fonction, c'est pareil que
Function Extract_Donnees(ByVal Nom_Fichier as String) as String
Comme tu as besoin d'une chaine texte et que tes valeurs sont numériques avec opérateur - (ex: 1 - 20), c'est plus propre et sûr