VBA - tri sur plusieurs plages de cellules spécifiques

Résolu/Fermé
Harry_Seldon Messages postés 4 Date d'inscription samedi 2 novembre 2019 Statut Membre Dernière intervention 5 novembre 2019 - 2 nov. 2019 à 23:53
Harry_Seldon Messages postés 4 Date d'inscription samedi 2 novembre 2019 Statut Membre Dernière intervention 5 novembre 2019 - 5 nov. 2019 à 22:57
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

yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
3 nov. 2019 à 10:06
bonjour, peux-tu partager ton programme?
1
Harry_Seldon Messages postés 4 Date d'inscription samedi 2 novembre 2019 Statut Membre Dernière intervention 5 novembre 2019
3 nov. 2019 à 12:05
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
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
Modifié le 3 nov. 2019 à 13:35
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
Harry_Seldon Messages postés 4 Date d'inscription samedi 2 novembre 2019 Statut Membre Dernière intervention 5 novembre 2019
3 nov. 2019 à 14:30
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
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476 > Harry_Seldon Messages postés 4 Date d'inscription samedi 2 novembre 2019 Statut Membre Dernière intervention 5 novembre 2019
Modifié le 3 nov. 2019 à 16:43
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
Harry_Seldon Messages postés 4 Date d'inscription samedi 2 novembre 2019 Statut Membre Dernière intervention 5 novembre 2019
5 nov. 2019 à 22:57
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