Cumul des heures pour calculer Date fin
Stagiaire WDF
Inscrit:
07/08/2007 12:23
Post(s): 3
Bonjour,

Je voudrais calculer la date et l'heure fin en cumulant les heures des équipes à partir d'une date et heure début.

J'ai une table EQUIPE qui contient les équipes avec les horaires respectifs.
Exemple : E1 : 13:00 - 20:00
E2 : 22:00 - 05:00

L'User doit pouvoir choisir à quelle veut il commencer le travail. Pour ce faire, le programme doit vérifier si l'heure est conforme aux bornes des équipes et déterminer quelle est l'équipe débutante.

Soit le scénario suivant :

Date début : 07/08/07 23:00
Nombre d'heures à travailler : 30 h

Logiquement, le programme doit retourner la planification suivante :

Intervalle planifié : 07/08/07 23:00 - 10/08/07 01:00

J'ai écris ce code pour ce faire mais la solution idéale pour tous les cas n'est pas encore au rendez-vous.

Quelqu'un peut-il m'éclairer ?

Voici mon code. Ayant un peu de patience car il est volumineux :


wHeureDernièreEquipe est une Heure
wHDE1,wHFE1,wHDE2,wHFE2,wHDE3,wHFE3 sont des Heures //HeureDeb & HeureFin des équipes E1,E2 & E3
wEquipeDébutante est une chaîne = "" //Quelle équipe va débuter la fabrication ? Ceci est connu en fonction de l'heure saisie par l'utilisateur
wEstInterne est un booléen //Pour voir si l'heure saisie par l'User est à l'intérieur des intervalles d'heures des équipes
wNbEquipe est un entier = 0 //On a combien d'équipe pour cette Machine ?


//Détermination du nombre d'équipe et de l'équipe débutante
CléParcours = HFiltreIdentique(MACHINE,PK_MACHINE,g_Societe_defaut,g_ent_defaut,P_CodMach)
HLitPremier(MACHINE,CléParcours)
SI HTrouve() ALORS
	//1ère équipe
	SI MACHINE.HEURDEB1 <> "" ALORS
		wEstInterne = VerifBorneHeureOK(MACHINE.HEURDEB1,MACHINE.HEURFIN1,P_HeureDeb)
		SI wEstInterne = Vrai ALORS
			wEquipeDébutante = "E1"
		FIN
		wHDE1..Heure = Gauche(MACHINE.HEURDEB1,2)
		wHDE1..Minute = Milieu(MACHINE.HEURDEB1,3,2)
		wHFE1..Heure = Gauche(MACHINE.HEURFIN1,2)
		wHFE1..Minute = Milieu(MACHINE.HEURFIN1,3,2)
		wHeureDernièreEquipe = wHFE1
		wNbEquipe++
	FIN
	//2ème équipe
	SI MACHINE.HEURDEB2 <> "" ALORS
		wEstInterne = VerifBorneHeureOK(MACHINE.HEURDEB2,MACHINE.HEURFIN2,P_HeureDeb)
		SI wEstInterne = Vrai ALORS
			wEquipeDébutante = "E2"
		FIN
		wHDE2..Heure = Gauche(MACHINE.HEURDEB2,2)
		wHDE2..Minute = Milieu(MACHINE.HEURDEB2,3,2)
		wHFE2..Heure = Gauche(MACHINE.HEURFIN2,2)
		wHFE2..Minute = Milieu(MACHINE.HEURFIN2,3,2)
		wHeureDernièreEquipe = wHFE2
		wNbEquipe++
	FIN
	//3ème équipe
	SI MACHINE.HEURDEB3 <> "" ALORS
		wEstInterne = VerifBorneHeureOK(MACHINE.HEURDEB3,MACHINE.HEURFIN3,P_HeureDeb)
		SI wEstInterne = Vrai ALORS
			wEquipeDébutante = "E3"
		FIN
		wHDE3..Heure = Gauche(MACHINE.HEURDEB3,2)
		wHDE3..Minute = Milieu(MACHINE.HEURDEB3,3,2)
		wHFE3..Heure = Gauche(MACHINE.HEURFIN3,2)
		wHFE3..Minute = Milieu(MACHINE.HEURFIN3,3,2)
		wHeureDernièreEquipe = wHFE3
		wNbEquipe++
	FIN
FIN
HDésactiveFiltre(MACHINE)

wRenvoyer = DébuterPar(wEquipeDébutante,wNbEquipe,NbreMinutes,P_DateDeb,P_HeureDeb,...
						wHDE1,wHFE1,wHDE2,wHFE2,wHDE3,wHFE3,wHeureDernièreEquipe)

RENVOYER(wRenvoyer)





//Procédure DébuterPar

PROCEDURE DébuterPar(P_EquipeDeb,P_NbEquipe,P_NbTotMin,P_DateDeb,P_HeureDeb,P_HDE1,...
									P_HFE1,P_HDE2,P_HFE2,P_HDE3,P_HFE3,P_HeureDernièreEquipe)

wNbreTotMin est un numérique
wRésultat,wTourEquipe sont des chaînes //wTourEquipe permet de dire c'est le tour de quelle équipe ?
wDateFin est une Date
wHeureDeb,wHeureFin,wDernièreBorneHF,wHeureDernièreEquipe sont des Heures
wHDE1,wHFE1,wHDE2,wHFE2,wHDE3,wHFE3 sont des Heures //HeureDeb & HeureFin des équipe E1,E2 & E3
wDiffMin est un entier = 0 //Nombre de Minutes entre une DateDeb et une DateFin
wPartirHeureDeb est un booléen = Vrai
wNbEquipe est un entier = P_NbEquipe

//Initialisations
wNbreTotMin = P_NbTotMin
wDateFin = P_DateDeb
wHeureDeb = P_HeureDeb
wHDE1 = P_HDE1
wHFE1 = P_HFE1
wHDE2 = P_HDE2
wHFE2 = P_HFE2
wHDE3 = P_HDE3
wHFE3 = P_HFE3
wHeureDernièreEquipe = P_HeureDernièreEquipe


SELON P_EquipeDeb
	CAS "E1"
		wDiffMin = DiffHeureEnMinutes(wHeureDeb,wHFE1)
		wDernièreBorneHF..Heure = Gauche(wHFE1,2)
		wDernièreBorneHF..Minute = Milieu(wHFE1,3,2)
	CAS "E2"
		wDiffMin = DiffHeureEnMinutes(wHeureDeb,wHFE2)
		wDernièreBorneHF..Heure = Gauche(wHFE2,2)
		wDernièreBorneHF..Minute = Milieu(wHFE2,3,2)
	CAS "E3"
		wDiffMin = DiffHeureEnMinutes(wHeureDeb,wHFE3)
		wDernièreBorneHF..Heure = Gauche(wHFE3,2)
		wDernièreBorneHF..Minute = Milieu(wHFE3,3,2)		
FIN

//On soustrait l'intervalle "Date saisie par l'User jusqu'à Borne HeureFin Equipe" du nombre Totale Min
SI wNbreTotMin >= wDiffMin ALORS
	wPartirHeureDeb = Faux
	wNbreTotMin-= wDiffMin
	wDiffMin = 0 //Réinitialisation
	//Prendre à présent tout l'intervalle "HeureDeb jusqu'à HeureFin" de l'équipe
	//puis déterminer à quelle équipe le Tour ?
	SELON P_NbEquipe
		CAS 1
			wDiffMin = DiffHeureEnMinutes(wHDE1,wHFE1)
			wTourEquipe = "ME"
			//*************************
			//Incrémenter la DateFin car c'est sa différence qu'on vient de soustraire ci-haut
			SI wNbreTotMin > 0 ALORS
				wDateFin..Jour++
			FIN
			//*************************
		CAS 2
			SI P_EquipeDeb = "E1" ALORS
				wDiffMin = DiffHeureEnMinutes(wHDE2,wHFE2)
				wTourEquipe = "E1"
			SINON
				wDiffMin = DiffHeureEnMinutes(wHDE1,wHFE1)
				wTourEquipe = "E2"
				//*************************
				//Incrémenter la DateFin car la boucle n'incrémente que sur E1
				SI wNbreTotMin > 0 ALORS
					wDateFin..Jour++
				FIN
				//*************************
			FIN
		CAS 3
			SI P_EquipeDeb = "E1" ALORS
				wDiffMin = DiffHeureEnMinutes(wHDE2,wHFE2)
				wTourEquipe = "E3"
			SINON
				SI P_EquipeDeb = "E2" ALORS
					wDiffMin = DiffHeureEnMinutes(wHDE3,wHFE3)
					wTourEquipe = "E1"
				SINON
					wDiffMin = DiffHeureEnMinutes(wHDE1,wHFE1)
					wTourEquipe = "E2"
					//*************************
					//Incrémenter la DateFin car la boucle n'incrémente que sur E1
					SI wNbreTotMin > 0 ALORS
						wDateFin..Jour++
					FIN
					//*************************
				FIN
			FIN
	FIN
FIN

TANTQUE wNbreTotMin >= wDiffMin
	wNbreTotMin-= wDiffMin
	SELON wTourEquipe
		CAS "ME"
			SI wNbreTotMin > 0 ALORS
				wDateFin..Jour++
			FIN
			wDiffMin = DiffHeureEnMinutes(wHDE1,wHFE1)
			wTourEquipe = "ME"
			wDernièreBorneHF..Heure = Gauche(wHFE1,2)
			wDernièreBorneHF..Minute = Milieu(wHFE1,3,2)
		CAS "E1" 
			//Que ce soit 2 ou 3 équipes, on passe toujours de la 1ère à la 2ème équipe
			//On incrémenter car on recycle
			SI wNbreTotMin > 0 ALORS
				wDateFin..Jour++
			FIN
			wDiffMin = DiffHeureEnMinutes(wHDE1,wHFE1)
			wTourEquipe = "E2"
			//Mais la dernière borne HeureFin varie en fonction du nombre d'équipe
			SI P_NbEquipe = 2 ALORS
				wDernièreBorneHF..Heure = Gauche(wHFE2,2)
				wDernièreBorneHF..Minute = Milieu(wHFE2,3,2)
			SINON //3 équipes
				wDernièreBorneHF..Heure = Gauche(wHFE3,2)
				wDernièreBorneHF..Minute = Milieu(wHFE3,3,2)
			FIN
		CAS "E2"
			wDiffMin = DiffHeureEnMinutes(wHDE2,wHFE2)
			//On a ici une seule dernière borne HeureFin : celle de l'équipe E1
			wDernièreBorneHF..Heure = Gauche(wHFE1,2)
			wDernièreBorneHF..Minute = Milieu(wHFE1,3,2)
			//Mais 2 cas se posent pour l'équipe suivante : on peut avoir 2 ou 3 équipes
			SI P_NbEquipe = 2 ALORS
				wTourEquipe = "E1"
			SINON //3 équipes
				wTourEquipe = "E3"
			FIN
		CAS "E3"
			//On a ici 3 équipes ==>> On boucle alors pour revenir à la 1ère équipe
			wDiffMin = DiffHeureEnMinutes(wHDE3,wHFE3)
			wTourEquipe = "E1"
			wDernièreBorneHF..Heure = Gauche(wHFE2,2)
			wDernièreBorneHF..Minute = Milieu(wHFE2,3,2)
	FIN
FIN

SI wPartirHeureDeb = Faux ALORS
	SI wNbreTotMin = 0 ALORS
		wHeureFin = wDernièreBorneHF
	SINON //wNbreTotMin > 0
		SELON wTourEquipe
			CAS "ME"
				//Le temps restant sera compté à partir de l'HeureDeb de l'équipe 1
				wHeureFin = wHDE1
				wHeureFin..Heure+= PartieEntière(wNbreTotMin / 60)
				wHeureFin..Minute+= modulo(wNbreTotMin,60)
			CAS "E1"
				SI P_NbEquipe = 2 ALORS
					//Le temps restant sera compté à partir de l'HeureDeb de l'équipe 2
					wHeureFin = wHDE2
					wHeureFin..Heure+= PartieEntière(wNbreTotMin / 60)
					wHeureFin..Minute+= modulo(wNbreTotMin,60)
				SINON // 3 équipes
					//Le temps restant sera compté à partir de l'HeureDeb de l'équipe 3
					wHeureFin = wHDE3
					wHeureFin..Heure+= PartieEntière(wNbreTotMin / 60)
					wHeureFin..Minute+= modulo(wNbreTotMin,60)
				FIN
			CAS "E2"
				//Indépendant du nombre d'équipe si c'est le tour de l'équipe E2
				//car on vient toujours de l'équipe E1
				//Le temps restant sera compté à partir de l'HeureDeb de l'équipe 1
				wHeureFin = wHDE1
				wHeureFin..Heure+= PartieEntière(wNbreTotMin / 60)
				wHeureFin..Minute+= modulo(wNbreTotMin,60)
			CAS "E3"
				//On est forcément en présence de 3 équipes
				//et on ne peut provenir que de l'équipe E2
				//Le temps restant sera compté à partir de l'HeureDeb de l'équipe 2
				wHeureFin = wHDE2
				wHeureFin..Heure+= PartieEntière(wNbreTotMin / 60)
				wHeureFin..Minute+= modulo(wNbreTotMin,60)
		FIN
	FIN
SINON
	wHeureFin = wHeureDeb
	wHeureFin..Heure+= PartieEntière(wNbreTotMin / 60)
	wHeureFin..Minute+= modulo(wNbreTotMin,60)
FIN

//Exécution de la requête SQL pour obtenir le nombre de jours fériés
HExécuteRequête(ReqJourFerie,hRequêteDéfaut,g_Societe_defaut,g_ent_defaut,P_DateDeb,wDateFin)
HLitPremier(ReqJourFerie)
SI HNbEnr(ReqJourFerie) > 0 ALORS //Il existe des jours fériés entre Date début et date fin
	wDateFin..Jour+= HNbEnr(ReqJourFerie) //La date fin doit inclure ces jours fériés
FIN

wRésultat = wDateFin + TAB + wHeureFin
RENVOYER(wRésultat)

Contribution le : 07/08/2007 12:44
_________________
Citation :
L'essentiel n'est pas de tout savoir mais de savoir là où tout se trouve
Créer un fichier PDF de la contribution Imprimer


Re: Cumul des heures pour calculer Date fin
Animateur WDF
Inscrit:
02/03/2003 04:07
De Noisy le grand(93)
Post(s): 2745
Bonjour et bienvenu sur notre site,

Sans chercher la bonne solution commencer par simplifier votre code en utilisant l'indirection ainsi que des tableaux dynamiques
wHeureDernièreEquipe est une Heure
tblwHDE est un tableau dynamique de 0 heures
tblwHFE est un tableau dynamique de 0 heures
wEquipeDébutante est une chaîne = "" //Quelle équipe va débuter la fabrication ? Ceci est connu en fonction de l'heure saisie par l'utilisateur
wEstInterne est un booléen //Pour voir si l'heure saisie par l'User est à l'intérieur des intervalles d'heures des équipes
wNbEquipe est un entier = 0 //On a combien d'équipe pour cette Machine ?
nNbEquipe est un entier = 3 //Nombre total d'équipe dispo.
Ind est un entier

Dimension(tblwHDE, nNbEquipe)
Dimension(tblwHFE, nNbEquipe)
//Détermination du nombre d'équipe et de l'équipe débutante
CléParcours = HFiltreIdentique(MACHINE,PK_MACHINE,g_Societe_defaut,g_ent_defaut,P_CodMach)
HLitPremier(MACHINE,CléParcours)
SI HTrouve() ALORS
  POUR Ind = 1 A nNbEquipe
    SI {"MACHINE.HEUREDEB" + Ind, indRubrique} <> "" ALORS
      wEstInterne = VerifBorneHeureOK({"MACHINE.HEURDEB" + ind, indRubrique},{"MACHINE.HEURFIN" + ind, indRubrique}, P_HeureDeb)
      SI wEstInterne = Vrai ALORS
	wEquipeDébutante = "E" + Ind
      FIN
      hHeure est une Heure
      hHeure..Heure = {"MACHINE.HEURDEB" + Ind, indRubrique}[[ A 2 ]]
      hHeure..Minute = ({"MACHINE.HEURDEB" + Ind, indRubrique}[[ 3 A 4 ]]
      hHeure..Heure = {"MACHINE.HEURFIN" + Ind, indRubrique}[[ A 2 ]]
      hHeure..Minute = {"MACHINE.HEURFIN" + Ind, indRubrique}[[ 3 a 4 ]]
      tblwHFE[Ind] = hHeure
      wHeureDernièreEquipe = hHeure
      wNbEquipe++
    FIN
  FIN  
FIN
HDésactiveFiltre(MACHINE)

wRenvoyer = DébuterPar(wEquipeDébutante,wNbEquipe,NbreMinutes,P_DateDeb,P_HeureDeb,...
	   tblwHDE, tblwHFE,wHeureDernièreEquipe)

RENVOYER(wRenvoyer)

Au lieu de renvoyer les variables par équipe, utiliser plutôt des tableaux cela bridera moins votre code si le nombre d'équipe vient à augmenter.
De plus l'indirection vous permettra de réduire considérablement votre code et de le rendre ainsi plus lisible et plus facile à maintenir.
Notes: vous pouvez aussi utiliser la classe jourFérié fourni dans des exemples de WinDev pour tenir compte des jours fériés.

Contribution le : 07/08/2007 15:47
_________________
@A+
Contact (privé)......
email : drcharly@wdforge.org
[DrCharly93]
Créer un fichier PDF de la contribution Imprimer


Re: Cumul des heures pour calculer Date fin
Stagiaire WDF
Inscrit:
07/08/2007 12:23
Post(s): 3
Bonjour,

Merci pour votre réponse. Je me disais si quelqu'un prendrait-il le temps d'examiner mon code tellement il est long. Mais c'est chose faite. Je vous remercie pour ça.

Je vais suivre votre conseil. Mais le seul Hic c'est ma procédure "DébuterPar(...)". En fait, le problème réside dans l'incrémentation des Jours de wDateFin. A quel moment le faire pour que l'algo soit juste !!!

S'il pouvait y avoir un oeil nouveau.

Merci

Mes amitiés et encore Merci à drcharly93 d'avoir pris la peine de me proposer cette optimisation.

Contribution le : 08/08/2007 08:35
_________________
Citation :
L'essentiel n'est pas de tout savoir mais de savoir là où tout se trouve
Créer un fichier PDF de la contribution Imprimer


Re: Cumul des heures pour calculer Date fin
Animateur WDF
Inscrit:
26/06/2002 16:24
De wdforge.org
Post(s): 2822
A chaque pointage correspond une date et une heure...
ainsi vous pouvez concaténer ces valeur dans une variable de type Dateheure.
L'intéret est alors d'utiliser la fonction DateHeureDifférence pour connaitre la durée à cumuler au champ (aussi de type dateheure).

En tout cas c'est une piste.

Contribution le : 08/08/2007 14:23
_________________
R&B
Contact, CV.
Créer un fichier PDF de la contribution Imprimer


Re: Cumul des heures pour calculer Date fin
Stagiaire WDF
Inscrit:
07/08/2007 12:23
Post(s): 3
L'utilisation de la fonction DateHeureDifférence suppose la connaissance préalable de la date fin. Ce qui n'est pas le cas ici.

L'objectif, c'est qu'étant donné une Date et une Heure début et connaissant un Nombre d'heures, on va ajouter ce nombre d'heures succèssivement jusqu'à ce qu'il s'épuise et qu'on obtienne en ce moment précis la "Fameuse Date Fin".

Espérant être clair

Contribution le : 08/08/2007 18:45
_________________
Citation :
L'essentiel n'est pas de tout savoir mais de savoir là où tout se trouve
Créer un fichier PDF de la contribution Imprimer



 Haut   Précédent   Suivant




Enregistrer votre réponse
CompteNom   Mot de passe   Authentification
Message:


Vous ne pouvez pas débuter de nouveaux sujets.
Vous pouvez voir les sujets.
Vous ne pouvez pas répondre aux contributions.
Vous ne pouvez pas éditer vos contributions.
Vous ne pouvez pas effacez vos contributions.
Vous ne pouvez pas ajouter de nouveaux sondages.
Vous ne pouvez pas voter en sondage.
Vous ne pouvez pas attacher des fichiers à vos contributions.
Vous ne pouvez pas poster sans approbation.

[Recherche avancée]


Connexion
Menu
Chercher WDForge
Chercher Web
Partenaires
Visualiser tous les Partenaires...
WinDev, WebDev, WinDev Mobile et HyperFile sont des marques déposées par PCSoft. |  Voter |  Legal |  Contact |   XOOPS 2.0.13.2