Comparer date format mois-année
Bonjour,
je chercher à créer un tableau de bord me permettant d'afficher le nom des personnes devant réaliser une visite medical ce mois.
Voilà mon début de code (je n'ai pas encore créé la boucle) :
Sub Visite()
'
Sheets("Visite medical").Select
If Range("E2") <= Range("H1") Then
Range("A2:D2").Select
Selection.Copy
Sheets("Tableau de bord").Select
Range("A3").Select
ActiveSheet.Paste
End If
End Sub
En E2 et H sont sotckés les dates que je veux comparer mais cela ne fonctionne pas.
Merci d'avance pour votre aide.
Bonjour
Ce serait plus clair si tu joignais un fichier.
Bye !
Bonjour,
D'abord, il est bon de penser à écrire un code propre et lisible.
Pour cela, au niveau de l'écriture, on indente le code selon des règles prédéfinies. Il sera ainsi plus rapidement lisible et compréhensible, et dans des proportions parfois considérables...
On évite aussi de singer l'enregistreur, et on bannit de son code tout Select, Selection, Activate, etc. (hors action d'affichage à l'intention de l'utilisateur) bons juste à ralentir l'exécution ! On élimine aussi les autres fragments de code inutiles (généralement inspirés de l'enregistreur...)
Ensuite, on pense VBA plutôt qu'Excel, car c'est VBA qui va faire le boulot et qui peut opérer autrement que l'utilisateur l'aurait fait manuellement.
On ne met pas simplement : Range(... parce que la plage se trouve dans la cellule qu'on à sous les yeux), on pense que VBA ne doit pas avoir à chercher l'élément actif auquel on fait référence implicitement mais on le lui dit : Worksheets(xxxx).Range(... Ainsi VBA n'aura pas à chercher et l'élément actif pourra être autre sans que cela ne provoque d'erreur par la suite...
Cela s'appelle doter ses expressions de qualificateurs d'objet.
Mieux, comme on va généralement faire plusieurs manipulations sur la même feuille, on regroupe en écrivant : With Worksheets(xxx). Tant qu'on n'aura pas clôt cette instruction avec End With, toute instruction précédée d'un point réfèrera à cet objet. Cela raccourcit le code à écrire, mais surtout permet à VBA d'être plus rapide.
On sait que l'on va faire une boucle sur toutes les lignes utiles d'une feuille, on le prévoit donc, avant d'écrire le code, mais lorsqu'on l'écrit, on inclut la boucle
Disposant d'autres moyens que copier et coller bêtement une ligne après l'autre, comme on aurait été contraint de le faire en manuel, on va préférer recueillir toutes les données correspondant au critère choisi, les stocker, pour ensuite les restituer en une seule fois à la destination souhaitée. Donc tableau pour recueillir les données, on ne connait pas leur nombre, donc redimensionnement du tableau au fur et à mesure, la partie variable correspondant à des lignes, pour la faire varier on aura un tableau dont la 1re dimension correspond à des colonnes et la seconde aux lignes, soit transposé par rapport à la plage source et à la plage cible.
A la fin, le tableau final étant constitué, on n'aura plus qu'à dire : plageCible(dimensionnée en fonction du tableau) = tableau transposé.
On peut maintenant lister les variables à utiliser (et à déclarer en tête de procédure) : un tableau dynamique (laissé de type Variant, plusieurs types de données pouvant être affectée), une variable pour recueillir le critère de sélection (laissé Variant dans le doute), 4 variables de type Integer : une pour retenir la dernière ligne à atteindre en parcourant la feuille, 2 compteur de boucles (sur les lignes de la feuille, et sur les colonnes des données à affecter au tableau lors d'une affectation), une pour incrémenter la variation du tableau.
Plus qu'à écrire :
Sub Visite()
Dim TVis(), d, n%, i%, k%, x%
With Worksheets("Visite medical")
n = .Cells(.Rows.Count, 1).End(xlUp).Row
d = .Range("H1"): x = -1
For i = 2 To n
If .Cells(i, 5) <= d Then
x = x + 1: ReDim Preserve TVis(3, x)
For k = 1 To 4
TVis(k - 1, x) = .Cells(i, k)
Next k
End If
Next i
End With
With Worksheets("Tableau de bord")
.Range("A3").Resize(x + 1, 4).Value = WorksheetFunction.Transpose(TVis)
.Activate
End With
End Subet à tester (si les données retenues correspondent bien
Cordialement.
merci beaucoup pour les conseils pour rédiger la macro et pour la formule. Je vois si j'arrive à l'adapter à mon fichier.
Désolé, j'ai un beug à l'éxécution de la macro et pour être honnête je ne trouve pas son origine. Pouvez vous m'aider svp
Evidemment dans le cas où personne ne répond à la condition, le tableau n'est même pas dimensionné...
J'aurais dû prévoir ce cas cependant !
J'ai donc fait un ajout à la macro pour le cas de recherche infructueuse.
J'ai aussi modifié la formule en H1 :
=FIN.MOIS(AUJOURDHUI();0)de façon qu'elle renvoie le dernier jour du mois.
Ainsi la recherche portera sur tous ceux dont la visite doit être effectuée dans le mois, ce qui paraît plus en adéquation avec ta formulation de départ.
(J'ai aussi modifié celle en E, mais là c'est juste pour ne pas se priver d'utiliser les fonctions que Microsoft a mis en place pour ce type de calcul.)
Note toutefois que le renvoi de "" en E lorsque D est vide met les intéressés hors condition et qu'ils ne seront jamais sélectionné pour une visite tant qu'un date n'a pas été saisie en D...
Si tu veux que l'on retienne ceux qui n'ont pas de date en D il faut faire renvoyer 0 au lieu de "" si D est vide (et dans le format de cellule de la col. E, ajouter un point-virgule (;) qui aura pour effet de ne pas afficher les 0.
Cordialement.
C'est super ! Merci à la fois pour le fichier et pour les explications qui vont me permettre de progresser.
Bonne journée