XL 2013 [Résolu] Recherche équipement manquant par nom et profils

Angelista

XLDnaute Occasionnel
Bonjour le Forum,

Je fais appel à vous pour le soucis suivant.
Dans le fichier joint, j'ai 3 onglets : Détails, User, Norme

L'onglet norme me donne les équipements nécessaire pour chaque profils
L'onglet User me donne le type de profil par user.
L'onglet Détails me donne quels équipement a déjà le user.

Je souhaiterais qu'une macro me donne dans l'onglet User en colonne C, tous les équipements qu'il manque à chaque personne par rapport à son profil par rapport et à ce qu'il a déjà en sa possession, concaténer dans la cellule, sinon inscrire complet s'il ne manque rien.
A savoir que ce fichier fait 25 000 lignes du user à la base, et que des équipements peuvent être ajoutés.
Merci à vous.

Angel
 

Pièces jointes

  • Test.xlsx
    11.4 KB · Affichages: 30

Robert

XLDnaute Barbatruc
Repose en paix
Bonjour Angelista, bonjour le forum,

En pièce jointe ton fichier modifié avec la macro ci-dessous. Attention ! La macro ne fonctionne correctement que si chaque participant (dans l'onglet Détails) est séparé du suivant par une ligne vierge (voir fichier).

Le code :

VB:
Sub Macro1()
Dim D As Worksheet 'déclare la variable D (Onglet Détails)
Dim U As Worksheet 'déclare la variable U (Onglet User)
Dim N As Worksheet 'déclare la variable N (Onglet Norme)
Dim TV As Variant 'déclare la variable TV (Tableau des Valeurs)
Dim I As Integer 'déclare la variable I (Incrément)
Dim J As Integer 'déclare la variable J (incrément)
Dim R As Range 'déclare la variable R (Recherche)
Dim PL As Range 'déclare la variable PL (PLage)
Dim TL As Variant 'déclare la variable TL (Tableau de la Liste)
Dim CEL As Range 'déclare la variable CEL (CELlule)
Dim L As String 'déclare la variable L (Liste)

Set D = Worksheets("Détails") 'définit l'onglet D
Set U = Worksheets("User") 'définit l'onglet U
Set N = Worksheets("Norme") 'définit l'onglet N
TV = U.Range("A1").CurrentRegion 'définit le tableau des valeurs TV
For I = 2 To UBound(TV, 1) 'boucle 1 : sur toutes les lignes du tableau des valeurs TV (en partant de la seconde)
    Set R = N.Rows(1).Find(TV(I, 2)) 'définit la recherche R (recherche le profil de la boucle dans la première ligne de l'onglet N)
    'si il existe au moins une occurrence trouvée, définit le tableau de la liste TL (= la liste de la norme trouvée)
    If Not R Is Nothing Then TL = Application.Transpose(Range(R.Offset(1, 0), N.Cells(Application.Rows.Count, R.Column).End(xlUp)))
    Set R = Nothing 'vide la variable R
    Set R = D.Columns(1).Find(TV(I, 1)) 'définit la recherche R (recherche le nom de la boucle danws la colonne 1 (=A) de l'onglet D
    If Not R Is Nothing Then Set PL = R.CurrentRegion 'définit la plage PL
    Set PL = PL.Offset(0, 1).Resize(, 1) 'redéfinit la plage PL (uniquement la colonne B)
    For J = 1 To UBound(TL) 'boucle 2 : sur toutes les données du tableau de la liste TL
        For Each CEL In PL 'boucle 3 : sur toutes les cellules CEL de la plage PL
            If TL(J) = CEL.Value Then GoTo suite: 'si la donnée correspond à la valeur de la cellule CEL, va à l'étiquette "suite"
        Next CEL 'procheiane cellule de la boucle 3
        L = IIf(L = "", TL(J), L & ", " & TL(J)) 'définit la liste L
suite: 'étiquette
    Next J 'prochaine donnée de la boucle 2
    U.Cells(I, "C").Value = IIf(L <> "", L, "Complet") 'renvoie la liste L dans la cellule ligne I colonne C
    Set R = Nothing: Erase TL: L = "" 'vide la variable R, efface le tableau TL, vide la liste L
Next I 'prochaijne ligne de la boucle 1
End Sub

Le fichier :
 

Pièces jointes

  • Angelista_v01.xlsm
    19.1 KB · Affichages: 19

Angelista

XLDnaute Occasionnel
Rebonjour,

Fonctionnement super, encore merci à vous 2.

@Robert,
j'ai bien lu macro, je me demande s'il est possible de l'adapter, par exemple rajouter en VBA une ligne vide entre chaque participant au début puis de les supprimer après, est ce que cela fonctionnerai encore.
Merci.

@ +

David
 

Robert

XLDnaute Barbatruc
Repose en paix
Re,

Ce qui me chagrine le plus dans cette histoire c'est de ne pas y avoir pensé avant... Le nouveau code :

VB:
Sub Macro1()
Dim D As Worksheet 'déclare la variable D (Onglet Détails)
Dim U As Worksheet 'déclare la variable U (Onglet User)
Dim N As Worksheet 'déclare la variable N (Onglet Norme)
Dim DL As Integer 'déclare la variable DL (Dernière Ligne)
Dim TV As Variant 'déclare la variable TV (Tableau des Valeurs)
Dim I As Integer 'déclare la variable I (Incrément)
Dim J As Integer 'déclare la variable J (incrément)
Dim R As Range 'déclare la variable R (Recherche)
Dim PL As Range 'déclare la variable PL (PLage)
Dim TL As Variant 'déclare la variable TL (Tableau de la Liste)
Dim CEL As Range 'déclare la variable CEL (CELlule)
Dim L As String 'déclare la variable L (Liste)

Application.ScreenUpdating = False 'masque les rafraîchissements d'écran
Set D = Worksheets("Détails") 'définit l'onglet D
DL = D.Cells(Application.Rows.Count, "A").End(xlUp).Row 'définit la dernière ligne éditée DL de la colonne A de l'onglet D
For I = DL To 2 Step -1 'boucle inversée sur toutes les lignes I de DL à 2
    If D.Cells(I, "A").Value <> "" Then Rows(I).Insert Shift:=xlDown 'si la cellule en colonne A est vide ajoute une ligne au-dessous
Next I 'prochaine ligne de la boucle
Set U = Worksheets("User") 'définit l'onglet U
Set N = Worksheets("Norme") 'définit l'onglet N
TV = U.Range("A1").CurrentRegion 'définit le tableau des valeurs TV
For I = 2 To UBound(TV, 1) 'boucle 1 : sur toutes les lignes du tableau des valeurs TV (en partant de la seconde)
    Set R = N.Rows(1).Find(TV(I, 2)) 'définit la recherche R (recherche le profil de la boucle dans la première ligne de l'onglet N)
    'si il existe au moins une occurrence trouvée, définit le tableau de la liste TL (= la liste de la norme trouvée)
    If Not R Is Nothing Then TL = Application.Transpose(Range(R.Offset(1, 0), N.Cells(Application.Rows.Count, R.Column).End(xlUp)))
    Set R = Nothing 'vide la variable R
    Set R = D.Columns(1).Find(TV(I, 1)) 'définit la recherche R (recherche le nom de la boucle danws la colonne 1 (=A) de l'onglet D
    If Not R Is Nothing Then Set PL = R.CurrentRegion 'définit la plage PL
    Set PL = PL.Offset(0, 1).Resize(, 1) 'redéfinit la plage PL (uniquement la colonne B)
    For J = 1 To UBound(TL) 'boucle 2 : sur toutes les données du tableau de la liste TL
        For Each CEL In PL 'boucle 3 : sur toutes les cellules CEL de la plage PL
            If TL(J) = CEL.Value Then GoTo suite: 'si la donnée correspond à la valeur de la cellule CEL, va à l'étiquette "suite"
        Next CEL 'procheiane cellule de la boucle 3
        L = IIf(L = "", TL(J), L & ", " & TL(J)) 'définit la liste L
suite: 'étiquette
    Next J 'prochaine donnée de la boucle 2
    U.Cells(I, "C").Value = IIf(L <> "", L, "Complet") 'renvoie la liste L dans la cellule ligne I colonne C
    Set R = Nothing: Erase TL: L = "" 'vide la variable R, efface le tableau TL, vide la liste L
Next I 'prochaijne ligne de la boucle 1
DL = D.Cells(Application.Rows.Count, "A").End(xlUp).Row 'définit la dernière ligne éditée DL de la colonne A de l'onglet D
For I = DL To 2 Step -1 'boucle inversée sur toutes les lignes I de DL à 2
    If D.Cells(I, "B").Value = "" Then Rows(I).Delete 'si la cellule en colonne B est vide, supprime la ligne
Next I 'prochaine ligne de la boucle
Application.ScreenUpdating = True 'affiche les rafraîchissements d'écran
End Sub
 

Discussions similaires

Membres actuellement en ligne

Statistiques des forums

Discussions
312 084
Messages
2 085 194
Membres
102 811
dernier inscrit
caroline29260