IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

fusion de 2 tableaux à 2 dimensions [XL-2016]


Sujet :

Macros et VBA Excel

  1. #1
    Membre éclairé
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 300
    Par défaut fusion de 2 tableaux à 2 dimensions
    Bonjour,

    je souhaiterai supprimer certaines "lignes" d'un tableau, puis décaler toutes les lignes suivantes à la ligne précédente qui vient d'être supprimée.
    ce cas peut se présenter plusieurs fois dans mon tableau Tbl_P
    Pour le moment je n'ai pas trouver plus simple pour assembler 2 tableaux ou fusionner (code ci-dessous).

    Mon raisonnement:
    -> je détecte la ligne qui me pose problème par le IF
    -> je mets dans un 1er tableau tmp1 la partie de tbl_P jusqu'à la ligne qui me pose problème (càd de 0 to compteur-1)
    -> je mets dans un 2nd tableau tmp2 l'autre partie de mon tbl_P jusqu'à son Ubound (càd de compteur + 1 à Ubound de tbl_P)
    -> puis je fusionne tmp1 et tmp2 et c'est là que je rencontre une difficulté à fusionner voici mon code (je ne sais pas si je suis clair si il manque des éléments de compréhension je les apporte au fur et à mesure).

    donc
    1/ Est-ce qu'il faut se s'y prendre comme cela ?
    2/ du coup cela m'amène un pb sous-jacent, càd je perds le traitement d'1 ligne de mon tableau tbl_P à chaque retour dans la boucle If => comment faire ?
    Merci pour votre aide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    Dim tmp1(), tmp2() As Variant
     
     
    For compteur = LBound(Tbl_P, 2) To UBound(Tbl_P, 2)
     
    'je détecte la ligne qui me pose problème
    If (Tbl_P(2, compteur) = "Nom" Or Tbl_P(2, compteur) = "") then
     
       '1ere partie du tableau tbl_P à extraire ligne "précédente"
        ReDim tmp1(0 To 11, 0 To compteur - 1)
        For i = 0 To 11
            For k = 0 To compteur - 1
            tmp1(i, k) = Tbl_P(i, k)
            Next k
        Next i
     
        '2nd partie du tableau tbl_P à extraire ligne "suivante"
        ReDim tmp2(0 To 11, compteur + 1 To UBound(Tbl_P, 2))
        For i = 0 To 11
            For k = compteur + 1 To UBound(Tbl_P, 2)
            tmp2(i, k) = Tbl_P(i, k)
            Next k
        Next i
     
    'efface le contenu de tbl_p pour être propre   
    Erase Tbl_P
     
    'fusionne tmp1 et tmp2 pour obtenir tbl_P complet
       ReDim Tbl_P(0 To 11, LBound(tmp1, 2) To UBound(tmp2, 2))
       For i = 0 To 11
        For k = LBound(tmp1, 2) To UBound(tmp2, 2)
        If k <= UBound(tmp1, 2) Then Tbl_P(i, k) = tmp1(i, k) Else Tbl_P(i, k) = tmp2(i, k + 1) 'attention au k+1 je risque de lire quelque chose qui n'existe pas au dela de la dimension Ubound(tmp2,2)
        Next k
       Next i
     
    'perte de mémoire: maintenant lors du retour dans la boucle if, le compteur+1 de mon tableau tbl_P devient compteur 
    et je ne pourrai plus tester cette valeur car compteur passera à compteur +1
    exemple:
    la ligne n°90 du tableau doit être supprimée donc compteur = 90 
     je récupère les valeurs de Tbl_P dans tmp1 de 0 à 89 les, idem pour tmp2 mais de 91 à ubound de tbl_P, 
    j'assemble tmp1 et tmp2 pour reformer tbl_P càd que la ligne 91 de tmp2 devient 90 pour tbl_P, la ligne 92 de tmp2 devient 91 pour tbl_P, etc.
    dans ce cas 91 devient 90 et ne sera du coup pas traitée par la suite car compteur était à 90 dans la boucle if
    end if

  2. #2
    Rédacteur/Modérateur

    Avatar de Jean-Philippe André
    Homme Profil pro
    Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Inscrit en
    Juillet 2007
    Messages
    14 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Canada

    Informations professionnelles :
    Activité : Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 14 674
    Par défaut
    Salut,

    sans évoquer l'approche de départ, une solution qu'on recommande lorsqu'il s'agit de supprimer des lignes dans un tableau, est de commencer par la fin

    Tu auras la logique à adapter, mais tu éviteras le compteur à incrémenter/décrémenter selon tes résultats de tests.
    Cycle de vie d'un bon programme :
    1/ ça fonctionne 2/ ça s'optimise 3/ ça se refactorise

    Pas de question technique par MP, je ne réponds pas

    Mes ouvrages :
    Migrer les applications VBA Access et VBA Excel vers la Power Platform
    Apprendre à programmer avec Access 2016, Access 2019 et 2021

    Apprendre à programmer avec VBA Excel
    Prise en main de Dynamics 365 Business Central

    Coffrets disponibles de mes ouvrages : https://www.editions-eni.fr/jean-philippe-andre
    Pensez à consulter la FAQ Excel et la FAQ Access

    Derniers tutos
    Excel et les paramètres régionaux
    Les fichiers Excel binaires : xlsb,

    Autres tutos

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 438
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 438
    Par défaut
    Salut,

    Pourquoi faire simple quand on peut faire compliqué ?
    A moins que ton tableau n'occuper un espace mémoire conséquent,
    contente toi de recopier les lignes intéressantes.

    Exemple avec un tableau 1D (le même principe peut s'appliquer a un tableau 2D):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    Public Sub test()
        Dim Table(5 To 15) As Integer
        GetData Table       '// initialisation du tableau
     
            '// instanciation d'un 2nd tableau aussi grand que le 1er
        Dim TableCopy() As Integer
        ReDim TableCopy(LBound(Table) To UBound(Table))
     
        Dim IndexCible As Integer
        IndexCible = LBound(TableCopy)
     
        Dim IndexSource As Integer
        For IndexSource = LBound(Table) To UBound(Table)
                '// on ne conserve que les elements pairs
            If ((Table(IndexSource) Mod 2) = 0) Then
                TableCopy(IndexCible) = Table(IndexSource)
                IndexCible = IndexCible + 1
            End If
        Next
            '// on supprime les elements non utilisés, qui se trouvent à la fin du tableau
        ReDim Preserve TableCopy(LBound(TableCopy) To IndexCible - 1)
    End Sub
     
    Private Sub GetData(ByRef Table() As Integer)
        Dim i As Integer
        For i = LBound(Table) To UBound(Table)
            Table(i) = i
        Next
    End Sub
    PS: Les tableau dynamiques étant pénible à gérer, je recommande plutôt l'utilisation de collections.

  4. #4
    Membre éclairé
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 300
    Par défaut
    Bonjour deedolith,

    ça répond à mon problème votre routine. Voici donc mon adaptation sur 2 dimensions et ça fonctionne très bien.
    Je partage donc la solution:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    Dim indexcible, indexsource As Integer
    Dim tablecopy() As Variant
    ReDim tablecopy(0 To 11, UBound(Tbl_P, 2))
    indexcible = LBound(tablecopy)
     
     
    For indexsource = LBound(Tbl_P, 2) To UBound(Tbl_P, 2)
     
     
    If (Tbl_P(2, indexsource) <> "Nom du propriétaire" And Tbl_P(2, indexsource) <> "" And Tbl_P(0, indexsource) <> "§") And _
    (IsNull(Tbl_P(2, indexsource)) <> True And (Replace(Tbl_P(0, indexsource), ".", "") <> "vente " And Replace(Tbl_P(0, indexsource), ".", "") <> "achat")) Then
     
    For i = 0 To 11
                If indexcible <= indexsource Then
                tablecopy(i, indexcible) = Tbl_P(i, indexsource)
                End If
    Next i
    indexcible = indexcible + 1
    End If
     
    Next indexsource
    ReDim Preserve tablecopy(0 To 11, LBound(tablecopy) To indexcible - 1)
    Erase Tbl_P
    Tbl_P= tablecopy


    Je dérive le sujet. J'ai à l'inverse des lignes à ajouter. Ca fonctionne, mais ce n'est pas très beau. Peut-on coder de manière plus courte (un peu comme dans la solution de mon problème initial) ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    Dim k, i As Integer
    Dim tmp3() As Variant
     
    ReDim tmp3(0 To 11, 0 To 90)
     
        For k = 0 To 90
            For i = 0 To 11
            tmp3(i, k) = Tbl_P(i, k)
            Next i
        Next k
     
    ReDim Preserve tmp3(0 To 11, 0 To UBound(Tbl_P, 2) + 1)
    tmp3(0, 91) = "achat.1"
     
       For k = 92 To 204
                For i = 0 To 11
                tmp3(i, k) = Tbl_P(i, k - 1)
                Next i
        Next k
     
    ReDim Preserve tmp3(0 To 11, 0 To UBound(Tbl_P, 2) + 2)
    tmp3(0, 205) = "achat.5"
     
       For k = 206 To UBound(Tbl_P, 2) + 2
                For i = 0 To 11
                tmp3(i, k) = Tbl_P(i, k - 2)
                Next i
        Next k
     
    Tbl_P= tmp3

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/07/2007, 23h55
  2. Tableaux 2 dimensions ou tableau de listes linéaires chaînées?
    Par mimina dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 16/11/2006, 16h17
  3. Tableaux 2 dimensions dynamiques
    Par onegamer dans le forum Struts 1
    Réponses: 1
    Dernier message: 06/07/2006, 13h55
  4. Réponses: 4
    Dernier message: 21/03/2006, 05h55
  5. [langage] erreurs utilisation tableaux 2 dimensions
    Par drosof dans le forum Langage
    Réponses: 11
    Dernier message: 01/07/2003, 12h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo