VBA Trier une listview par affichage

Bonjour,

je n'ai pas réussi à trouver une réponse qui me correspond sur le net. J'ai une listview avec un affichage dynamique et je souhaiterais trier automatiquement les lignes en fonction de la valeur dans une colonne :

image

Typiquement, je cherche que l'affichage soit automatique et que la colonne "Etat" soit trier du plus grand au plus petit (pour afficher les lignes rouge en premier).

Voici le code qui permet d'afficher ma listview.

Private Sub Actualisation() 'Affichage des lignes dans le listview demande

Dim DR As Integer, i As Integer, k As Integer
Dim j As Byte
Dim color As Variant, Critere As Variant
Dim ws_demandes As Worksheet
Set ws_demandes = Worksheets("DEMANDES")

AffichageDemande.ListItems.Clear 'efface le listview
AffichageStock.ListItems.Clear
DR = ws_demandes.Cells(Rows.Count, "A").End(xlUp).Row

k = 1
    For i = 2 To DR
        Critere = ws_demandes.Cells(i, 2) 'Configure la couleur des lettres
        If Critere > 1 Then
            Select Case Critere
                Case Is = 1 '1 = Commande livré mais il manque des infos noir
                    color = 0
                Case Is = 2 '2 = Commande en cours par le magasin blue
                    color = &HFF0000
                Case Is = 3 '3 = Nouvelle demande red
                    color = &HFF&
            End Select

            With AffichageDemande 'Affiche les éléments
                .ListItems.Add , , ws_demandes.Cells(i, 1)

                For j = 1 To 15
                    .ListItems(k).ListSubItems.Add , , ws_demandes.Cells(i, j + 1)
                    .ListItems(k).ListSubItems(j).ForeColor = color
                Next j
            End With
          k = k + 1
        End If
    Next i
End Sub

Jusqu'à présent, j'utilise ce code :

Private Sub AffichageDemande_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader) 'filtrer les colonnes en cliquant dessus

AffichageDemande.Sorted = False
AffichageDemande.SortKey = ColumnHeader.Index - 1
    If AffichageDemande.SortOrder = lvwAscending Then
        AffichageDemande.SortOrder = lvwDescending
    Else
        AffichageDemande.SortOrder = lvwAscending
    End If
AffichageDemande.Sorted = True

End Sub

Mais il créer des erreurs et je voudrais que cela soit automatique (sans clique le le bouton de l'entête).

Merci pour votre aide ! ;)

Bonjour Fafe93,

Par défaut, c'est la première colonne (N°) basée sur ta colonne A qui actualise par N° de demande (donc ligne croissant) les données.

Donc après la colorisation apportée selon l'Etat (1 à 3), il faut en fin de boucle préciser le tri souhaité.

 k = k + 1
        End If
    Next i
'Classement du plus grand au plus petit selon colonne Etat
AffichageDemande.Sorted = False
AffichageDemande.SortKey = 2
AffichageDemande.SortOrder = lvwDescending
AffichageDemande.Sorted = True
End Sub

Merci pour votre réponse rapide.

Alors le code fonctionne mais je me retrouve quand même avec la même erreur.

Le tri ce fait bien. Mais lorsque j'actualise le listview (avant dernière ligne), Je me retrouve avec des lignes dispersées et des couleurs mal mise :

Private Sub acommander_Click() 'Bouton pour pneu à commander

'Définition des variables
    Dim Ligne As Integer, Ind As Range
    Dim ws_demandes As Worksheet
    Set ws_demandes = Worksheets("DEMANDES")

'Cherche le numéro de commande (index) dans la colonne A de Demandes
    Set Ind = ws_demandes.Range("A:A").Find(Val(txtIndex))
'Recupère le numéro de la ligne correspondante
    Ligne = Ind.Row

    If MsgBox("Avez-vous pris les informations pour passer la commande ?", 36, "Commande de pneu") = vbYes Then 'Si bouton "oui" sélectionner alors ...
        If NumCmd = "" Then 'pour aucune valeur renseignée
            MsgBox "Aucun numéro de commande n'a été renseigné."
        Else
            ws_demandes.Unprotect (123) 'unprotect la feuille avec le code pour écriture
                ws_demandes.Range("S" & Ligne) = UCase(NumCmd) 'inscrit le numéro de commande en maj
                ws_demandes.Range("B" & Ligne) = 2 '2 = commande en cours
            ws_demandes.Protect (123) 'protège la feuille
            NumCmd = Clear
            txtIndex = Clear
        End If
    End If
Call Actualisation 'appel code Actualisation
End Sub

Avant de cliquez de "acommander" :

image

Après avoir cliquez sur le bouton :

image

Une partie des infos s'efface...

Private Sub Actualisation() 'Affichage des lignes dans le listview demande

Dim DR As Integer, i As Integer, k As Integer
Dim j As Byte
Dim color As Variant, Critere As Variant
Dim ws_demandes As Worksheet
Set ws_demandes = Worksheets("DEMANDES")

AffichageDemande.ListItems.Clear 'efface le listview
AffichageStock.ListItems.Clear
DR = ws_demandes.Cells(Rows.Count, "A").End(xlUp).Row

k = 1
    For i = 2 To DR
        Critere = ws_demandes.Cells(i, 2) 'Configure la couleur des lettres
        If Critere > 1 Then
            Select Case Critere
                Case Is = 2 '2 = Commande en cours par le magasin blue
                    color = &HFF0000
                Case Is = 3 '3 = Nouvelle demande red
                    color = &HFF&
            End Select
            With AffichageDemande 'Affiche les éléments
                .ListItems.Add , , ws_demandes.Cells(i, 1)
                For j = 1 To 15
                    .ListItems(k).ListSubItems.Add , , ws_demandes.Cells(i, j + 1)
                    .ListItems(k).ListSubItems(j).ForeColor = color
                Next j
            End With
          k = k + 1
        End If
    Next i
'Classement du plus grand au plus petit selon colonne Etat
AffichageDemande.Sorted = False
AffichageDemande.SortKey = 1 'numéro de colonne (0 = première, 1 = 2eme ...)
AffichageDemande.SortOrder = lvwDescending 'du plus petit au plus grand
AffichageDemande.Sorted = True
End Sub

A nouveau,

Revoir ta macro acommander

Déjà, ci dessous, Clear cela représente quoi?

 NumCmd = Clear
 txtIndex = Clear

Ensuite, l'état 3 passe à 2 pour signifier le changement d'état de la ligne. Ok.

Par contre, vu que sur la feuille, il n'y a pas de colonne avant celle A

 ws_demandes.Range("A:A").Find(Val(txtIndex))

Or, la colonne 0 est dans les ListWiew réservée à l'ID, c'est à dire la clé permettant de rechercher tout donnée. Cette clé est unique et elle n'est jamais modifiable.

Souvent jamais affichée car seules les données sont montrées. Et cette clé devrait être ici sur la colonne A. Donc, la colonne 1 devrait être le N° et 2 pour l'Etat.

Je comprends de ce fait que tu as modifié le tri.

AffichageDemande.Sorted = False
AffichageDemande.SortKey = 1 'numéro de colonne (0 = première, 1 = 2eme ...)

Sans le fichier, pour vérifier le déroulement des macros afin de test. Et surtout, sans l'existence d'une colonne clé qui permettrait de ressortir les données dans l'ordre croissant de cette clé, j'hésiterais.

Voici un lien wet ransfer, le fichier est trop gros pour le site.

https://we.

tl/t-V6VR9sodeH

Le code en question est dans le projet VBA et c'est "ListeDemande".

Dans la colonne A de la feuille DEMANDES, je créer un index unique.

La colonne B est le fameux Etat d'avancement.

Merci pour ton aide :)

Bonjour Fafe93,

En retour modification de tes macros postés.

Bouton commander

Private Sub acommander_Click() 'Bouton pour pneu à commander

'Définition des variables
    Dim Ligne As Integer, Ind As Range
    Dim ws_demandes As Worksheet
    Set ws_demandes = Worksheets("DEMANDES")

'Cherche le numéro de commande (index) dans la colonne A de Demandes
    Set Ind = ws_demandes.Range("A:A").Find(Val(txtIndex))
'Recupère le numéro de la ligne correspondante
    Ligne = Ind.Row
Retour:
    If MsgBox("Avez-vous pris les informations pour passer la commande ?", 36, "Commande de pneu") = vbYes Then 'Si bouton "oui" sélectionner alors ...
        If NumCmd = "" Then 'pour aucune valeur renseignée
            MsgBox "Aucun numéro de commande n'a été renseigné. Sinon annuler la procédure": GoTo Retour
        Else
            ws_demandes.Unprotect (123) 'unprotect la feuille avec le code pour écriture
                ws_demandes.Range("S" & Ligne) = UCase(NumCmd) 'inscrit le numéro de commande en maj
                ws_demandes.Range("B" & Ligne) = 2 '2 = commande en cours
            ws_demandes.Protect (123) 'protège la feuille
            NumCmd = Clear
            txtIndex = Clear
        End If
    'Sortie si réponse NON sur premier MsgBox (aucune actualisation)
    Else: Exit Sub
    End If
Call Actualisation 'appel code Actualisation
End Sub

Ainsi que l'actualisation

Private Sub Actualisation() 'Affichage des lignes dans le listview demande

Dim DR As Integer, i As Integer, k As Integer
Dim j As Byte
Dim color As Variant, Critere As Variant
Dim ws_demandes As Worksheet
Set ws_demandes = Worksheets("DEMANDES")
'Suppression du tri en cours
AffichageDemande.Sorted = False
AffichageDemande.ListItems.Clear 'efface le listview
AffichageStock.ListItems.Clear
DR = ws_demandes.Cells(Rows.Count, "A").End(xlUp).Row

k = 1
    For i = 2 To DR
        Critere = ws_demandes.Cells(i, 2) 'Configure la couleur des lettres
        If Critere > 1 Then
            Select Case Critere
                Case Is = 2 '2 = Commande en cours par le magasin blue
                    color = &HFF0000
                Case Is = 3 '3 = Nouvelle demande red
                    color = &HFF&
            End Select
            With AffichageDemande 'Affiche les éléments
                .ListItems.Add , , ws_demandes.Cells(i, 1)
                For j = 1 To 15
                    .ListItems(k).ListSubItems.Add , , ws_demandes.Cells(i, j + 1)
                    .ListItems(k).ListSubItems(j).ForeColor = color
                Next j
            End With
          k = k + 1
        End If
    Next i
'Classement du plus grand au plus petit selon colonne Etat
'AffichageDemande.Sorted = False  placement en début de macro
AffichageDemande.SortKey = 1 'numéro de colonne (0 = première, 1 = 2eme ...)
AffichageDemande.SortOrder = lvwDescending 'du plus grand au plus petit
AffichageDemande.Sorted = True
End Sub

Attention cependant qu'il n'existe pas deux numéros d'index similaires dans la feuille.

Génial merici beaucoup !

J'ai juste retiré le GoTo Retour et ça fonctionne bien.

Rechercher des sujets similaires à "vba trier listview affichage"