VBA - tri sur plusieurs plages de cellules spécifiques

Résolu
Harry_Seldon Messages postés 4 Statut Membre -  
Harry_Seldon Messages postés 4 Statut Membre -
Bonjour à toutes et à tous,

Je suis confronté à un petit problème sur VBA. Je réalise un programme permettant de trier des factures selon le numéro de compte et la date et ce, par fournisseur. Le tableau se présente de la manière suivante:


Problème :
Je souhaiterais que le programme trie les factures par n° de compte (Colonne B ) puis par date (colonne A) pour chaque fournisseur (FOURNISSEUR 1,2,3...).
La plage de cellule sur laquelle le programme effectuera le tri devra donc se réinitialiser à chaque fois que nous passons une ligne fournisseur.

Exemple :
Après avoir passé la cellule B3 FOURNISSEUR 1, le programme effectuera un tri de la cellule B4 à la cellule B11 pour le n° compte. Il réalisera un tri de la cellule A4 à la cellule A11 pour la date. Puis, après avoir réalisé les deux tris, il passera à la cellule B12 FOURNISSEUR 2. Il réitérera les mêmes opérations pour les cellules jusqu'au FOURNISSEUR 3 ect.

Le gros problème pour ma part vient du fait de définir automatiquement la plage de tri (Ex: B4 à B11 & A4 à A11) puis de la réinitialiser pour générer une nouvelle plage de tri (Ex: B13 à B20 & A13 à A20). Je pensais me baser sur le fait que les cellules FACTURE de la colonne B commencent toujours par un chiffre (51200000 FACTURE 3) pour pouvoir m'aider à définir la plage de données mais je bloque sur l'utilisation d'une boucle Do While. Auriez-vous des pistes à me proposer?

J'espère que mes indications sont claires et n'hésitez pas à me demander plus de précisions.

Un grand merci à toutes et à tous pour votre aide :)

2 réponses

  1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    bonjour, peux-tu partager ton programme?
    1
    1. Harry_Seldon Messages postés 4 Statut Membre
       
      Bonjour yg_be merci pour ton retour

      Le code est le suivant :
      Sub tri()
      'Tier les comptes
      'Création des variables
      Dim debut_palge As Integer 'création d'une variable pour le début de la plage de selection
      Dim fin_plage As Integer 'création d'une variable pourla fin de la plage de selection
      Dim DerniereLigne As Integer 'création de la variable dernière ligne
      'Affectation des variables
      DerniereLigne = Range("A" & Rows.Count).End(xlUp).Row 'Affectation de la viariable dernière ligne
      'Création de la boucle pour definir la plage de selection pour le tri par numéro de compte
      For i = 3 To DerniereLigne 'boucle de la 3ème a la dernière ligne
          For j = 2 To 2  'boucle de la deuxième colonne
              If IsNumeric(Left(Cells(i, j), 1)) = True Then 'si le premier caractère de la cellule est numérique
                  debut_palge = Cells(i, j) 'on affecte les coordonnées de cells à debut_plage
              End If
              If IsNumeric(Cells(i + 1, j)) = False Then 'si le premier caractère de la cellule suivante n'est pas numérique (F de FOURNISSEUR) alors cette cellule est la fin de la plage de donnée pour le tri
                  fin_plage = Cells(i, j) 'on affecte les coordonnées de cells à fin_plage
              End If
              Range(debut_plage, fin_plage).Sort Key1:=Range("B1"), Order1:=xlAscending 'tri de debut_plage à fin_plage
          Next
      Next
      End Sub


      Cependant ce code me fait ressortir la boite d'erreur suivante :


      Merci beaucoup pour ton aide.
      0
  2. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    merci de spécifier à quelle ligne de code se produit l'erreur.
    je suggère d'ajouter
    option explicit
    en début de module.
    quelques changements:
    Dim debut_plage As range 'création d'une variable pour le début de la plage de selection
    Dim fin_plage As range 'création d'une variable pourla fin de la plage de selection
    Dim DerniereLigne As long 'création de la variable dernière ligne
    dim i as long
    'Affectation des variables
    DerniereLigne = Range("A" & Rows.Count).End(xlUp).Row 'Affectation de la viariable dernière ligne
    'Création de la boucle pour definir la plage de selection pour le tri par numéro de compte
    For i = 3 To DerniereLigne 'boucle de la 3ème a la dernière ligne
            If IsNumeric(Left(Cells(i, 2), 1))  Then 'si le premier caractère de la cellule est numérique
                set debut_plage = Cells(i, 1) 'on affecte les coordonnées de cells à debut_plage
            End If
            If ! IsNumeric(Cells(i + 1, 2))  Then 'si le premier caractère de la cellule suivante n'est pas numérique (F de FOURNISSEUR) alors cette cellule est la fin de la plage de donnée pour le tri
                set fin_plage = Cells(i, 3) 'on affecte les coordonnées de cells à fin_plage
                Range(debut_plage, fin_plage).Sort Key1:=Range("B1"), Order1:=xlAscending 'tri de debut_plage à fin_plage
            End If
    Next i
    End Sub
    1
    1. Harry_Seldon Messages postés 4 Statut Membre
       
      Le message d'erreur ne renvoie à aucune ligne de code en particulier mais cela provenait sûrement du type de variable (integer au lieu de range et long).



      Merci pour votre proposition de code. J'ai quelques questions sur celui-ci (en vert ci-dessous):
      Sub tri()
      Dim debut_plage As Range
      Dim fin_plage As Range
      Dim DerniereLigne As Long
      DerniereLigne = Range("A" & Rows.Count).End(xlUp).Row
      For i = 3 To DerniereLigne
              If IsNumeric(Left(Cells(i, 2), 1)) Then
                  Set debut_plage = Cells(i, 2) 'Je me suis permis de changer le n° de colonne à 2 (au lieu de 1)  pour que la variable debut_plage soit dans la colonne B.
              End If
              If ! IsNumeric(Cells(i + 1, 2)) Then 'Quel est l'impact du ! sur le code? il semble le bloquer.
                  Set fin_plage = Cells(i, 2) 'Je me suis permis de changer le n° de colonne à 2 (au lieu de 3)  pour que la variable fin_plage soit dans la colonne B.
                  Range(debut_plage, fin_plage).Sort Key1:=Range("B1"), Order1:=xlAscending
              End if
      Next i
      End Sub


      Ce code permet bien de réaliser le tri des lignes selon le numéro de compte cependant il classe également les lignes fournisseurs (ci dessous).

      Je souhaiterais qu'il puisse réaliser ce tri par fournisseur (ci-dessous)


      Cependant je ne vois pas trop comment transcrire cette problématique en VBA.Auriez-vous une idée? Merci beaucoup.
      0
      1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588 > Harry_Seldon Messages postés 4 Statut Membre
         
        quand il y a une erreur, en général, une ligne est sélectionnée, c'est cette ligne qui provoque l'erreur.
        le ! doit être remplacé par not.
        je pense que le tri doit se faire sur une zone qui a trois colonnes de largeur, donc la zone doit commencer sur une cellule en colonne 1, et se terminer sur une cellule en colonne 3.
        je suggère d'ajouter
        option explicit
        en début de module.
        suggestion:
        Private [/contents/446-fichier-sub Sub] tri()
        Dim debut_plage As Range
        Dim fin_plage As Range
        Dim DerniereLigne As Long, nligne As Long
        DerniereLigne = Range("A" & Rows.Count).End(xlUp).Row
        nligne = 3
        Do While nligne < DerniereLigne
            If IsNumeric(Left(Cells(nligne, 2), 1)) Then
                Set debut_plage = Cells(nligne, 1)
                Do While IsNumeric(Left(Cells(nligne + 1, 2), 1))
                    nligne = nligne + 1
                Loop
                Set fin_plage = Cells(nligne, 3)
                Range(debut_plage, fin_plage).Sort Key1:=Range("B1"), Order1:=xlAscending
            End If
            nligne = nligne + 1
        Loop
        End Sub

        une autre façon de l'écrire, que certains trouveront plus clair:
        Private Sub tri2()
        Dim debut_plage As Range
        Dim fin_plage As Range
        Dim DerniereLigne As Long, ici As Range
        DerniereLigne = Range("A" & Rows.Count).End(xlUp).Row
        Set ici = Cells(3, 2)
        Do While ici.Row < DerniereLigne
            If IsNumeric(Left(ici, 1)) Then
                Set debut_plage = ici.Offset(0, -1)
                Do While IsNumeric(Left(ici.Offset(1, 0), 1))
                    Set ici = ici.Offset(1, 0)
                Loop
                Set fin_plage = ici.Offset(0, 1)
                Range(debut_plage, fin_plage).Sort Key1:=Range("B1"), Order1:=xlAscending
            End If
            Set ici = ici.Offset(1, 0)
        Loop
        End Sub
        0
    2. Harry_Seldon Messages postés 4 Statut Membre
       
      Bonsoir yg_be,
      merci beaucoup pour votre retour et pour ce code. J'ai encore du mal à traduire les problèmes en solutions VBA et l'étude de votre code m'aidera énormément. Encore un grand merci :D
      0