Vérifier si condition ok
Bonjour,
j'ai un classeur dans lequel, j'ai une feuille critère,une feuille sportif et une feuille résultat.
Dans la feuille critère j'ai des listes de valeurs par conditions (condition 1, condition 2...).
Dans la feuille sportif, j'ai des listes de valeur par nom.
j'aimerai si possible, vérifier pour chaque nom si ils remplissent une ou plusieurs conditions (exemple est ce que toutes les valeurs de la condition 1 sont présentes dans les valeurs de jean, de même pour la condition 2 ...)
si une ou plusieurs conditions sont remplis alors reporter le nom dans la feuille résultat (un nom par colonne) et lister pour chaque nom le ou les noms des conditions remplis (exemple: jean en A1, condition 1 en A2, condition 3 en A3...)
Un grand merci d'avance car j'ai testé plusieurs chose sans succès.
Bonjour JEAN123,
Voyez dans le fichier joint si la solution proposée peut vous aider
Super, mais idéalement une macro aurai été top
j'aurais par la suite plus de colonne pour les deux feuilles (nombre indéterminé ) du coup un truc qui boucle serais parfait.
Super, mais idéalement une macro aurai été top
j'aurais su, je n'y aurais pas touché, désolé
merci quand même désolé pour le temps que tu y a consacré
j'ai trouvé ça, mais je ne suis vraiment pas sûr du truc un p'tit coup de pouce
Sub maindd()
Dim strngToMatch As String
Dim cell As Range
With Worksheets("Feuil1")
strngToMatch = Join(Application.Transpose(.Range("A3", .Cells(.Rows.Count, 1).End(xlUp)).Value), "")
End With
With Worksheets("Feuil2")
For Each cell In .Range("A1", .Cells(1, .Columns.Count).End(xlToLeft)).SpecialCells(xlCellTypeConstants)
If strngToMatch = Join(Application.Transpose(.Range(cell.Offset(1), .Cells(.Rows.Count, cell.Column).End(xlUp)).Value), "") Then
Worksheets("Feuil3").Range("A2").Value = cell.Value
Exit For
End If
Next cell
End With
End Sub
voici le lien de la page source
ah je crois que c'est pas tout à fait ça.
je perd tout espoir
Salut le fil
Un début de solution il faudrait peut être enlever les doublons...
Dans ta feuille "résultat" tu colles un bouton et tu lui affectes ce code.
Bon courage...
Sub Bouton1_Cliquer()
'On dimmensionne nos objets
Dim e As Range, i As Integer, c As Range, d As String, depart As String
With Range("Critère") 'Correspond la plage Critére![A1,L24]
For Each e In Range("Sportifs") 'Correspond à la plage sportif![A1,D41]
' on fait une recherche
Set c = .Find(e, LookIn:=xlValues, SearchOrder:=xlByColumns)
If Not c Is Nothing Then
'Si trouvé on récupère l'adresse de départ
depart = c.Address
Do
' On récupère le nom du sportif 1ère ligne de la colonne
d = Range("Sportifs").Cells(, e.Column).Value
'J'ai fait une plage nommée pour chaque sportif mais il y a d'autres solutions
'On rajoute une ligne à la plage nommée
allongerange d
'On écrit le résultat
Range(d).Rows(Range(d).Rows.Count).Value = Range("Critère").Cells(1, c.Column)
'On recherche le suivant
Set c = .FindNext(c)
Loop While Not c Is Nothing And c.Address <> depart
End If
Next
End With
End Sub
Sub allongerange(NomRange As String)
Dim Tableau() As String
With ThisWorkbook.Names(NomRange)
Tableau = Split(.RefersTo, "!")
ThisWorkbook.Names.Add _
Name:=.Name, _
RefersTo:=Tableau(0) & "!" & _
Range(Tableau(1)).Resize(Range(Tableau(1)).Rows.Count + 1).Address
End With
End Sub
j'ai un message d'erreur "la méthode range de l'objet _global a échoué"
sur :
With Range("Critère") 'Correspond la plage Critére![A1,L24]
autant pour moi c'étais une faute sur le nom de ma feuille.
c'est presque ça, en fait il faudrait : si toutes les valeurs d'une condition sont présente exemple pour la condition 1:
"A001 A002 A003 A014 A016 A023 A025 A026 A027 A029 A030 A031 A032 A033 A034 A036 A038 A039 A040 A042"
si il en manque une la condition n'est pas rempli
et si possible ramener les nom de sportif a la feuille résultat (je vais surement avoir beaucoup de nom par la suite)
j'ai un message d'erreur "la méthode range de l'objet _global a échoué"
sur :
With Range("Critère") 'Correspond la plage Critére![A1,L24]
Bien sur que tu as un message d'erreur ... as tu nommé tes champs "Critère" "Sportif" etc..... tu as en remarque à quoi correspond chaque champ nommé.
La première chose à faire quand on reçois un code c'est d'en comprendre le fonctionnement avant de faire du copier coller.
Concernant ta demande tu dois traiter par personne et non par champ complet des sportifs. Tu peux vérifier chaque valeur du champ si Ok tu met un Flag à True , et à la fin tu vérifie ton Flag si = True tu écris la valeur si False tu ne fait rien.
oui j'ai bien vu ça c’était juste une faute d’accent pas plus pas moins
n’étant pas un expert je n'ai pas bien compris les "flag" et comment ramener le nom du sportif ? est ce que c'est là:
Range(Tableau(1)).Resize(Range(Tableau(1)).Rows.Count + 1).Address
j'ai essayé de comprendre comment cela fonctionne mais vu mon niveau je suis vraiment pas sûr, j'ai mis des commentaires dans le code. après plusieurs essais à chaque fois j'ai une erreur.
Option Explicit
Sub Bouton1_Cliquer()
'On dimmensionne nos objets
Dim e As Range, i As Integer, c As Range, d As String, depart As String
With Range("Critère") 'Correspond la plage Critére![A1,L24]
For Each e In Range("Sportifs") 'Correspond à la plage sportif![A1,D41]
' on fait une recherche, là j'ai pas compris (tu recherche le nom du sportif?)
Set c = .Find(e, LookIn:=xlValues, SearchOrder:=xlByColumns)
If Not c Is Nothing Then
'Si trouvé on récupère l'adresse de départ
depart = c.Address
Do
' On récupère le nom du sportif 1ère ligne de la colonne
'(est-ce que c'est ici qu'ont peut recupéré le nom du sportif pour le ramener automatiquement dans la feuille résultat ?)
d = Range("Sportifs").Cells(, e.Column).Value
'J'ai fait une plage nommée pour chaque sportif mais il y a d'autres solutions
'On rajoute une ligne à la plage nommée
allongerange d
'On écrit le résultat
'ici flag = true ?
Range(d).Rows(Range(d).Rows.Count).Value = Range("Critère").Cells(1, c.Column)
'On recherche le suivant
Set c = .FindNext(c)
Loop While Not c Is Nothing And c.Address <> depart
End If
Next
End With
End Sub
Sub allongerange(NomRange As String)
Dim Tableau() As String
With ThisWorkbook.Names(NomRange)
Tableau = Split(.RefersTo, "!")
ThisWorkbook.Names.Add _
Name:=.Name, _
RefersTo:=Tableau(0) & "!" & _
Range(Tableau(1)).Resize(Range(Tableau(1)).Rows.Count + 1).Address
End With
End Sub
Salut le fil
Bon on revois tout...
Encore une fois . la sortie du confinement ne me réussi pas
donc si j'ai bien compris:
je supprime les noms dans la feuille résultat,
je dois faire une autre boucle dans la boucle (je ne sais pas faire ça)
j'ai fait un test mais sans résultat
Salut le fil,
Bon on reprends tout si j'ai bien compris ce que tu veux tu dois faire des boucles imbriquées.
J'ai mis des explications dans le code, ce ne doit pas être la méthode la plus rapide, en passant par des tableaux à plusieurs dimensions cela devrait être mieux. Regardes la fenêtre d'exécution pour voir le cheminement.
Donc on colles tout ce petit monde dans un module et on affecte la sub Bouton1_Cliquer à un bouton sur la feuille résultat.
Sub Bouton1_Cliquer()
Dim sportifCurrentRegion As Range 'Cela correspond à toutes les cellules de la feuille Sportif
Dim colSportif As Range 'colonne dans l'objet sportifCurrentRegion
Dim d As String 'd va contenir le nom du sportif
Dim CritèreCurrentRegion As Range 'Cela correspond à toutes les cellules de la feuille critére
Dim colCritère As Range 'colonne dans l'objet CritèreCurrentRegion
Dim c As Range 'Chaque cellule de la colonne colCritère de l'objet CritèreCurrentRegion
Dim s As Range 'Plage de cellules ou l'on va rechercher
Dim flag As Boolean 'Passe à False si le critère n'est pas trouvé
Dim valCritère As Range
'On nettoie la feuille de résultat
CleanNames
'Pour être générique on va rechercher le nombre de colonne dans la feuille sportif
Set sportifCurrentRegion = Sheets("sportif").Range("A1").CurrentRegion
'On définie la plage de recherche
Set CritèreCurrentRegion = Sheets("critére").Range("A1").CurrentRegion
flag = True
For Each colSportif In sportifCurrentRegion.Columns
Debug.Print vbNewLine & "-------------------------------------------------------------------"
Debug.Print "Nom de la colonne : " & colSportif.Range("A1")
Set s = colSportif.Range("A2:A" & colSportif.Cells.Find("*", , , , xlByColumns, xlPrevious).Row)
For Each colCritère In CritèreCurrentRegion.Columns
Debug.Print " - Recherche du critère : " & colCritère.Range("A1")
For Each c In colCritère.Range("A2:A" & colCritère.Cells.Find("*", , , , xlByColumns, xlPrevious).Row)
Set valCritère = s.Find(c)
If valCritère Is Nothing Then
Debug.Print " - Recherche de: " & c & " : False"
flag = False
Exit For
Else
Debug.Print " - Recherche de: " & c & " : True"
flag = True
End If
Next
If flag Then
Debug.Print " - " & colCritère.Range("A1") & " trouvée pour le joueur : " & colSportif.Range("A1") & vbNewLine
d = colSportif.Range("A1")
AllongeRange d
'On écrit le résultat
Range(d).Rows(Range(d).Rows.Count).Value = colCritère.Range("A1")
End If
Next
Set s = Nothing
Next
End Sub
Sub AllongeRange(NomRange As String)
Dim Tableau() As String
With ThisWorkbook.Names(NomRange)
Tableau = Split(.RefersTo, "!")
ThisWorkbook.Names.Add _
Name:=.Name, _
RefersTo:=Tableau(0) & "!" & _
Range(Tableau(1)).Resize(Range(Tableau(1)).Rows.Count + 1).Address
End With
End Sub
Sub CleanNames()
'On efface la feuille résultat
Sheets("Résultat").Cells.Clear
'On remplie les entêtes
With Range("A1:F1")
.Value = Array("Jean", "Paul", "Robert", "Fred", "Max", "Jules")
.Interior.Color = vbYellow
End With
'On définie les noms
With ActiveWorkbook
.Names("Jean").RefersToR1C1 = "=résultat!R1C1"
.Names("Paul").RefersToR1C1 = "=résultat!R1C2"
.Names("Robert").RefersToR1C1 = "=résultat!R1C3"
.Names("Fred").RefersToR1C1 = "=résultat!R1C4"
.Names("Max").RefersToR1C1 = "=résultat!R1C5"
.Names("Jules").RefersToR1C1 = "=résultat!R1C6"
End With
'on efface la fenêtre d'éxécution
SendKeys "^g ^a {DEL}"
End Sub
en l'état sur le classeur exemple ça marche du toner !! un grand merci à toi
par contre si j'ajoute des noms en modifiant la range
Sub CleanNames()
Sheets("Résultat").Cells.Clear
With Range("A1:G1")
et en ajoutant
.Names("Jack").RefersToR1C1 = "=résultat!R1C7"
j'ai une "erreur d'éxecution 1004 erreur définie par l'application ou par l'objet"
j'aurai par la suite un centaine de noms dans mon fichier, je devrais tous les lister dans le code?
est-ce que les plages du gestionnaire de noms ont une importance ? A caque fois il faut attribuer une plage ? il n'y a pas possibilité de ramener les noms autrement
a terme je vais avoir beaucoup de noms