Alors, un petit exemple, ou j'ai pris quelques libertés plutôt que revenir poser pleins de questions.
J'ai commenté ces "libertés" par "il me semblait logique...." au dans le style.
Tout d'abord la classe qui va contenir les paramètre, gérer les intervalles et signaler le nouveau solde, le seuil d'alerte etc...
J'ai fait en sorte que tout soit paramétrable si un jour tu veux passer de 24h à quelques secondes.
Je pense avoir suffisamment commenté, mais si t'as des questions n'hésite pas. J'ai pris quelques précautions que je ne sais pas si elles sont nécessaire en basic.
Imports System.Text
Imports System.Threading.Tasks
Imports System.Timers
Imports System.Windows.Threading
''' <summary>
''' Délégué décrivant la signature de l'évenement alertant le passage du seuil
''' </summary>
''' <param name="QuantiteRestante"></param>
Public Delegate Sub SeuilAtteintEvent(ByVal QuantiteRestante As Integer)
Public Delegate Sub DiversEvent()
Public Class LeTrucAJerlo
'Puisque ton besoin est d'une fois par jour un timer à le seconde est sur-qualitatif
'mais pour l'exemple je vais te le faire toutes les 10s...
Private monTimer As New Timer(1000)
'Association d'une date à attendre et d'un débit
Private echeance As KeyValuePair(Of Date, Integer)
'Cet objet sert à parler en dehors du timer sans poser de problèmes inter thread
Private dispacther As Dispatcher
''' <summary>
''' Construction d'un nouveau Truc avec les paramètres d'initialisation utiles
''' </summary>
''' <param name="QuantiteDepart"></param>
''' <param name="DebitDefaut"></param>
''' <param name="SeuildAlerte"></param>
''' <param name="HeureDefaut"></param>
Public Sub New(ByVal QuantiteDepart As Integer, ByVal DebitDefaut As Integer, ByVal SeuildAlerte As Integer, ByVal HeureDefaut As TimeSpan, Optional ByVal ProchaineEcheanceAjouteeEtAttendueAutomatiquement As Boolean = True)
dispacther = Dispatcher.CurrentDispatcher
QuantiteInitiale = QuantiteDepart
DebitParDefaut = DebitDefaut
SeuilAlerte = SeuildAlerte
HeureParDefaut = HeureDefaut
LesDebits = New Dictionary(Of Date, Integer)()
AddHandler monTimer.Elapsed, AddressOf monTimer_Elapsed
If ProchaineEcheanceAjouteeEtAttendueAutomatiquement Then
AjouterEcheance()
End If
End Sub
#Region "Propriétés"
Public Property QuantiteInitiale() As Integer
Public Property DebitParDefaut() As Integer
Public Property SeuilAlerte() As Integer
Public Property HeureParDefaut() As TimeSpan
Private soldeActuel_Renamed As Integer
''' <summary>
''' Propriété donnant le solde actuel, elle comprend une variable interne pour signaler sont changement
''' </summary>
Public Property SoldeActuel() As Integer
Get
Return soldeActuel_Renamed
End Get
Private Set(ByVal value As Integer)
'le set est privé car seul l'objet peut mettre à jour ce champ
If value = soldeActuel_Renamed Then 'même valeur on s'en va
Return
End If
soldeActuel_Renamed = value
dispacther.Invoke(New Action(Sub() RaiseEvent QuantiteRestanteMiseAJour()), DispatcherPriority.Normal)
End Set
End Property
''' <summary>
''' Dictionnaire liant chaque débit à sa datation
''' </summary>
Public Property LesDebits() As Dictionary(Of Date, Integer)
#End Region
#Region "Méthodes"
''' <summary>
''' Retourne la quantité restante maintenant
''' </summary>
''' <returns></returns>
Public Function QuantiteRestante() As Integer
Return QuantiteRestante(Date.Now)
End Function
''' <summary>
''' Retourne la quantité restante à un instant donné
''' </summary>
''' <param name="Quand"></param>
''' <returns></returns>
Public Function QuantiteRestante(ByVal Quand As Date) As Integer
'on additionnes tous les débits antérieurs au moment quand
Dim totalDebit As Integer = LesDebits.Where(Function(x) x.Key <= Quand).Sum(Function(x) x.Value)
Dim reste As Integer = QuantiteInitiale - totalDebit
If reste <= SeuilAlerte Then
dispacther.Invoke(New Action(Sub() RaiseEvent SeuilAtteint(reste)), DispatcherPriority.Normal)
End If
Return reste
End Function
''' <summary>
''' Ajoute la prochaine échéance avec les paramètres par défaut
''' </summary>
Public Sub AjouterEcheance()
Dim heureCalcul As Date = Date.Now.Date + HeureParDefaut
'si l'heure est déjà passée ce sera pour le lendemain
If heureCalcul < Date.Now.Date Then
heureCalcul = heureCalcul.AddDays(1)
End If
AjouterEcheance(heureCalcul, DebitParDefaut)
End Sub
''' <summary>
''' Ajoute une échéance
''' </summary>
Public Sub AjouterEcheance(ByVal [Date] As Date, ByVal CeDebit As Integer)
LesDebits.Add([Date], CeDebit)
'il me parrait logique de lancer l'attente automatiquement mais si ça te covinet pas il suffit de supprimer la ligne suivante
AttendreLaProchaineEcheance()
End Sub
''' <summary>
''' Lance la procédure pour attendre l'échéance suivante
''' </summary>
Public Sub AttendreLaProchaineEcheance()
'on vérife qu'on est pas déjà en train d'attendre
If monTimer.Enabled Then
Return
End If
'on vérifie qu'il y a une échéance à attendre
If LesDebits.Last().Key < Date.Now Then
dispacther.Invoke(New Action(Sub() RaiseEvent PasdEcheanceAVenir()), DispatcherPriority.Normal)
'il me parrait logique d'ajouter la prochaine échéance de suite, si ça ne te convient il faudra quitter la méthode
AjouterEcheance()
End If
'on prends la première échéance à venir, imaginons que l'utilisateur en rentre plein d'avance
echeance = LesDebits.Where(Function(x) x.Key > Date.Now).First()
'lance l'attente
monTimer.Start()
End Sub
Private Sub monTimer_Elapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs)
If Date.Now >= echeance.Key Then
monTimer.Stop()
'la date est atteinte ou dépassée
SoldeActuel = QuantiteRestante()
'il me parrait logique de relancer de suite pour la prochaine échéance, si ça ne te convient il te suffit de supprimer la ligne en dessous
AttendreLaProchaineEcheance()
End If
End Sub
#End Region
''' <summary>
''' Evément signalant que le seuil d'alerte est atteint ou dépassé
''' </summary>
Public Event SeuilAtteint As SeuilAtteintEvent
''' <summary>
''' Evénement signalant qu'il n'y a pas déchance dans le futur
''' </summary>
Public Event PasdEcheanceAVenir As DiversEvent
''' <summary>
''' Evénement signalant la mise à jour de la quantité restante, sans passer de paramètre
''' </summary>
Public Event QuantiteRestanteMiseAJour As DiversEvent
End Class
Le formulaire de test contient deux boutons et un label
Imports System.ComponentModel
Imports System.Text
Imports System.Threading.Tasks
Partial Public Class Form1
Inherits Form
Private truc As LeTrucAJerlo
Public Sub New()
InitializeComponent()
End Sub
Private Sub truc_SeuilAtteint(ByVal QuantiteRestante As Integer)
MessageBox.Show("Quantité inférieure ou égale au seuil.")
End Sub
Private Sub truc_QuantiteRestanteMiseAJour()
label1.Text = "Le solde est : " & truc.SoldeActuel
End Sub
Private Sub truc_PasdEcheanceAVenir()
MessageBox.Show("Il n'y a plus d'échéances.")
End Sub
Private Sub butNouvelleSequence_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butNouvelleSequence.Click
'cette séquence teste va arriver un un nombre de séquence insuffisant
Dim HeureParDefautDeTest As TimeSpan = Date.Now.TimeOfDay + TimeSpan.FromSeconds(5)
'initialisation d'un truc
truc = New LeTrucAJerlo(4000, 200, 400, HeureParDefautDeTest)
'on abonne les méthodes aux événements de truc
AddHandler truc.PasdEcheanceAVenir, AddressOf truc_PasdEcheanceAVenir
AddHandler truc.QuantiteRestanteMiseAJour, AddressOf truc_QuantiteRestanteMiseAJour
AddHandler truc.SeuilAtteint, AddressOf truc_SeuilAtteint
'j'ajoute des échéances personnalisées pour que l'exemple ne dure que quelques secondes
Dim heureSuivante As Date = Date.Now.Date + HeureParDefautDeTest + TimeSpan.FromSeconds(5)
truc.AjouterEcheance(heureSuivante, 200)
truc.AjouterEcheance(heureSuivante.AddSeconds(5),500)
truc.AjouterEcheance(heureSuivante.AddSeconds(10), 200)
truc.AjouterEcheance(heureSuivante.AddSeconds(15), 500)
truc.AjouterEcheance(heureSuivante.AddSeconds(20), 500)
End Sub
Private Sub button2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles button2.Click
'cette séquence teste va passer sous le seuil
Dim HeureParDefautDeTest As TimeSpan = Date.Now.TimeOfDay + TimeSpan.FromSeconds(5)
'initialisation d'un truc
truc = New LeTrucAJerlo(4000, 800, 400, HeureParDefautDeTest)
'on abonne les méthodes aux événements de truc
AddHandler truc.PasdEcheanceAVenir, AddressOf truc_PasdEcheanceAVenir
AddHandler truc.QuantiteRestanteMiseAJour, AddressOf truc_QuantiteRestanteMiseAJour
AddHandler truc.SeuilAtteint, AddressOf truc_SeuilAtteint
'j'ajoute des échéances personnalisées pour que l'exemple ne dure que quelques secondes
Dim heureSuivante As Date = Date.Now.Date + HeureParDefautDeTest + TimeSpan.FromSeconds(5)
truc.AjouterEcheance(heureSuivante, 800)
truc.AjouterEcheance(heureSuivante.AddSeconds(5), 800)
truc.AjouterEcheance(heureSuivante.AddSeconds(10), 900)
truc.AjouterEcheance(heureSuivante.AddSeconds(15), 500)
truc.AjouterEcheance(heureSuivante.AddSeconds(20), 500)
End Sub
End Class
28 mai 2016 à 17:05
Modifié par vb95 le 28/05/2016 à 17:15
Je te laisse ce plaisir : plussoyez mon cher
28 mai 2016 à 18:53
Merci je vais essayer de mettre à jours mon code celon ton exemple