Copier contenu plrs cellules et les coller dans une cellule avec clipboard
Bonjour à tous,
Je suis confronté à un problème qui...m'enquiquine terrible.
Dans une feuille d'un classeur A, j'ai une colonne "Références de produit" listant... toutes mes références de produit et une colonne D "N° de commande" listant tous les n° de commande relatifs aux références de produit:
En face de chaque référence de produit, j'ai un ou plusieurs n° de commande:
| Références de produit | N° de commande |
| Banane001 | CDE2306-032 CDE2306-855 CDE2306-917 |
| Poire001 | CDE2305-024 |
| Pomme001 |
Je mets à jour ma colonne "N° de commande" en cherchant cette référence dans la feuille d'un autre classeur pour récupérer ces n° de commande.
Pour me faciliter la vie, j'ai fait une macro:
- J'applique un filtre sur la colonne "N° de commande" (cellule vide).
- Je peux donc boucler sur toutes les références de produits pour lesquelles il n'y a pas de n° de commande.
- Je fais un petit "countif" dans la feuille du classeur B pour m'assurer que ma référence de produit existe bien (sinon, pas la peine d'aller plus loin: il n'y aura forcément pas de n° de commande)
- S'il au moins une occurrence est trouvée, je filtre sur la colonne "N° de commande " de la feuille B.
- Je copie le ou tous les n° de commande.
- Et c'est là qu'est l'os.. Je veux coller tous ces n° de commande dans une seule cellule (de la feuille A) alors que j'ai copié plusieurs cellules.
On a "tous" fait la manip de copier le contenu de plusieurs cellules et de les coller dans un éditeur de texte (notepad ou notepad++) et on se retrouve avec une liste de valeurs "texte" séparées par un retour chariot.
Et c'est ça que j'aimerais exploiter car je trouve que c'est hyper simple plutôt que de devoir coller les cellules dans une feuille "tampon" ou adajacentes les transposer et les concaténer en ajoutant un retour chariot.
Ce que je cherche donc c'est à transformer du contenu de plusieurs cellules en "un seul contenu" au format texte et le récupérer: ni plus ni moins.
Je me suis renseigné et j'ai utilisé le code suivant:
Dim varCLIPBOARD As Variant 'ou string ?
Dim DataObject As MsForms.DataObject
sheetB.Range(Cells(Ligne_First_Hit, CdeA_Col), Cells(DerniereLigne_First_Hit, CdeA_Col+ 1)).Copy
'Col+ 1 pour prendre en compte le statut de la Cde A ou E (Acquittée/En cours)
With New DataObject
.GetFromClipboard
varCLIPBOARD = .GetText '(1)
End With
SheetA.Cells(LigneRef, CdeB_Col).Value = varCLIPBOARDCette solution ne fonctionne qu'à moitié.
Pour une raison incompréhensible, ça fonctionne 3 ou 4 fois puis j'ai un message d'erreur:
"Erreur d'exécution '-2147221040 (800401d0)': DataObject:GetText Échec de OpenClipboard"
J'ai pas mal cherché et je ne trouve pas vraiment de solutions.
Il y en a une qui consisterait à ouvrir le notepad et d'utiliser les sendkeys "^c" et "^v" mais non seulement ce n'est pas élégant mais utiliser les sendkeys me parait aller un peu à l'encontre de la programmation.
Enfin, j'ai vu des solutions en passant par des CLSID ou un truc du genre mais comme je ne suis pas Bill Gates... c'est incompréhensible et une sacrée usine à gaz.
Bref, si vous avez d'autres façons de faire, je suis preneur.
Récupérer le contenu du presse-papier me semble hyper simple dans l'approche et totalement en phase avec ce que je veux obtenir...
Merci d'avance pour votre aide.
Bonne journée.
Bonsoir pipout64, le forum,
Je veux coller tous ces n° de commande dans une seule cellule (de la feuille A)
Pas certain d'avoir tout compris, mais voici un exemple,
En espérant que cela t'aide...
Cordialement,
Bonjour xorsankukai,
Je te remercie de t'être penché sur mon problème.
L'utilisation de ce clipboard n'est pas fiable pour un rond.
Je voulais éviter de passer par des boucles parce que le fichier contient plus de 15 000 lignes.
Je trouvais que faire une recherche avec "pomme" (par exemple) dans le filtre automatique et copier toutes les cellules "cde" des lignes visibles filtrées était super pratique.
Il suffisait juste de récupérer ces cellules dans le presse-papier comme on pourrait les coller dans le notepad.
Ça prend 2 lignes de codage et c'est instantanée puisque le filtre automatique affiche directement toutes les "cde" pour la "réf" voulue sans boucler 15 000 lignes.
Sauf que ça fonctionne 3,4 fois et puis ça plante.
J'ai regardé ta solution et pffff... le gap de ouf entre ton niveau et le mien...
J'essaie de décoder chaque ligne pour apprendre et déjà ça commence par la déclaration des variables: je n'avais jamais vu les caractères "&".
J'ai donc cherché et vu que c'était une façon rapide de déclarer les long.
Ensuite, je ne comprends pas pourquoi ttes les variables ne sont pas typées (j'ai un peu plus de mal à comprendre le code si les variables ne sont pas explicitement typées): Newtab () c'est du variant ? et tb c'est du "range" (puisque currentRegion) ? Mais dans ce cas, pourquoi on ne set pas la variable ?
Je croyais que ttes les variables de types workbook, worksheets et range devaient être "settées" ?
Normalement currentRegion.Address renvoie une plage: je tente tb.Address et j'ai une erreur 424.
Ça me saoule parce que je code depuis quelque temps (mais trop peu et trop espacé) mais il me manque encore des clefs pour comprendre.
Pourtant si on raisonne avec des range, string etc.. je pense être capable de décoder les erreurs mais non...
Si tb est une range, pourquoi msgbox tb.Address n'est pas viable ?
J'a voulu typer les variables et du coup, ça plante.
Pareil pour "Like" et "Erase" que je vois pour la première fois et pour lesquels je me renseigne...
Bref, merci pour le temps que tu as passé pour moi.
Je suis capable de faire de bonne macros bien consistantes mais je ne suis même pas capable de typer les variables d'un code de 10 lignes !
Bonne journée à toi.
Bonjour pipout64, le forum,
Merci pour le retour,
Désolé, j'ai laissé quelques boulettes de mes précédents essais, je ne suis pas un pro non plus,
Private Sub Worksheet_Change(ByVal Target As Range)
Dim tb, i As Long, c As String
'si la cible est différent de A2, on quitte la procédure
If Target.Address <> "$A$2" Then Exit Sub
'agit sur feuil1 uniquement
With Sheets("Feuil1")
'définit le tableau de valeur tb (permet de travailler en mémoire)
tb = Sheets("Feuil2").Range("A1").CurrentRegion
'boucle sur toutes les lignes de tb
For i = 1 To UBound(tb, 1)
'si la première colonne de tb correspond à A2
If tb(i, 1) Like Target Then
'on stocke dans c,la valeur de la seconde colonne auquel je rajoute un saut à la ligne
c = c & Chr(10) & tb(i, 2)
End If
Next i
'si une erreur est générée, je poursuis
On Error Resume Next
'J'efface les données de B2
.Range("B2").ClearContents
'j'écris le contenu de dans B2 sans le premier saut de ligne
.Range("B2") = Right(c, Len(c) - 1)
'réinitialise la gestion des erreurs
On Error GoTo 0
End With
'libère la mémoire
Erase tb: c = ""
End SubPrends le temps de parcourir les cours du site, ça m'a beaucoup aidé...https://www.excel-pratique.com/fr/vba/variables
Cordialement,