[VBA] recopier informations

Bonjour,

Je souhaiterais, par VBA, recopier des informations de cellules d'un onglet A vers un onglet B

Dans mon onglet A
Colonne A - Colonne B - Colonne C
TARTEMPION - Prénom - Numéro
MACHIN - Prénom2 - Numéro

Dans mon onglet B
Colonne A Colonne D
Numéro
TARTEMPION Numéro
Prénom MACHIN
Prénom

L'identifiant est le numéro
Les numéros de la colonne C de l'onglet A ne sont pas triés.

Merci de votre aide.
ed
Configuration: Windows XP
Firefox 2.0.0.15

22 réponses

Résumé de la discussion

Plusieurs utilisent VBA pour recopier des informations d'un onglet A vers un onglet B en utilisant le numéro de la colonne C non triée comme identifiant, afin d'associer Prénom et Numéro sur B. La meilleure réponse recommande d'améliorer les performances en parcourant la feuille de répartition une seule fois, plutôt que de balayer toutes les cellules, tout en préservant l'association numéro-information. D'autres échanges portent sur l'utilisation d'arrays 2D et ReDim Preserve, l'importance d'UBound et des détails comme Option Explicit et possibilité de déclarer la macro Private, afin d'améliorer stabilité et clarté. En cas de gros fichiers, plusieurs observations soulignent que les performances dépendent de la méthode d'indexation et que des erreurs d'indice ou des questions de dimensionnement exigent des tests.

Bobot (l’IA à votre service)
  1. j ai pas trop compri la disposition de ton onglet B peux tu continuer ton exemple et separer chaque colone par des |
    1. Hello Vautour,

      Je m,apercois que ma question n'est pas très claire en fait.
      Je recommence

      Onglet A
      Colonne A | Colonne B | Colonne C
      NOM | Prénom | Numéro

      Cet onglet comporte environ 20.000 noms. Certains ont des numéros dans la colonne C, d'autres pas.

      Onglet B
      Dans cet onglet, je veux disposer certains noms qui ont des numéros dans l'onglet A (colonne C non triée) dans un ordre pré-défini

      Colonne B | Colonne C | Colonne D | Colonne E | Colonne F....
      Numéro | Numéro | Numéro | Numéro | Numéro |....
      TARTEMPION | MACHIN |(vide) | TRUCMUCHE | DUPONT
      Prénom| Prénom |(vide) | Prénom | Prénom

      L'identifiant est le numéro. C'est à dire que dans mon onglet B, j'ai le numéro à une place donnée et fixe.
      et je voudrais ratacher à ce numéro les informations de l'onglet A.

      En espérant être plus clair (pas certain... lol)
      Un gros merci d'avance.
      ed
      1. lol donc si j ai bien compris, tu prend un nom et prenom de l onglet A qu'y n'a pas de numero et tu trouve ce numero dans l onglet B? c'est bien ca?
    2. En fait, je prends le nom et le prénom de l'onglet A
      en fonction du numéro qu'il a en colonne C(ongletA), je place le nom et le prénom dans l'onglet B à ll'endroit où se trouve le numéro en onglet B

      Sur les 20.000 noms, j'ai environ 5.000 noms à distribuer dans l'onglet B.
      Merci.
      ed
      1. Onglet A
        Colonne A | Colonne B | Colonne C
        NOM | Prénom | Numéro

        Colonne B | Colonne C | Colonne D | Colonne E | Colonne F....
        Numéro | Numéro | Numéro | Numéro | Numéro |....
        TARTEMPION | MACHIN |(vide) | TRUCMUCHE | DUPONT
        Prénom| Prénom |(vide) | Prénom | Prénom

        je ve appele les onglet des feuille pour utiliser les mot correct

        a=1 'remplace le 1 par le numero de la premiere ligne de la feuille A
        do while worksheets("NOMFEUILLEA").cells(a,1).value <> ""
        b=1 'remplace le 1 par le numero de la premiere ligne de la feuille B
        do while worksheets("NOMFEUILLEB").cells(1,b).value <> worksheets("NOMFEUILLEA").cells(a,3).value
        'j espere que sur ta feuille B les numero son a la ligne 1, sinon il siffu de remplacer le 1 de .cells(1,b). ci dessu par le bon numero
        b=b+1
        loop
        'pour les nom
        if worksheets("NOMFEUILLEB").cells(2,b).value = "" then
        worksheets("NOMFEUILLEB").cells(2,b).value=worksheets("NOMFEUILLEA").cells(a,1).value
        elseif worksheets("NOMFEUILLEB").cells(2,b).value=worksheets("NOMFEUILLEA").cells(a,1).value then
        worksheets("NOMFEUILLEA").cells(a,1).interior.colorindex=4
        elseif worksheets("NOMFEUILLEB").cells(2,b).value<>worksheets("NOMFEUILLEA").cells(a,1).value then
        worksheets("NOMFEUILLEA").cells(a,1).interior.colorindex=3
        endif
        'pour les prenom
        if worksheets("NOMFEUILLEB").cells(3,b).value = "" then
        worksheets("NOMFEUILLEB").cells(3,b).value=worksheets("NOMFEUILLEA").cells(a,2).value
        elseif worksheets("NOMFEUILLEB").cells(3,b).value=worksheets("NOMFEUILLEA").cells(a,2).value then
        worksheets("NOMFEUILLEA").cells(a,2).interior.colorindex=4
        elseif worksheets("NOMFEUILLEB").cells(3,b).value<>worksheets("NOMFEUILLEA").cells(a,2).value then
        worksheets("NOMFEUILLEA").cells(a,2).interior.colorindex=3
        endif
        a=a+1
        loop

        pour les couleur qui von apparaitre dans la feuille A, vert = identique, rouge= pas identique, blanc = normalement copier
      2. @vautour88Merci Vautour pour ce coup de main. Je vais tester.
        cordialement
        ed
    3. Contributeur
      Bonjour,
      En fait je veux pas me meler à la discution mais si tu mettais un exemple de fichier avec une feuille du résulat souhaiter sur ci-joint ca aiderait fortement vautour à te comprendre.
      https://www.cjoint.com/
      et mettre le lien dans un poste suivant... A+
      1. Contributeur
        Bonjour,

        Sans vouloir m'en meler non plus, tu parles de 5000 à 20000 noms à répartir dans des colonnes selon un numéro.
        Mais dans excel 2003 tu n'as que 256 colonnes (16384 dans excel 2007)...
        Va falloir être plus explicite : plusieurs noms pour le même numéro et faut les écrire en colonne ?
        Les numéros sont déjà inscrits dans l'onglet B ?
        Certains ont des numéros dans la colonne C, d'autres pas. Ceux qui n'en ont pas faut en faire quoi ?

        eric
        1. Contributeur
          Sans vouloir vexer personne, il ne ressemble pas à grand chose ton onglet Repartition...
          Te rends tu compte qu'il faut balayer TOUTES les cellules pour trouver un numéro ?
          Et ça 5000 à 20000 fois... Ca risque de prendre un temps énorme.

          Et quand tu écris [ici Date], il faut comprendre date reconstituée avec jour-mois- année ?
          Si oui, excel le stocke sous forme de nombre, j'espère que tu n'as pas de numéro qui depasse les 36000 car il risque d'y avoir des doublons avec les dates.

          eric
          1. Tu ne vexes personne, enfin pas moi en tous cas.
            Ton avis est précieux.
            Cela signifie simplement que mon idée n'est pas réalisable et c'est parfois bien de connaître les limites de ce que l'on peut faire.
            J'avais dans l'idée que RECHERCHEV en vba était la solution sans savoir comment écrire ma private sub.

            Merci pour le temps passé
            cordialement
            ed
            1. Contributeur
              Bonjour,

              je n'ai pas dit impossible, mais que le traitement risquait d'être long...
              J'ai optimisé pour que la feuille répartition ne soit parcourue qu'une fois :
              http://www.cijoint.fr/cjlink.php?file=cj200807/cijARJ821G.xls

              eric
              1. Franchement Eriic, c'Est GÉ-ANT...

                Un BIG BIG MERCI pour cette performance. Et pardon de ne pas avoir réagi plus tot... J'étais en déplacement.

                Peux tu juste m'expliquer ce que signifie option explicit ?
                Crois tu que je puisse mettre la sub en private sub?

                Merci encore, vraiment j'apprécie autant d'entraide.

                Cordialement
                ed
                1. Contributeur
                  Bonsoir,

                  De rien... ;-)
                  Option Explicite oblige à déclarer les variables (et donc à éviter les bugs difficiles à trouver si on fait une erreur de frappe sur un nom de variable).
                  Tu peux mettre la macro en private bien sûr, mais fais le lien avec un bouton avant.

                  eric
                  1. Je suis en train de tester ton code sur mon big fichier.
                    Et au no.1001, il me dit que l'indice n'appartient pas à la sélection.
                    Peux tu m'expliquer aussi ce que ReDim num(1000,1) signifie?

                    merci
                    ed
                    1. Contributeur
                      Ah, ben c'était prévu pour agrandir le tableau en cas de besoin justement.
                      Bizarre, je jette un oeil...
                      1. Contributeur
                        Comprend pas, je viens de tester ça marche.
                        A défaut remplace ReDim num(1000, 1) par ReDim num(8000, 1) (un peu plus que ton nombre maxi de numéros en fait)

                        Heuuu, précise quand même à quelle ligne tu as l'erreur stp, c'est peut-être dans la 2nde partie
                        1. pas de probleme... ça marche sur ton exemple aussi...

                          Dans mon big fichier, la ligne

                          num(nbNum, 0) = c.Value me fait une erreur d'exe No. 9

                          qd je fais un pas à pas détaillé, le nbNum est à 1001.
                          J'ai mis 10 000 et ça bugue à 10 001...
                          c'est pour ça, je me demandais ce que 1000 voulait dire.

                          merci
                          ed
                          1. Contributeur
                            ok, vu
                            rajoute ,1 à la fin de If nbNum = UBound(num) Then ReDim num(UBound(num) + 1000)
                            pour obtenir :
                            If nbNum = UBound(num) Then ReDim num(UBound(num) + 1000, 1)

                            J'avais oublié la 2nde dimension dans le redim...

                            eric
                            1. CHapeau-Bas!

                              Maintenant la macro fonctionne complètement.
                              Seul bémol, les infos ne s'inscrivent pas dans ma big feuille répartition.
                              Je regarderai cela de plus près demain et te tiendrai au courant si pb.

                              Encore Merci. J'aurais été incapable de trouver un tel code et j'apprends bcp.
                              Bonne nuit
                              ed
                              1. Contributeur
                                Bonjour ,
                                Je pense que si le redimentionnement doit se faire il faudrait employer __ Preserve __ pour ne pas effacer les données déjà présentes.
                                Mais si le mot Preserve est employer faudra modifier ReDim num(1000, 1)
                                par
                                ReDim num(1,1000)
                                If nbNum = UBound(num , 2) Then ReDim Preserve num( 1, UBound(num , 2) + 1000)

                                Et adapter le code.
                                A+
                                1. Contributeur
                                  Bonjour lermite et merci,

                                  oui, tout à fait, il faut utiliser preserve.
                                  Et le code devient :
                                  Sub Remplir()
                                      Dim c As Range, nbNum As Long, nonTrouvé As Long, i As Long
                                      ' recup position numéros
                                      Dim num()
                                      ReDim num(1, 1000)
                                      Sheets("REPARTITION").Select
                                      For Each c In Range([A1], [A1].SpecialCells(xlCellTypeLastCell))
                                          If IsNumeric(c.Value) Then
                                              If c.Value > 0 Then
                                                  nbNum = nbNum + 1
                                                  num(0, nbNum) = c.Value
                                                  num(1, nbNum) = c.Address
                                                  If nbNum = UBound(num) Then ReDim Preserve num(1, UBound(num) + 1000)
                                              End If
                                          End If
                                      Next c
                                      ' remplir
                                      Sheets("DONNEES").Select
                                      For Each c In Range([E2], [E65536].End(xlUp))
                                          i = 1
                                          Do Until c.Value = num(0, i) Or i > nbNum
                                              i = i + 1
                                          Loop
                                          If c.Value <> "" Then
                                              If i <= nbNum Then
                                                  Worksheets("REPARTITION").Range(num(1, i)).Offset(2, 0) = c.Offset(0, -4)
                                                  Worksheets("REPARTITION").Range(num(1, i)).Offset(3, 0) = c.Offset(0, -3)
                                                  Worksheets("REPARTITION").Range(num(1, i)).Offset(4, 0) = c.Offset(0, -2)
                                              Else
                                                  nonTrouvé = nonTrouvé + 1
                                              End If
                                          End If
                                      Next c
                                      i = MsgBox("Références absentes : " & nonTrouvé, vbInformation + vbOKOnly)
                                  End Sub


                                  Là je pense que c'est bon :-)
                                  Bonne journée tout le monde
                                  1. Contributeur
                                    Je veux pas ergoter mais je pense que la ligne.. :D
                                    If nbNum = UBound(num) Then ReDim Preserve num(1, UBound(num) + 1000)

                                    devrait-être..
                                    If nbNum = UBound(num,2) Then ReDim Preserve num(1, UBound(num, 2) + 1000)
                                    ou plus simple
                                    If nbNum = UBound(num, 2) Then ReDim Preserve num(1, nbNum + 1000)

                                    :D
                                    A+
                                    • 1
                                    • 2