j'ai un problème avec l'adressage dans un tableau :
Une mise en Tblo :
VB:
tbl = Feuil1.Range("A2:C8")
Je souhaiterai avoir le résultat de la combinaison "Nom1" et "Niveau 5", sans passer par une boucle...une écriture du style (un peu comme on fait avec un . Cells(,) :
Tbl("Nom1","5") qui donne "Val1" comme résultat....
Naturellement mon fichier est plus important (450000 lignes), j'ai utilisé les formules INDEX/EQUIV, mais très/trop long en calcul ..donc j'essaye avec un Tblo...et souhaite éviter de faire une boucle, car dans l'ensemble de mon code, il y a un calcul qui me donne"Nom1 et "5", donc c'est pour cette raison que je cherche l'adressage de "Nom1"/"5" directement et sans passer par une boucle de recherche...
J'ai pensé que peut-être il y avait une solution en utilisant le tuto Dictionary de JB, mais...pas fonctionné....
450,000 lignes, arf ! moi je mets tout ça sur SQL Server (2017 Express est free)
Après c'est une nano seconde pour remonter avec une close "Where" depuis VBA ADO...
Mais bon il y aura peut-être une solution sans boucle sur ton tableau, mais là je ne la vois pas...
Je pense même que les Auto-Filters d'Excel s'arrêtent avant autant de lignes...
J'ai testé mais si Eric veut trouver le résultat de la combinaison "Nom1" et "Niveau 5" (comme une clause "Where", il fait comment sans un loop sur Tbl ?
Dim tbl, lig As Variant, nom As String, niv As Long
tbl = Feuil1.Range("A2:C8")
nom = "Nom1": niv = 5
lig = Application.Match("nom1", Columns(1), 0)
If IsError(lig) Then
MsgBox "non trouvé"
Else
MsgBox tbl(lig + niv - 2, 3)
End If
Equiv() sur feuille est relativement rapide.
Mais si tu en as qq milliers à faire ça peut valoir le coup de faire une boucle pour récupérer dans un dictionary la 1ère ligne de chaque nom, et faire le même calcul pour avoir la ligne de la donnée.
eric
Edit : pour info 1000 Equiv() sur 450000 lignes (500 au milieu, 500 à la fin) prennent quand même 18s (bouzin de 12 ans d'age)
Si beaucoup il vaut mieux accepter une boucle pour construire un dictionnaire
Oui, cela donne exactement le résultat que je recherchais à obtenir...Mais effectivement, je cherche la rapidité et donc la proposition
Mais si tu en as qq milliers à faire ça peut valoir le coup de faire une boucle pour récupérer dans un dictionary la 1ère ligne de chaque nom, et faire le même calcul pour avoir la ligne de la donnée.
Oui, justement, j'avais trouvé (=recherche doublons, en faisant mondico(c)="") les noms, mais je n'arrivais pas à retrouver le numéro de ligne, d'où le recours à un adressage...
Ci joint le fichier de base (8000 lignes). Je cherche par exemple la ligne de 43840R3C4 avec comme Niveau "-9", car ensuite, j'effectuerai des calculs avec les valeurs se trouvant dans H:AB
Bon finalement ce n'est pas si terrible avec un simple loop sur Tableau.
Je ne vais pas poster un fichier avec 450,000 Rows, (dans le 10Mb) mais donc j'ai fait un fichier avec un bouton qui va créer les 450,000 rows en 1 minute plus/moins
Ensuite vous pourrez tester le Loop avec le bouton dédié, c'est assez rapide quand même (plus que je ne pensais)
Effectivement, c'est rapide !! Merci !! Je pensais qu'une boucle (je faisais avec For...mais peut-être j'avais mis trop de "conditions") était plus lente....d'où la recherche avec les noms dan le Tblo....
On peut imaginer de sauvegarder l'index et ne le créer qu'une fois.
Code:
Sub essai()
'--- construction index
Tbl = [H2].CurrentRegion
Set d = CreateObject("scripting.dictionary")
For i = 1 To UBound(Tbl)
temp = Tbl(i, 1)
If d.exists(temp) Then
idx = d(temp)
Else
idx = d.Count + 1
d(temp) = idx
End If
Next i
'--- sauvegarde index
[E2].Resize(d.Count) = Application.Transpose(d.keys)
[F2].Resize(d.Count) = Application.Transpose(d.items)
'-----interrogation
nom = "Nom2"
idx = d(nom)
niveau = 3
valeur = Tbl(idx, niveau + 1)
MsgBox valeur
End Sub