Doublons ect
Hola !
Je viens vers vous pour une nouvelle demande, je bloque complètement sur access pour editer une feuille excel, donc je commence par chercher sur excel directement une astuce pour ensuite l'adapter sur access.
Donc le délire, j'aimerais en vba dans une feuille chercher les doublons sur une colonne et s'il y en a 2 par exemple, les rassembler sur une seules ligne si possible par rapport au autres données qu'il y'a sur ces lignes donc s'il y a de la place disponible sur une des ses lignes.
Alors ca doit pas être très très clair,j'ai du mal a expliquer avec des mots le truc.
Je met donc un petit tableau exemple le tableau numéro 1 c'est les données "brutes" et le tableau deux c'est le rendu que le vba devrait faire.
Merci a ceux qui se pencheront sur mon problèmes ou me donneront des pistes pour avancer.
PS: je pense qu'il faut jouer peut etre avec le nombre de doublons si pair ou impair !!
Non j'aimerais que ce soit fait par code vba, et non pas avec cette présentation, le tableau deux c'est juste ce que doit devenir le tableau un, en fait c'est juste regrouper les doublons sur la même ligne si la colonne B ou C le permet.
Dans le tableau par exemple pour titi (il y en a trois en tout mais deux peuvent "s'assembler" celui qui a un 1 et celui qui a un 2", le troisième vu qu'il n'y a pas d'autre titi il reste tout seul... après il pourrait y avoir d'autre titi dans le tableau qui serai à même d'être assemblé ou pas aussi.
Bonsoir,
En fait il ne s'agit pas de doublons, mais de fusionner les éléments compatibles.
Sub Fusionner()
Dim Tbl(), i%, j%, k%, n%, m%, lib$
Application.ScreenUpdating = False
With Worksheets("Feuil1")
n = .Cells(.Rows.Count, 1).End(xlUp).Row
For i = 2 To n
If .Cells(i, 1) <> "" Then
ReDim Preserve Tbl(2, m)
Tbl(0, m) = .Cells(i, 1)
If .Cells(i, 2) <> "" Then Tbl(1, m) = .Cells(i, 2) Else k = 2
If .Cells(i, 3) <> "" Then Tbl(2, m) = .Cells(i, 3) Else k = 3
If k > 0 Then
lib = .Cells(i, 1)
For j = i + 1 To n
If .Cells(j, 1) = lib Then
If .Cells(j, k) <> "" Then
If .Cells(j, k + (k > 2) - (k < 3)) = "" Then
Tbl(k - 1, m) = .Cells(j, k)
.Cells(j, 1).ClearContents
Exit For
End If
End If
End If
Next j
End If
m = m + 1: k = 0
End If
Next i
.Range("A2").Resize(n - 1, 3).Clear
With .Range("A2").Resize(m, 3)
.Value = WorksheetFunction.Transpose(Tbl)
.Borders.Weight = xlThin
.Borders(xlEdgeTop).Weight = xlMedium
End With
End With
End SubOn suppose que tous les éléments du tableau ont toujours au moins l'une ou l'autre des colonnes B ou C servie, qu'il n'y a donc jamais d'élément avec les colonnes B et C vides.
Cordialement.
C'est parfait, juste une dernière chose sans vouloir abuser de tes talents
Si par exemple il y a une dernière colonne avec un chiffre qui sera toujours le même affecté à tous les TOTO ou un pour tous les TITI et que je veux le conserver, et si au lieu que la première entrée du tableau se trouve en A2 s'il est en B6?
Je remet le tableau que tu m'as fait avec les modifs sur la feuille excel pour l'exemple.
Encore merci de ton aide.
Bonjour,
La méthode repose sur la construction d'un tableau VBA résultat dans lequel on insère chaque ligne : si une ligne est incomplète, on cherche dans la suite du tableau si on peut la compléter en fusionnant une autre ligne (on efface la première cellule de cette ligne fusionnée pour éviter de la reprendre ensuite). Une fois le tableau résultat fini, on détruit le tableau initial et on affecte le nouveau tableau sur l'emplacement (et on reconstruit les bordure.
Si tu tiens à pouvoir placer ton tableau initial un peu n'importe où sur la feuille, je conseille de le nommer de façon dynamique :
=DECALER(Feuil1!$B$6;;;NBVAL(Feuil1!$B$6:$B$5000);4)Ainsi le nom s'adaptera à la longueur du tableau.
[NB- Si tu prévois d'aller au-delà de la ligne 5000, tu augmentes ce nombre, si tu envisages de dépasser 30000 tu bascules les variables Integer (sauf k) en Long (en remplaçant % par & dans les déclarations).]
La procédure s'appuiera sur le nom et peut rester la même où que tu places ton tableau.
Fichier ci-joint avec proc. modifiée et tableau à 4 colonnes (si le nb de colonnes varie il faudra modifier la proc pour intégrer les nouvelles colonnes...)
Cordialement.
Petites questions:
A quoi correspond "With [Tablo]" ?
Et donc si je veux rajouter une colonne à quel endroit dois je modifier la procédure?
Sur ces lignes la??:
ReDim Preserve Tbl(3, m)
Tbl(0, m) = .Cells(i, 1): Tbl(3, m) = .Cells(i, 5)
MErci de ton aide
Tablo est le nom que j'ai donné à ton tableau, ce nom réfère à la formule que j'ai citée, qui le rend dynamique en ce qui concerne l'extension en lignes. (voir dans Gestionnaire de noms)
La procédure utilise ce nom au lieu de références à une plage dans une feuille, et demeure valide quelles que soient les extensions du tableau en hauteur.
Ce n'est pas la même chose si tu fais varier les colonnes.
Tbl(3, m) définit un tableau (transposé) de 4 colonnes (0 à 3) [m, égal à 0 au départ, incrémente le nombre de lignes au fur et à mesure). Le tableau ne peut avoir moins de 3 colonnes, la fusion s'opérant à partir des 2e et 3e. S'il y en a plus il faut intégrer l'insertion dans Tbl des données des colonnes en sus de ces 3 initiales (la procédure intègre actuellement une 4e colonne, si d'autres sont ajoutées, il faut ajouter le code d'insertion de leurs données). Et lors de l'affectation il faut également ajuster le redimensionnement sur le nombre de colonnes (4 actuellement).
Cordialement.
Et la même chose est faisable en utilisant le premier code car comme j'ai dis je vais d'abord utiliser access en fait et je ne sais pas comment rajouter un nom avec une formule en passant par excel le premier code était plus facile a mettre en place, quel changement sur le premier code je devrais mettre en place pour avoir le résultat avec 4 ou 5 colonnes (voir plus) et en commencant le tableau la première entrée en B6?
Merci mais il faut que ce soit par vba car la feuille excel sera générée automatiquement par access en fait, donc la première solution de MFerrand est pas mal, reste a réussir a l'adapter sur B6 et avec 5 colonnes.
Adapter le 1er code ? C'est le 2e, qui est justement l'adaptation du 1er !
Il adapte sur 2 points :
-En utilisant un nom dynamique pour la plage-tableau, ce qui affranchit des adaptations dues au positionnement du tableau. On ajuste la formule de définition du nom si on le déplace mais cela permet de ne pas avoir à toucher au code. Il suffit de savoir insérer un nom dynamique...
-Il traitait une 4e colonne, le 1er n'en traitant que 3.
Pour ce qui est de la fusion, le code n'opère que sur 3 col. : la 1re pour identification, les 2e et 3e pour les possibilités de fusion, et fusionner quand c'est possible. Aucune différence entre les deux codes sur ce points.
Les colonnes supplémentaires ne font que suivre, on récupère leur valeur pour les reporter (valeur commune pour un même identifiant). Pour 4, c'est le 2e code. Pour 5 ou plus, il faut donc repérer les éléments du code représentant des index de colonnes pour les modifier : pour le tableau VBA de résultats, c'est le premier indice qui représente les colonnes (2 pour 3, 3 pour 4, 4 pour 5, etc. car on part d'un indice 0 pour la 1re colonne), pour les redimensionnements de plages c'est le 2e index de la méthode Resize qui correspond au nombre de colonnes. Tout cela reste facile à rectifier, il faut juste lire attentivement et ne pas en louper.
Le 2e code ajoute au 1er la récupération de valeur de la 4e colonne :
Tbl(3, m) = .Cells(i, 4)Pour une 5e col. il faudra ajouter la même commande avec un indice 4 pour le tableau et un index 5 pour la cellule. Pour chaque colonne supplémentaire tu auras une ligne de code en plus... (NB : le signe ":" qui sépare des commandes sur un même ligne est un séparateur de lignes de code (pour éviter d'allonger considérablement lorsque des commandes courtes et semblables se succèdent...)
Tbl(0, m) = .Cells(i, 1):Tbl(3, m) = .Cells(i, 4)Cette ligne contient 2 lignes de code, séparées par le ":" surligné.
Cordialement.
