XL 2010 mise à jour de deux tableaux avec une boucle d'exécution rapide

Niquido

XLDnaute Junior
Bonjour à tous,

Voila j'ai deux tableaux et je veux mettre à jour le tableau "tbl_bdd" qui se trouve dans la feuille "BDD" avec les lignes qui se trouvent dans le tableau "tbl_inflow" qui se trouve dans la feuille "inflow".

Je souhaite faire une boucle qui recherche la valeur par exemple de la cellule A1 du tableau tbl_inflow dans la colonne A du tableau tbl_bdd.
Si la valeur est trouvée je veux que la ligne du tableau tbl_inflow écrase la ligne tu tableau tbl_bdd.
Si la valeur n'est pas trouvée je veux que la ligne du tbl_inflow vienne s'ajouter à la fin du tableau tbl_bdd.

J'ai commencé un code mais je n'ai pas l’habitude de faire de boucle dans mes macros du coup je pêche un peu => en gros ça ne marche pas dès le début de ma boucle.
De plus il faut que l'exécution soit assez rapide car évidement c'est pour traiter une quantité importante de données.

Merci d'avance.
 

Pièces jointes

  • Classeurtest.xlsm
    24.3 KB · Affichages: 50

Dranreb

XLDnaute Barbatruc
Bonjour.
qui recherche la valeur par exemple de la cellule A1
Ce "par exemple" me paraît bizarre. Ça devrait toujours être la ou les mêmes colonnes qui identifie(nt) la ligne. J'aurais plus facile à classer la BDD et donc à insérer la nouvelle ligne non pas forcément à la fin mais à sa place de classement.
Dans votre code c'est la feuille "inflow" que vous modifiez, contrairement à vos explications où ce serait la "BDD"
 

Niquido

XLDnaute Junior
Bonjour Dranreb,

Tout d'abord merci pour ton intérêt à mon problème et dsl pour la réponse tardive du coup tu as déjà travaillé sur un code et je t'en remerci je vais regarder cela.

Je répond quand même à ton premier message ci-dessous.
C'est bien le tableau bdd que je souhaite mettre à jour avec le tableau inflow.
Quand je dit par exemple A1 c'était pour dire je prend la première référence du tableau inflow.
Oui il faut balayer toutes les références du tableau inflow pour vérifier leur existence ou non dans le tableau bdd et en fonction soit écraser la ligne soit la rajouter à la fin du tableau.

Les valeurs que j'ai mise sont purement inventer il n'est pas nécessaire de les classer lorsqu'on rajoute les lignes dans le tableau bdd, je peux trier par la suite le tableau. Est ce que je répond bien à ta question?
 

Niquido

XLDnaute Junior
Re bonjour Dranreb,

Je te remercie ta macro s'exécute instantanément c'est géniale !!!!
maintenant il faut que je regarde tout ça car à première vu je ne connait pas du tout ce type de programmation, j'espère que je suis compréhensible.
Et par la suite que j'arrive à l'adapter à mon fichier d'origine.
Cela risque de me prendre du temps avant de te faire un retour convenable, alors je te dis dors et déjà merci pour ce que tu as fais !!!!!
 
Dernière édition:

Niquido

XLDnaute Junior
Bonjour Dranreb,

J'ai quelques questions à te poser, car j'ai incruster ta macro dans mon gros fichier (plus de 50000 lignes et 20 colonnes à comparer ;)):
  1. La macros me dit dépassement de capacité et me renvoi sur la ligne "Case "ListObject": TSrc = TP(P).DataBodyRange.Value" du module MTableaux. Dsl mais je ne comprend pas pourquoi, surtout que quand je refait mes 2 tableaux dans un nouveau fichier ça marche très bien :confused::confused::confused: ? 22-03-2017 15-18-01.jpg
  2. Est il possible lors de la création du tableau final de garder les "0" qui se trouve devant les nombres dans les colonnes B; D; F; H; J; L stp ? Ou alors, si c'est plus simple pour toi, que la macros considère que tout est en texte mais je ne sais pas si ça me gainera pour la suite.
  3. Une fois le tableau mis à jour je filtre la colonne C en prenant tout ce qui ne contient pas "ACC", "DIF", "INP", "RET" et je supprime toutes les lignes apparentes. Seul problème je doit vérifier si une fois filtrer il y a bien des lignes avant de les supprimer, et le fait de les supprimer dur un certain temps. ==> Du coup est il possible une fois que le tableau est mis à jours dans la variable de supprimer toutes les lignes qui n'ont pas dans la colonne C les références citées ci-dessus et seulement après d'écrire le nouveau tableau ?
Gros plus ;) :
Je fais des recherches dans les colonnes suivantes (21ème et plus)
Est il possible de faire autrement que ce que je fais pour que cela soit plus rapide ?
Moi je copie la formule qui marche bien dans la colonne, puis je copie colle en dure le résultat.
  1. Il y a une colonne où je regarde les digits de la première colonne qui sont devant le "-" et je recherche dans un tableau ou mes références sont listées puis je renvois le lieu.
  2. Dans une colonne je regarde si la "colonne14" contient la lettre "R" ou "C" mais attention juste "C" pas "CO" d'où ma formule qui regarde le premier ou le dernier caractère seulement car le "R" ou le "C" sont toujours placés à ces positions là.

Merci d'avance Dranred
 

Pièces jointes

  • Avancement fichier 2.xlsm
    6.8 MB · Affichages: 50

Dranreb

XLDnaute Barbatruc
Bonjour
1. J'ai exécuté un coup MAJ et je n'ai pas eu de problème, et je ne vois pas comment ça peut se produire. Mettez des epions si ça se reproduit.
2. Mettez des formats "Texte" dans ces colonnes
3. Il serait plus simple de ne pas exécuter L = L + 1: For C = 1 To 20: T(L, C) = Src2(C): Next C
si Src2(3) ne contient pas une de ces valeurs
C'est sûr que perso je me déclarerais un variable LO1 As ListObject, initialisée au début par
Set LO1 = Feuil1.ListObjects("tbl_bdd") et j'accèderais au colonnes par LO1.Columns("lieu").DataBodyRange
Du moins si j'avais à travailler sur les cellules. Mais je préfère éviter.
Peut être que j'utiliserais plutôt un Dictionary.
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonsoir Niquido, Dranreb ;),

Un essai avec dictionnaire.
VB:
Sub miseAjour()
Dim dicoBDD, xcell
  Application.ScreenUpdating = False
  Set dicoBDD = CreateObject("scripting.dictionary")
  For Each xcell In Range("tbl_bdd[numéro]")
    If Not dicoBDD.exists(xcell.Value) Then
      dicoBDD(xcell.Value) = xcell.Row
    Else
      MsgBox " Le numéro de BDD '" & xcell.Value & "' existe en double en ligne " & _
              dicoBDD(xcell.Value) & " et " & xcell.Row & "   -> échec de la MàJ"
      Exit Sub
    End If
  Next xcell

  With Worksheets("BDD")
    For Each xcell In Range("tbl_inflow[numéro]")
      If dicoBDD.exists(xcell.Value) Then
        .Range("a" & dicoBDD(xcell.Value)).Resize(, 9) = xcell.Resize(, 9).Value
      Else
        .Range("a" & Range("tbl_bdd[numéro]").Rows.Count + 2).Resize(, 9) = xcell.Resize(, 9).Value
      End If
    Next xcell
    .ListObjects("tbl_bdd").Range.Sort Key1:=Range("tbl_bdd[numéro]"), Order1:=xlAscending, Header:=xlYes
  End With
End Sub
 

Pièces jointes

  • Niquido- MàJ Tableaux- v1a.xlsm
    28.4 KB · Affichages: 67
Dernière édition:

Niquido

XLDnaute Junior
Bonjour mapomme,

Merci pour ta macro, par contre ce n'est pas tout à fait ce que je souhaite arriver à faire.
Il ne faut pas que la macro s’arrête si une valeur est en doublon mais justement que la donnée du tbl_inflow écrase la donnée du tbl_bdd.:oops:
 

Niquido

XLDnaute Junior
Bonjour Dranreb,

Pour le 1er point sur le fichier que j'ai mis sur le forum tout marche très bien mais mon autre fichier je ne comprend pas pourquoi ça ne marche pas. Du coup j'ai refait un nouveau fichier et la tout va bien:confused: c'est à n'y rien comprendre.
Pour le 2nd point c'est bon en mettant au format texte ç'est nickel.
Pour le 3ème point dsl mais du coup je ne comprend pas. Je suis dsl mais je ne comprend pas toute ta macro, elle est trop longue pour moi et je ne sais pas codé comme tu le fais, de plus je ne sais pas ce qu'est un dictionary ==> je suis en pleine recherche et apprentissage la dessus du coup maintenant.;)

A plus tard !:)
 

Dranreb

XLDnaute Barbatruc
Bonjour.
Ma macro d'origine n'était pas longue, c'est vous qui avez rajouté plein de choses.
Je tentais d'expliquer que c'est complètement idiot de créée toutes les lignes et de rajoutez du code derrière pour enlever celles qu'il ne fallait pas, il vaut mieux ne pas créer, au départ, les lignes qu'il ne faut pas !
Débrouillez pour que le Cas = Cas Or 2 ne soit exécuté que si c'est une donnée à conserver.
 

Niquido

XLDnaute Junior
Bonjour Dranreb,

Oui ta macros est courte, mais tout le reste qu'il y à dans "MGigogne" et "MTableaux" c'est ça que je trouve long. ;)
Effectivement j'ai rajouté des lignes, pour faire quelques calculs dans les colonnes 21, 22 et 23.
Et enfin supprimer toutes les lignes qui ne contiennent pas "CAN", "INA", "RCA, "RET" et "REJ" dans la colonne 3 parce-que je ne sais pas faire ce que tu me propose mais je suis d'accord avec toi c'est ce qu'il y à de mieux à faire et pas les supprimer après.
 

Dranreb

XLDnaute Barbatruc
Et vous n'avez rien vu. La bibliothèque Excel est certainement des centaines de fois plus grosse et plus compliquée ! Mais sa programmation vous est bien sûr inaccessible. Dois je rendre inaccessible la programmation de mes modules de service ? Ou seulement regrouper tous les commentaires guides d'utilisation dans un manuel Word et les enlever carrément des
modules ?
J'en ai marre de cette critique. Si ça continue je vais finir par ne plus proposer ces solutions qu'avec un classeur xlam complémentaire, au projet VBA protégé par un mot de passe…
Comme le Solver.

Esayez comme ça :
VB:
Sub MAJ()
Dim LOBD As ListObject, Données As Collection, Numéro As SsGr, T(), L&, C&, Cas%, Détail, Src1(), Src2()
Set LOBD = Feuil1.ListObjects("tbl_bdd")
Set Données = Gigogne(TableUnique(LOBD, Feuil2.ListObjects("tbl_inflow")), 1)
ReDim T(1 To Données.Count, 1 To 9)
For Each Numéro In Données
   Cas = 0
   For Each Détail In Numéro.Co
      If Détail(0) = 0 Then
         Src1 = Détail: Cas = 1
      Else
         Src2 = Détail
         Select Case Src2(3)
            Case "CAN", "INA", "RCA", "RET": Cas = Cas Or 2
            End Select: End If
      Next Détail
   Select Case Cas
      Case 1: L = L + 1: For C = 1 To 9: T(L, C) = Src1(C): Next C ' N'existe que dans BDD.
      Case 2: L = L + 1: For C = 1 To 9: T(L, C) = Src2(C): Next C ' N'existe que dans Inflow.
      Case 3: L = L + 1: For C = 1 To 9: T(L, C) = Src2(C): Next C ' Existe des deux cotés.
      End Select: Next Numéro
LOBD.ListRows(1).Range.Resize(L).Value = T
À tester.
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonsoir Niquito,

Si le message annonçant un doublon apparaît, c'est qu'il y a un doublon au sein même de la base BDD (rien à voir avec tbl_inflow).
Ce qui ne devrait sans doute pas se produire. C'est pourquoi la macro s'arrête et laisse la main à l'utilisateur pour corriger BDD.
 

Niquido

XLDnaute Junior
Bonjour Dranreb,
Cela faisait longtemps ;-)
dsl mais j'ai du travailler sur d'autre projet et sur celui ci avec pas mal d'évolution.
J'ai de nouveau le problème "Erreur d'exécution '6': Dépassement de capacité"
Et ça me renvois dans le module MTableaux à la ligne ci-dessous.
Case "ListObject": TSrc = TP(P).DataBodyRange.Value
Je ne comprend pas pourquoi ça me refait cette erreur, alors que ça ne me le faisait plus lorsque j'ai recommencé mon fichier de zéro.

Pourrais tu m'aider stp ?
Je te met le fichier en pièce jointe mais par la suite je devrai l'enlever.

Merci d'avance
 

Discussions similaires

Réponses
21
Affichages
893

Statistiques des forums

Discussions
311 720
Messages
2 081 924
Membres
101 841
dernier inscrit
ferid87