XL 2016 Concaténer une plage variable suivant un critère

piga25

XLDnaute Barbatruc
Bonjour,
Comment faire pour concaténer une plage variable suivant un critère qui peut être situer sur une ou deux colonnes.
Le fichier exemple sera beaucoup plus parlant.
Je ne sais pas s'il faut procéder avec des formules matricielles ou par un code VBA
Cordialement
Edit: Peut être également avec des requêtes!!!
 

Pièces jointes

  • Concatener plage variable suivant critere.xlsx
    13.6 KB · Affichages: 13
Dernière édition:

Robert

XLDnaute Barbatruc
Repose en paix
Bonsoir Le fil bonsoir le forum,

LE code ci-dessous ne me donne pas le même résultat que toi mais, après vérification, il semble que tu te sois planté dans les résultats proposés...

VB:
Sub Macro1()
Dim O As Worksheet 'déclare la variable O (Onglet)
Dim TS As ListObject 'déclare la variable TS (Tableau Structuré)
Dim TV As Variant 'déclare la variable TV (Tableau des Valeurs)
Dim D As Object 'déclare la variable D (Dictionnaire)
Dim TMP As Variant 'déclare la variable TMP (tableau TeMPoraire)
Dim I As Integer 'déclare la variable I (Incrément)
Dim J As Integer 'déclare la variable J (incrément)
Dim K As Integer 'déclare la variable K (incrément)
Dim L As Integer 'déclare la variable L (incrément)
Dim TC() As Variant 'déclare la variable TC (Tableau des Critères)
Dim TL() As Variant 'déclare la variable TL (Tableau des Lignes)
Dim T As String 'déclare la variable T (Texte)

Set O = Worksheets("Données") 'définit l'onglet O
Set TS = O.ListObjects("Tableau1") 'définit le tableau structuré TS
TV = TS.DataBodyRange 'définit le tableau des valeurs TV
Set D = CreateObject("Scripting.Dictionary") 'définit le dictionnaire D
For I = 1 To UBound(TV, 1) 'boucle sur toutes les lignes I du tableau des valeurs TV
    D(TV(I, 3)) = "" 'alimente le dictionnaire Davec les données en colonne 3 (DPD Principal)
Next I 'prochaine ligne de la boucle
TMP = D.keys 'récupère dans le tableau temporaire TMP la liste des éléments du dictionnaire D sans doublons (les clé)
'on a récupérés les "DPD Pricipal" sans doublon

ReDim Preserve TC(0 To UBound(TMP)) 'redimensionne le tableau des critères CT (autant de lignes que TMP)
For J = 0 To UBound(TMP) 'boucle 1 : sur tous les éléments du tableau temporaire TMP
    Set D = Nothing 'vide le dictionnaire D
    Set D = CreateObject("Scripting.Dictionary") 'définit le dictionnaire D
    For I = 1 To UBound(TV, 1) 'boucle 2 : sur toutes les lignes I du tableau des valeurs TV
        If TV(I, 3) = TMP(J) Then 'condition : si la donnée ligne I colonne 3 de TV est égale à TMP(J)
            D(TV(I, 1)) = "" 'alimente le dictionnaire D avec les données en colonne 1 de TV (CODEUT)
        End If 'fin de la condition
    Next I 'prochaine ligne de la boucle
    TC(J) = D.keys 'recupère dans le tableau TC(J), la listes des élément du dictionnaire D sans doublons (les clé)
Next J 'prochain élément du tableau temporaire TMP
'on a pour chaque 'DPD Principal" un tableau des critères avec leurs CODEUT sans doublon

For J = 0 To UBound(TMP)  'boucle 1 : sur tous les éléments J du tableau temporaire TMP (les "DPD Principal")
    K = K + 1 'incrémente K
    ReDim Preserve TL(1 To K) 'redimentionne le tableau des Lignes TL (K lignes)
    TL(K) = TMP(J) 'récupère dans la ligne K de TL le DPD Principal TMP(J)
    For L = 0 To UBound(TC(J)) 'boucle 2 : sur tous les citères L du tableau des critères TC
        For I = 1 To UBound(TV, 1) 'boucle 3 sur toutes les lignes I du tableau des valeurs TV
            If TV(I, 3) = TMP(J) Then 'condition : si la donnée ligne I colonne 3 de TV est égale à l'élément j de TMP
                'si la donnée ligne I colonne 1 de TV est égale au critère L du tableau des critères TC(J)
                'le texte T est égal à T suivie de la donnée ligne I colonne 2 de TV
                If TV(I, 1) = TC(J)(L) Then T = T & TV(I, 2)
            End If 'fin de la condition
        Next I 'prochaine ligne de la boucle 3
        K = K + 1 'incrémente K
        ReDim Preserve TL(1 To K) 'redimensionne le tableau des lignes TL (K lignes)
        'récupère dans la ligne K de TL, le critères L tu tableau des critères TC(J), suivi du texte T, suivi de la date principale, suivi de DPD principal
        TL(K) = TC(J)(L) & T & "_" & TV(1, 5) & "_" & TMP(J)
        T = "" 'vide le texte T
    Next L 'prochain critère de la boucle 2
Next J 'prochaine élément du tableau temporaire TMP
'si K est supérieure à zéro, renvoie le tableau trsposé Tl dans la cellule H34 redimensionnée (tu adapteras l'adresse de la cellule)
If K > 0 Then Range("H34").Resize(K).Value = Application.Transpose(TL)
End Sub
 

piga25

XLDnaute Barbatruc
Bonjour le fil, le forum,
Un grand merci pour ce code si bien commenté.
En effet ton code met bien toutes les possibilités.
J'ai remarqué qu'il effectuait ses recherches que sur les PDP principaux (colonne C) sans prendre en compte les secondaires (colonne D). J'ai juste modifié le tableau pour tout regrouper en colonne C (Principaux et secondaire). Puis j'ai rectifié ma colonne date pour qu'elle soit au bon endroit.
Résultat tout fonctionne et avec une réponse instantanée. Ne reste plus qu'a tester sur le bon fichier.

Pour ce problème, j'avais envisagé trois solutions:
- Par code VBA (ce que tu as fait, merci)
- Par formule (je sais qu'il existe depuis 2016, la fonction CONCAT) si version avant il y a la même en fonction personnalisée. J'aimerai bien finaliser ça, rien que pour une démarche intellectuelle.
- Par requête, mais là je suis très novice.

Merci Robert pour ce code.
Cordialement
 

Robert

XLDnaute Barbatruc
Repose en paix
Re,

C'est en allant me coucher (fort tard) que j'ai cogité et je me suis dit : il avait parlé d'un critère pouvant se situer sur une ou deux colonnes. La nuit fut longue P... de B... de M... (Purée de Bananes Mexicaine évidemment)...
Merci pour ton retour. J'aimerais bien ton code modifié.
 

piga25

XLDnaute Barbatruc
Re,

N'étant pas un expert en VBA, j'ai néanmoins réussi à automatiser la procédure.
1- A l'aide de formules, j'intègre dans un tableau consolidation les données des pdp secondaires à la suite des principaux.
2- Je copie uniquement les valeurs de ce tableau sur une autre feuille dans un tableau nommé : Tpdp
3- dans ce tableau Tpdp, je supprime les lignes vide de la colonne A
4- J'exécute ton code

Il y a peut être une simplification à faire!

Je n'ai pas trouvé comment modifier ton code pour mettre les pdp secondaires à la suite des pdp principaux.
C'est pour cette raison que j'ai trouvé plus simple de créer le tableau déjà fait avant de concaténer.
Merci pour l'intérêt que tu m'apportes
 

Pièces jointes

  • Concatener plage variable suivant critere V2.xlsm
    57.3 KB · Affichages: 4

piga25

XLDnaute Barbatruc
Re,
Je viens de remarquer deux choses dans le code:
1- La date est toujours la même, C'est toujours la première date qui est prise en compte alors que cette dernière change en fonction des pdp (Plan De Prévention).
2- Sur le bon fichier, 675 lignes de données, j'ai une erreur sur la ligne située juste au dessus de End Sub.
Au maximum prévoir 1000 lignes de données. (Pour info k=313)

'récupère dans la ligne K de TL, le critères L tu tableau des critères TC(J), suivi du texte T, suivi de la date principale, suivi de DPD principal
TL(K) = TC(J)(L) & T & "_" & TV(1, 4) & "_" & TMP(J) '****** TV(1, 5) 5 est le n° de colonne pour la date
T = "" 'vide le texte T
Next L 'prochain critère de la boucle 2
Next J 'prochaine élément du tableau temporaire TMP
'si K est supérieure à zéro, renvoie le tableau trsposé Tl dans la cellule H34 redimensionnée (tu adapteras l'adresse de la cellule)
If K > 0 Then Range("H2").Resize(K).Value = Application.Transpose(TL)
End Sub

Si j'ai bien saisie le code, le tableau date c'est " TV(1,4) " - ne devrait on pas avoir une variable à la place du 1 (ligne) pour choisir la bonne date correspondant au pdp.
 

Robert

XLDnaute Barbatruc
Repose en paix
Bonjour Piga,

Pour le premier problème je te propose de corriger le code comme ça :

VB:
Sub Macro1()
Dim O As Worksheet 'déclare la variable O (Onglet)
Dim TS As ListObject 'déclare la variable TS (Tableau Structuré)
Dim TV As Variant 'déclare la variable TV (Tableau des Valeurs)
Dim D As Object 'déclare la variable D (Dictionnaire)
Dim TMP As Variant 'déclare la variable TMP (tableau TeMPoraire)
Dim I As Integer 'déclare la variable I (Incrément)
Dim j As Integer 'déclare la variable J (incrément)
Dim K As Integer 'déclare la variable K (incrément)
Dim L As Integer 'déclare la variable L (incrément)
Dim TC() As Variant 'déclare la variable TC (Tableau des Critères)
Dim TL() As Variant 'déclare la variable TL (Tableau des Lignes)
Dim T As String 'déclare la variable T (Texte)
Dim DAT As String 'déclare la variable DAT (DATe)<------------------ ICI
Copy
macro2

Set O = Worksheets("Données") 'définit l'onglet O
Set TS = O.ListObjects("Tpdp") 'définit le tableau structuré TS -----("Tpdp")est le nom du tableau ou s'effectue les recherches de données
TV = TS.DataBodyRange 'définit le tableau des valeurs TV
Set D = CreateObject("Scripting.Dictionary") 'définit le dictionnaire D
For I = 1 To UBound(TV, 1) 'boucle sur toutes les lignes I du tableau des valeurs TV
    D(TV(I, 3)) = "" 'alimente le dictionnaire Davec les données en colonne 3 (DPD Principal)
Next I 'prochaine ligne de la boucle
TMP = D.keys 'récupère dans le tableau temporaire TMP la liste des éléments du dictionnaire D sans doublons (les clé)
'on a récupérés les "DPD Pricipal" sans doublon

ReDim Preserve TC(0 To UBound(TMP)) 'redimensionne le tableau des critères CT (autant de lignes que TMP)
For j = 0 To UBound(TMP) 'boucle 1 : sur tous les éléments du tableau temporaire TMP
    Set D = Nothing 'vide le dictionnaire D
    Set D = CreateObject("Scripting.Dictionary") 'définit le dictionnaire D
    For I = 1 To UBound(TV, 1) 'boucle 2 : sur toutes les lignes I du tableau des valeurs TV
        If TV(I, 3) = TMP(j) Then 'condition : si la donnée ligne I colonne 3 de TV est égale à TMP(J)
            D(TV(I, 1)) = "" 'alimente le dictionnaire D avec les données en colonne 1 de TV (CODEUT)
        End If 'fin de la condition
    Next I 'prochaine ligne de la boucle
    TC(j) = D.keys 'recupère dans le tableau TC(J), la listes des élément du dictionnaire D sans doublons (les clé)
Next j 'prochain élément du tableau temporaire TMP
'on a pour chaque 'DPD Principal" un tableau des critères avec leurs CODEUT sans doublon

For j = 0 To UBound(TMP)  'boucle 1 : sur tous les éléments J du tableau temporaire TMP (les "DPD Principal")
    K = K + 1 'incrémente K
    ReDim Preserve TL(1 To K) 'redimentionne le tableau des Lignes TL (K lignes)
    TL(K) = TMP(j) 'récupère dans la ligne K de TL le DPD Principal TMP(J)
    For L = 0 To UBound(TC(j)) 'boucle 2 : sur tous les citères L du tableau des critères TC
        For I = 1 To UBound(TV, 1) 'boucle 3 sur toutes les lignes I du tableau des valeurs TV
            If TV(I, 3) = TMP(j) Then 'condition : si la donnée ligne I colonne 3 de TV est égale à l'élément j de TMP
                'condition : si la donnée ligne I colonne 1 de TV est égale au critère L du tableau des critères TC(J)
                If TV(I, 1) = TC(j)(L) Then
                    T = T & TV(I, 2) 'le texte T est égal à T suivie de la donnée ligne I colonne 2 de TV
                    DAT = TV(I, 4) 'définit la date DAT <------------------ ICI
                End If
            End If 'fin de la condition
        Next I 'prochaine ligne de la boucle 3
        K = K + 1 'incrémente K
        ReDim Preserve TL(1 To K) 'redimensionne le tableau des lignes TL (K lignes)
        'récupère dans la ligne K de TL, le critères L tu tableau des critères TC(J), suivi du texte T, suivi de la date principale, suivi de DPD principal
        TL(K) = TC(j)(L) & T & "_" & DAT & "_" & TMP(j) '<------------------ ICI
        T = "" 'vide le texte T
    Next L 'prochain critère de la boucle 2
Next j 'prochaine élément du tableau temporaire TMP
'si K est supérieure à zéro, renvoie le tableau trsposé Tl dans la cellule H34 redimensionnée (tu adapteras l'adresse de la cellule)
If K > 0 Then Range("H2").Resize(K).Value = Application.Transpose(TL)
End Sub

Pour le second je t'avoue que je ne connais pas les limites des tableaux de type Variant. En tout cas ce n'est un problème de K puisqu'elle est déclarée de type Integer. Désolé je n'ai pas de solution pour cela. Si tu veux, envoie ton vrai fichier par mail perso afin que je puisse constater et peut-être, améliorer...
 

Discussions similaires

Statistiques des forums

Discussions
312 176
Messages
2 085 959
Membres
103 065
dernier inscrit
HB ARPF 95