Mettre X si une condition est respectée

Résolu
alexpepe - 5 avril 2016 à 10:52
alexpepe Messages postés 20 Date d'inscription mercredi 30 mars 2016 Statut Membre Dernière intervention 14 avril 2016 - 7 avril 2016 à 12:04
Bonjour à tous,

j'ai besoin d'aide car je suis novice en VBA.
j'ai une macro qui analyse des dates, pour les dates de la colonne B qui se situent dans les 7 jours après aujourd'hui, alors un mail est envoyé à l'adresse correspondante en colonne E.

Le but est d'envoyer un mail de rappel à la bonne personne.
Le problème c'est que si je lance la macro tous les jours cette macro va se envoyer des mails au même personne sans cesse.
Je voudrais donc que lors de la première analyse, si les dates sont respectées alors un mail est envoyé dans ce car mettre en X en colonne G sur la ligne correspondante. Ensuite lors de la prochaine analyse, s'il y a un X alors ne pas envoyer de mail.

Voici mon code actuel d'analyse des dates

Sub TesteDate()
'envoie un mail si la date est dans 7 jours ou moins
Dim sSujet, sBody, sAdresseMail As String 'chaines pour le sujet, corps, adresse d'envoi
Dim duree As Date 'nbre de jours entre aujourd'hui et la date à tester
Dim Lig_Deb, Lig_Fin As Integer 'ligne de début, de fin
Dim sDates_Col, sMails_Col As String 'colonnes qui contiennent les dates à tester et les adresses mail
Dim I As Integer

'initialisation des constantes de la macro :
Lig_Deb = 2 'dans ma feuille Excel, les dates à tester commencent en ligne 2
sDates_Col = "B" ' et elles sont en colonne B ( 2 ième colonne)et les adresses mail sont en colonne E à côté

'initialisation des données du mail envoyé :
sSujet = "Visite médical"
sBody = "Votre agent doit passer sa visite médicale dans sept jours ou moins."

'Ligne de fin =1ère cellule vide dans la colonne des dates
Lig_Fin = Val(Range(sDates_Col & CStr(Lig_Deb)).End(xlDown).Row)

' boucle de test dans la plage des dates (=> )

For I = Lig_Deb To Lig_Fin
Range(sDates_Col & CStr(I)).Select 'activer la cellule testée
duree = ActiveCell.Value - Now ' la date est dans la cellule active
If duree <= 7 And duree > 0 Then 'la date est dans 7 jours ou moins par rapport à aujourd'hui
sAdresseMail = ActiveCell.Offset(0, 3).Value 'l'adresse mail est dans trois colonne après offset (0,3)

' envoyer le mail :
CDO_SendMail sSujet, sBody, sAdresseMail
Else

End If

Next I

End Sub



Merci d'avance pour votre aide.

2 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 5/04/2016 à 11:37
Bonjour, Sous VBA :
1) dim X, Y as type_machin
ne type en type_machin que Y.
Il faut typer explicitement chaque variable
===>> à corriger :
Dim Lig_Deb, Lig_Fin As Integer 
Dim sDates_Col, sMails_Col As String

2) on ne sélectionne pas une cellule pour y travailler (lourd). On manipule l'objet Range qu'elle est :
exemple :
Range("A3").select
toto = activecell.value

s'écrit
toto = range("A3").value

3) l'utilisation de l'argument xldown ne retourne pas la dernière ligne remplie, mais la première non remplie. Risque à ne jamais courir.
La dernière ligne remplie de la colonne B est assurément :
Range("B" & rows.count).end(xlup).row 

4) typer lig_fin en integer est maladroit. Le nombre de lignes remplies peut dépasser la limite d'un integer. Typer en long

Je m'arrête personnellement là car continuer serait tout te faire (et c'est vraiment simple) de A à Z.

EDIT : tu voudras bien comprendre les raisons de ma réaction.
- tu ne connais apparemment pas grand-chose de VBA/Excel, mais :
--- tu ne montres ni un véritable intérêt d'apprentissage des bases
--- tu ne sembles même pas tenir compte des réponses que tu as reçues dans ta toute première discussion.
J'en veux pour preuve cette ligne de code :
Lig_Fin = Val(Range(sDates_Col & CStr(Lig_Deb)).End(xlDown).Row)

à comparer avec ce que je t'ai dit du type de Row

Il est sans doute utile que tu te familiarise avec les rudiments avant de continuer à tenter d'écrire ton projet (d'autant que j'observe que tu cherches finalement à en faire écrire toutes les parties, une par une, à en juger par toutes les discussions ouvertes et concernant des points très simples).
Bonne chance.
________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
0
alexpepe Messages postés 20 Date d'inscription mercredi 30 mars 2016 Statut Membre Dernière intervention 14 avril 2016
5 avril 2016 à 12:34
Bonjour,

merci pour ces précisions.

1) je ne savais pas il me semblais que cela fonctionnait, c'est corrigé==> merci

2)en suivant ton exemple, je suis donc passé de
Range(sDates_Col & CStr(I)).Select 'activer la cellule testée
duree = Now - ActiveCell.Value ' la date est dans la cellule active

à ça
duree = Range(sDates_Col & CStr(I)).Value - Now  ' la date est dans la cellule active'activer la cellule testée


Par contre la macro ne fonctionne plus pour le coup. j'ai du faire une erreur dans la compilation des deux arguments.

3) pourquoi ne faut-il jamais courir ce risque, quelle est la différence?
j'ai quand même modifié selon tes conseils:
Lig_Fin = Range("B" & Rows.Count).End(xlUp).Row


4) j'ai donc laisser Lig_Deb en Integer car = 2 et j'ai changé Lig_Fin en Long car en effet on ne sais pas combien de ligne il peut y avoir.

Edit:
- Je l'ai dit clairement au début je suis novice en VBA, je débute, j'ai fais mes premières lignes de codes en décembre en essayant d'apprendre sur internet pour créer des fichiers avec des boutons d'envoi de mail automatique à la bonne personne selon des listes déroulantes, mais aussi enregistrer le document sur le bon emplacement sur le serveur en fonction de différents paramètres et des listes déroulantes. Donc oui je débute je te l'accorde c'est pour ça que je fais appel à l'aide sur les forum.
- c'est faux j'essaie de comprendre les infos que l'on me donne mais étant débutant cela est très compliqué de comprendre l'imbrication des éléments de codes les uns avec les autres quand on ne les connait déjà pas forcément bien séparé.
- je n'avais en effet pas compris ton msg sur mon premier post comme quoi val et row etait en fait la même chose donc du numérique. ayant repris cette ligne sur un forum j'ai fais confiance.

et oui j'ai créer plusieurs sujets car comme tu me l'a dit, c'est un sujet traité par post et j'ai plusieurs sujets.
cela te semble simple pour toi j'en suis conscient. mais quand on est pas expert en vba comme toi, les choses simples à ton niveau ne le sont pas pour tous le monde.
oui si je pouvais avoir la solution toute cuite ce serait le top car je pourrais rapidement mettre en application et cela arrangerai bcp de monde. mais le but n'est pas de faire un copié collé et quitter le vba, j'essaie de comprendre ce que je copie même si ce n'est pas toujours simple.

merci quand même pour ton aide.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211 > alexpepe Messages postés 20 Date d'inscription mercredi 30 mars 2016 Statut Membre Dernière intervention 14 avril 2016
5 avril 2016 à 12:42
Ah cà !!!!
je m'arrête à ton point 2, car là, vraiment ...
Comment peut-on penser que toto - titi est titi - toto ???????
0
alexpepe Messages postés 20 Date d'inscription mercredi 30 mars 2016 Statut Membre Dernière intervention 14 avril 2016 > ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018
5 avril 2016 à 14:24
nan c'est normal c'est que mon calcul de départ était dans le mauvais sens, d'ou la modif car je veux que la durée soit égale à date en colonne B - date d'aujourd'hui.
donc en fait j'ai
Range(sDates_Col & CStr(I)).Select 'activer la cellule testée
duree = ActiveCell.Value - Now ' la date est dans la cellule active

donc merci mais je sais bien que toto - titi n'est pas égal à titi - toto.
0
alexpepe Messages postés 20 Date d'inscription mercredi 30 mars 2016 Statut Membre Dernière intervention 14 avril 2016
5 avril 2016 à 14:56
Ce problème est résolu.
J'ai modifié mon code pour que si la condition de date est ok et que la colonne G soit vide alors on envoi le mail et dans la colonne G on indique l'heure de la macro.

For I = Lig_Deb To Lig_Fin
Range(sDates_Col & CStr(I)).Select 'activer la cellule testée
duree = ActiveCell.Value - Now ' la date est dans la cellule active
If duree <= 7 And duree > 0 And Range(sRappel_Col & CStr(I)).Value = "" Then 'la date est dans 7 jours ou moins par rapport à aujourd'hui et la case rappel est vide
sAdresseMail = ActiveCell.Offset(0, 3).Value 'l'adresse mail est dans trois colonne après offset (0,3)

' envoyer le mail :
CDO_SendMail sSujet, sBody, sAdresseMail
'mettre la date d'envoi dans la case rappel
Range(sRappel_Col & CStr(I)) = Now
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211 > alexpepe Messages postés 20 Date d'inscription mercredi 30 mars 2016 Statut Membre Dernière intervention 14 avril 2016
5 avril 2016 à 16:26
Il est vraiment désolant que tu continue à travailler à coup de "select" en dépit de ce que l'on t'en dit !
Tu décourages toute bonne volonté.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
5 avril 2016 à 21:25
Discussion par ailleurs déplacée du forum général "Visual Basic" vers le sous-forum où elle aurait dû être ouverte (VBA).
0
Rejoignez-nous