Recherche multicritères dans tableau structuré
Salut à tous,
J'utilise de plus en plus les tableaux structurés suite à pas mal de vos conseils. Mais je suis un peu perdu sur un sujet, la recherche multicritères.
J'ai vu dans les cours VBA la fonction cellsSearch qui est top, le soucis c'est de déployer les outils sur tous les postes de mon taff. Je voudrais réaliser ce type de recherche en "vrai" VBA pour que ça puisse passer partout. Voici un exemple de tableau:
Item | Année | Poste |
1 | 2023 | Soudage |
2 | 2023 | Montage |
3 | 2024 | Soudage |
4 | 2024 | Montage |
5 | 2024 | Débitage |
En gros j'aimerai pouvoir chercher la ligne en fonction de deux critères, l'année et le poste.
J'ai voulu commencer par lister toutes les lignes contenant l'année 2024, pour ensuite insérer une formule If
qui testerai dans chaque ligne si on retrouve le poste "Montage" dans la colonne "Poste" mais cela ne semble pas fonctionner car cela me renvoie toujours au même nombre "3" ce que je ne comprends pas...
With ExcelDoc.Sheets("Audits").ListObjects("Tableau_Audits")
For Ligne = 2 To .ListRows.Count
MsgBox Ligne
Set Tableau = .ListColumns("Année").DataBodyRange.Find(Right(Date, 4), LookIn:=xlValues)
MsgBox Tableau.Row
Next Ligne
Exit Sub
Sauriez-vous pourquoi ce code me renvoie à cette valeur ?
Edit:
J'ai essayé cela pour voir s'il trouvais les lignes mais sans succès également:
Dim Cellule as Range
For Each Cellule In .ListColumns("Année").DataBodyRange
If Cellule = Right(Date, 4) Then
MsgBox Cellule.Row & "OK"
End If
Next
Exit Sub
Merci.
Bonjour à tous,
T'as pas essayé la fonction =index(plage, equiv(1;(critere 1)*(critere 2);0)) qui va te donner le meme resultat ??
Crdlmt
Salut DjiDji, cette recherche s’inscrit dans une macro globale sur plusieurs tableaux, d’où la nécessité de le traiter en VBA. En gros ma macro vient ouvrir un autre fichier Excel dans lequel je viens chercher la ligne qui contient les deux valeurs pour y insérer une date et un lien hypertexte. Je cherchais justement les Index Equiv sur tableau structuré mais pas encore tout compris à ce sujet...
Testé avec ce code et toujours aucun résultat. Essayé sans le ListColumns pareil. J'en suis presque à revenir à un tableau standard mais j'aimerai passer au dessus
'Définition des objets
Set ExcelApp = CreateObject("Excel.Application")
ExcelApp.Visible = False 'Mettre True pour rendre Excel visible
Set ExcelDoc = ExcelApp.Workbooks.Open(Chemin) 'Ouvre le document Excel
Dim c As Range
Dim Valeur As String
Valeur = "2024"
Set c = Sheets("Audits").ListObjects("Tableau_Audits").ListColumns("Année").DataBodyRange.Find(Valeur, LookIn:=xlValues, lookat:=xlWhole)
If Not c Is Nothing Then
MsgBox c.Address
Set c = Nothing
Else
MsgBox "valeur " & TaValeur & " non trouvée"
End If
Exit Sub
Desolé, je ne te serais d'aucun secours en VBA !
Crdlmt
Pas grave, à force der recherche je vais finir par trouver
J'ai pu avancer un peux grâce à l'aide de Jean-Eric sur un post du forum avec son code:
Sub Test()
Dim Value
Dim rCell As Range
Dim loCol As ListColumn
Dim lRow As Long
Value = "2024"
With Me.ListObjects(1)
Set rCell = .DataBodyRange.Find(what:=Value, LookIn:=xlValues, lookat:=xlWhole)
If Not rCell Is Nothing Then
Set loCol = .ListColumns(rCell.Column - (.HeaderRowRange.Cells(1).Column) + 1)
lRow = rCell.Row - .HeaderRowRange.Row
MsgBox "La valeur cherchée est dans la colonne " & loCol.Name & Chr(10) & "à la ligne " & lRow & "."
Else
MsgBox "La valeur recherchée est inconnue.", vbOKOnly
End If
End With
Set loCol = Nothing
End Sub
Cela m'a permis d'en comprendre un peu plus sur l'utilisation des tableaux, le soucis du find est qu'il ne trouve que la première valeur. J'ai essayé de modifier la code en faisant un find sur une ligne plutôt que sur l'ensemble du tableau, ce qui permettrait de boucler une recherche sur chaque ligne puis d'aller vérifier la seconde valeur, mais je ne vois pas comment cibler la ligne et quand je regarde la page -> https://www.excel-pratique.com/fr/astuces/tableau-structure j'avoue ne pas être sûr de pouvoir le faire.
J'ai un peu avancé sur le sujet grâce à d'autres sujet sur le forum, merci à eriiic, Game Over etc. pour leur participation à ces sujet intéressants.
Je trouve la ligne de ma première recherche, je vérifie la valeur de la cellule de ma seconde recherche par rapport à sa colonne que je connais et la ligne que j'ai déterminé avant. Cela fonctionne bien.
Ensuite je dis que si cela ne correspond pas je fais un Do/Loop Until jusqu'à ce que je trouve une correspondance mais cela ne fonctionne pas encore. Il ne boucle pas toutes les recherches j'ai 3 cases 2024 mais il boucle uniquement entre la première et la seconde. Quelque chose m'échappe encore.
Voici mon sub et en dessous mon fichier test si quelqu'un passe par là et sait ce qui cloche...
Sub Test()
Dim Value
Dim rCell1 As Range
Dim rCell2 As Range
Dim cCell1 As Range
Dim loCol As Long
Dim lRow As Long
Dim myrange1 As Long
Dim myrange2 As Long
Dim Test As Integer
With Me.ListObjects(1)
Value = "2024"
Set rCell1 = .DataBodyRange.Find(what:=Value, LookIn:=xlValues, lookat:=xlWhole)
If Not rCell1 Is Nothing Then
myrange1 = rCell1.Row - .HeaderRowRange.Row
'Set loCol = .ListColumns(rCell.Column - (.HeaderRowRange.Cells(1).Column) + 1)
'lRow = rCell.Row - .HeaderRowRange.Row
'MsgBox "La valeur cherchée est dans la colonne " & loCol.Name & Chr(10) & "à la ligne " & lRow & "."
MsgBox "Ligne rch 1 = " & myrange1
loCol = .ListColumns("Poste").DataBodyRange.Column
MsgBox loCol
If Cells(myrange1, loCol) = "Montage" Then
MsgBox "good"
Else
MsgBox "pas good"
Do
Set rCell2 = .DataBodyRange.Find(Value, After:=rCell1)
If Not rCell2 Is Nothing Then
myrange2 = rCell2.Row - .HeaderRowRange.Row
MsgBox rCell2.Address
MsgBox "Ligne rch 2 = " & myrange2
MsgBox loCol
MsgBox Cells(myrange2, loCol).Value
If Cells(myrange2, loCol) = "Montage" Then
Test = 1
MsgBox "Test = 1"
Else
Set rCell1 = rCell2
Test = 0
End If
End If
Loop Until Test = 1
End If
MsgBox Cells(myrange2, loCol).Address
Else
MsgBox "La valeur recherchée est inconnue.", vbOKOnly
End If
End With
End Sub
Ca y est j'ai enfin réussi
Par contre maintenant le programme s'arrète sur loCol = .ListColumns("Poste").DataBodyRange.Column
Quand je continue tout fonctionne bien jusqu'au bout et ma recherche multicritère est valide. Par contre pourquoi d'un coup il bug sur le loCol... ?
et si vous utilisez les filtres ???
Sub Heelflip_Filtre()
Dim c As Range
With Range("Tableau_Audits").ListObject 'votre tableau structuré
On Error Resume Next 'désactiver autofilter eventuel
.Parent.AutoFilter.Range.AutoFilter
On Error GoTo 0
.Range.AutoFilter 2, 2024 'filtrer l'année
.Range.AutoFilter 6, "Montage" 'filtrer poste
On Error Resume Next
Set c = .ListColumns("Poste").DataBodyRange.SpecialCells(xlVisible) 'plage avec les cellules de "Poste" visible
On Error GoTo 0
.Range.AutoFilter 'désactiver filtre
If c Is Nothing Then MsgBox "sorry" Else MsgBox c.Address(0, 0)
End With
End Sub
Re,
Alors je n'ai encore jamais utilisé les filtres en VBA, donc j'ai codé avec le peu de savoir que j'ai
Pour l'instant mon code fonctionne donc je diffuse avec la version 1 (Impératif délai), mais je suis ici depuis assez longtemps pour savoir qu'un code n'est jamais terminé, je garde donc le sujet ouvert le temps de tester les filtres et ton code, qui semble quand même bien plus simple que la boucle. Surtout que dans la version 1, je n'ai pas encore pris en compte le fait de pouvoir avoir ces deux critères sur plusieurs lignes, ce qui fatalement arrivera un jour ou l'autre histoire d'embêter le codeur
Merci pour ces propositions, elle permettent d'étoffer chaque jours mes connaissances