Trier des colonnes avec du VBA

Bonjour,

J'utilise un fichier Excel qui me permet de suivre l'entretien de machines. A chaque nouvel entretien, je viens créer un historique avec la date, le nombre d'heures et la maintenance réalisée. Le fichier fonctionne très bien, mais je n'ai pas droit à l'erreur. Les données s'incrémentent sans possibilités de les modifier (sauf manuellement avec des supp, et des copier coller). Vous trouverez en pièce jointe un extrait de ce fichier.

J'ai deux problèmes à résoudre.

1 - En admettant que j'ai oublié une maintenance réalisée l'année passée et qu'entre temps j'ai rentré une nouvelle maintenance je me retrouve avec une anomalie dans la chronologie. En effet si je rentre finalement la maintenance oubliée elle se retrouve en dernière position, donc problème de chronologie.

2 - Je voudrais également pouvoir supprimer une maintenance si elle a été rentrée par erreur

Merci d'avance pour votre aide

Bonjour,

Est-ce si important d'avoir toutes les machines sur une même feuille ?

Une feuille par machine serait plus simple à gérer, avec une maintenance par ligne

Exemple Feuille "Machine1"

image

Pour remettre dans l'ordre il suffit de reclasser la liste par date, et pour une suppression, on supprime tout simplement la ligne.

Bien sûr Il faudra modifier la programmation et placer un bouton "Nouvelle maintenance" (par copier coller) sur chaque feuille qui appellera la même macro.

Eric

Bonjour,

Ce n'est pas si simple malheureusement. J'ai environ 250 machines.

Je comprends

L'idée de placer les maintenances en vertical reste valable. Il suffit de rajouter une colonne avant "Date" et d'y placer la référence de la machine.

image

A toi de voir

Bonjour à tous ,

Un essai via VBA :

Sub ToutOrdonner()
Dim derlig&, dercol&, t, i&, j&, k&, ech As Boolean, n&, m&, aux
   With Sheets("Feuil1")
      If .FilterMode Then .ShowAllData
      derlig = .Cells(Rows.Count, "a").End(xlUp).Row
      dercol = .Cells(3, "b").End(xlToRight).Column
      t = .Range(.Cells(4, "b"), .Cells(derlig, dercol))
      For i = 1 To UBound(t)
         n = -3
         For j = 1 To UBound(t, 2) Step 4
            If t(i, j) <> "" Then
               n = n + 4
               For k = 0 To 3: t(i, n + k) = t(i, j + k): Next
            End If
         Next j
         For j = n + 4 To UBound(t, 2): t(i, j) = "": Next
         Do
            ech = False
            For j = 1 To n - 4 Step 4
               ech = False
               If t(i, j) > t(i, j + 4) Then
                  ech = True
                  For m = 0 To 3
                     aux = t(i, j + m): t(i, j + m) = t(i, j + 4 + m): t(i, j + 4 + m) = aux
                  Next m
               End If
            Next j
         Loop Until Not ech
      Next i
      .Cells(4, "b").Resize(UBound(t), UBound(t, 2)) = t
   End With
End Sub

Bonjour et merci,

Je viens de tester le code. C'est pas mal, mais il faut lancer plusieurs fois la macro avant que tout soit dans l'ordre. Exemple, si j'ai besoin de rentrer une maintenance avec 3 dates antérieures, il faut lancer la macro 3 fois

bonjour le fil,

avec une fonction personnalisée et un tableau structuré

Bonjour

Alors que les tableaux structurés faits pour gérer des tables de données existent dans Excel depuis plus de 20 ans, pourquoi ne pas les utiliser ce qui simplifierait nettement le problème...

En plus ton nombre d'heure est en texte

Une proposition avec contrôle des dates et nombres + tri

Re,

mais il faut lancer plusieurs fois la macro avant que tout soit dans l'ordre

Et vous avez tout à fait raison . Dans le code , la ligne Ech = False était mal placée. Il fallait la remonter d'une ligne juste après le DO.

Dans le fichier joint :

  • La macro a été corrigée. Le code est dans Module1 (code aussi corrigé dans mon premier message)
  • J'ai ajouté une macro évènementielle pour la suppression d'une maintenance. Il suffit de double-cliquer sur une des 4 cellules de la maintenance pour effacer l'ensemble des 4 cellules. Le code est dans le module associé à la feuille "Feuil1". On termine la macro par l'exécution automatique de la macro ToutOrdonner pour combler "le trou" laissé par la suppression.

Astuce : double-cliquer sur une maintenance pour la supprimer puis refuser la suppression. On réordonnera malgré tout le tableau sans aucune suppression.

Merci pour votre retour. Je viens de prendre connaissance du fichier çà a l'air vraiment top.

Je vais faire des tests à "grande échelle" et je reviens vers vous pour valider les résultats.

Dans tous les cas merci.

Bonjour,

On y est presque !

2 petits problèmes.

Quand je rentre une nouvelle maintenance et ensuite j'exécute la macro voilà ce qui se passe :

- Le jour et le mois de la date s'inverse et le classement ne se fait pas

J'exécute ensuite une deuxième fois la macro :

- Le classement s'effectue bien cette fois (mais ma date est fausse)

- Le nombre d'heures se retrouve avec 2 décimales dont je ne veux surtout pas.

Des solutions ?

Merci d'avance

Erratum...

re,

dans mon cas, il n'y a pas une macro à lancer. Je ne connais pas si bien les nouvelles formules 365, mais on peut faire la même chose en formules ... .

Bonjour du lundi Humanum ,

Ce n'est pas mon code qui est en cause mais votre code de saisie d'une nouvelle maintenance.

Gardez à l'esprit que dans votre Userform de saisie vous utilisez des Textbox pour la date et le nombre d'heures. Quand vous transférer ces données sur la feuille de calcul, vous effectuez l'équivalent d'une saisie de textes et non pas de nombres (une date est représentée par un nombre au sein d'Excel).

Pour vous en convaincre (pendant la phase de test), élargissez vos colonnes "Date" et "Heures" et appliquez pour ces deux colonnes l'alignement "Standard". Après une insertion, vous verrez le contenu de ces deux cellules alignés à gauche (texte) et non pas à droite comme des nombres.

J'ai refait un code pour la validation des saisies du userform (bouton "Valider") avec vérifications des saisies (vérification basique pour ce qui est de la date). Les dates seront de vraies dates au sens d'Excel (idem pour les heures) .Cela devrait répondre à vos besoins, du moins je l'espère.

Private Sub Valider1_Click()
Dim ligne&, j&, colonne&, pasOK$, s$

   If ComboBox1.ListIndex < 0 Then MsgBox "Veuillez sélectionner une machine, svp.", vbCritical: Exit Sub
   ligne = 4 + ComboBox1.ListIndex

   For j = 2 To 9999 Step 4
      If Trim(Cells(ligne, j)) = "" Then colonne = j: Exit For
   Next j
   If colonne = 0 Then MsgBox "Plus aucune cellule vide disponible pour insérer une maintenance.": Exit Sub

   On Error Resume Next
   Cells(ligne, colonne).NumberFormat = "dd/mm/yyyy": Cells(ligne, colonne) = CDate(TextBox1)
   If Not IsDate(Cells(ligne, colonne)) Then pasOK = "date"
   If Val(Format(Cells(ligne, colonne), "00")) <> Val(TextBox1) Then pasOK = "date"
   On Error GoTo 0

   Cells(ligne, colonne + 1).NumberFormat = "#,##0": Cells(ligne, colonne + 1) = Int(Val(TextBox2))
   If Not Application.IsNumber(Cells(ligne, colonne + 1)) Then pasOK = pasOK & "heure"
   If Cells(ligne, colonne + 1) <= 0 Then pasOK = pasOK & "heure"

   If ComboBox2.ListIndex < 0 Then pasOK = pasOK & "huile"
   Cells(ligne, colonne + 2) = ComboBox2.Text

   If ComboBox3.ListIndex < 0 Then pasOK = pasOK & "air"
   Cells(ligne, colonne + 3) = ComboBox3.Text

   If pasOK = "" Then
      ToutOrdonner
      Unload Me
   Else
      Cells(ligne, colonne).Resize(, 4).ClearContents
      If InStr(pasOK, "date") > 0 Then s = s & vbLf & " La date"
      If InStr(pasOK, "heure") > 0 Then s = s & vbLf & " Le nombre d'heures"
      If InStr(pasOK, "huile") > 0 Then s = s & vbLf & " Le filtre à huile"
      If InStr(pasOK, "air") > 0 Then s = s & vbLf & " Le filtre à air"
      MsgBox "Les saisies suivante sont incorrectes !" & s, vbCritical
   End If
End Sub

RE

Gardez à l'esprit que dans votre Userform de saisie vous utilisez des Textbox pour la date et le nombre d'heures. Quand vous transférer ces données sur la feuille de calcul, vous effectuez l'équivalent d'une saisie de textes et non pas de nombres (une date est représentée par un nombre au sein d'Excel).
C'est ce que j'ai signalé dans mon post manifestement ignoré d'hier...

Bonjour 78Chris ,

Mille (plus une) excuses 78 Chris . Effectivement j'avais manqué ton message. Allez savoir pourquoi ? L'âge grandissant peut-être.

Merci Mafraise pour le travail effectué et merci pour votre patience. Je débute et ce n'est pas simple (mais passionnant)

Pour la date, apparemment çà bug

image

Re,

Pour la date, apparemment çà bug

Une ligne en trop a été enlevé. Essayez cette version v3b.

RE

Bonjour 78Chris ,

Mille (plus une) excuses 78 Chris . Effectivement j'avais manqué ton message. Allez savoir pourquoi ? L'âge grandissant peut-être.

C'est surtout le demandeur qui fait abstraction des 2 autres aidants...

çà fonctionne, bravo !!

Vous allez me haïr mais j'ai une dernière question.

Si je dois ajouter 1 ou plusieurs colonnes avant et après le tableau, avec d'autre données que je n'ai pas besoin de modifier et de trier, je dois modifier quels paramètres dans le code ?

Donc faire du tri seulement entre la colonne B et AD

image image
Rechercher des sujets similaires à "trier colonnes vba"