IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Simulation de process industriel

Simulation de process industriel dans un formulaire Access.

Niveau requis : confirmé.

Commentez cet article : 6 commentaires Donner une note à l´article (5)

Article lu   fois.

L'auteur

Profil Pro

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Les process industriels impliquent souvent des calculs complexes et nécessitent donc un peu d'expérience pour appréhender le code mis en œuvre. Le but n'étant pas d'alourdir le propos avec des formules trop compliquées, je vais donc essayer de décrire un exemple simple de simulation d'un process industriel dans Ms Access, suivant une gamme de fabrication.

II. Contexte

Dans l'industrie, les machines peuvent être regroupées en ensembles autonomes de production spécialisés par type de produits qui utilisent les mêmes machines : ces ensembles s'appellent des îlots. Les flux de produits (matières) peuvent utiliser les postes de travail de l'îlot dans un ordre différent suivant leur gamme de fabrication, alors que dans une ligne de fabrication l'ordre est impératif.

Image non disponible
Description d'un îlot de machines

Pour simplifier, on va ici considérer une gamme de fabrication composée de m machines placées en série et négliger les durées de transfert entre machines.

III. Description du principe

L'objectif est d'obtenir, à partir de formules mathématiques, le nombre de pièces en attente sur une machine quelconque ainsi que le total des pièces déjà usinées à un instant donné. Nous injecterons ces fonctions traduites en VBA dans des requêtes pour afficher et représenter la progression des pièces sur les différentes machines.

III-A. Formules mathématiques de base mises en œuvre

La durée de fabrication de n pièces qui passent sur m machines au total
Sélectionnez
duree_fabrication = (n-1)*duree_max + duree_total
  • duree_max : durée de passage la plus longue entre les machines.
  • duree_total : durée totale de passage sur les machines.

On en déduit :

Le nombre de pièces fabriquées sur m machines placées en série après une durée d
Sélectionnez
nbre_fabrique = ((d - duree_total) \ duree_max) + 1

C'est cette formule mathématique qui va nous servir de base pour nos calculs dans nos requêtes.

III-B. Formules mathématiques généralisées

La durée de passage de n pièces qui passent sur i machines disposées en série (i compris entre 1 et m)
Sélectionnez
duree_passage(i) = (n-1)*duree_max(i) + duree_total(i)
  • duree_max(i) : durée de passage la plus longue entre les machines d'indice 1 à i.
  • duree_total(i) : durée totale de passage sur les i machines.

En inversant la formule on obtient :

Le nombre de pièces passées sur les i machines, après une durée d
Sélectionnez
nbre_passe(i) = ((d - duree_total(i)) \ duree_max(i)) + 1

Nous utilisons ici la division entière, notée « \ » en VBA, pour obtenir un nombre entier de pièces.

On en déduit enfin :

Le nombre de pièces en attente sur la machine d'indice i, après une durée d
Sélectionnez
nbre_attente(i) = (((d - duree_total(i-1)) \ duree_max(i-1)) + 1) - (((d - duree_total(i)) \ duree_max(i)) + 1)
  • duree_max(i-1) : durée de passage la plus longue entre les machines d'indice 1 à (i-1) ;
  • duree_total(i-1) : durée totale de passage sur l'ensemble des (i-1) machines ;
  • duree_max(i) : durée de passage la plus longue entre les machines d'indice 1 à i ;
  • duree_total(i) : durée totale de passage sur les i machines.

Cette dernière formule va nous permettre de connaître, à un instant donné, le nombre de pièces en attente sur une machine quelconque et surtout, le nombre total de pièces déjà terminées en bout de gamme.

IV. Rendu final de la simulation du process

Voici le rendu du formulaire qui présente, pour chaque machine, le nombre de pièces en attente et donc la progression des pièces usinées.

Image non disponible
Aperçu du formulaire de simulation

On constate que le programme permet de visualiser, pour chaque tranche horaire, le plan de charge de toutes les machines.

Voici les objets nécessaires pour aboutir à ce résultat.

V. Les tables nécessaires

Pour sauvegarder les durées d'usinage sur chaque machine ainsi que les jours et tranches horaires intervenant dans la simulation, nous aurons besoin de trois tables :

V-A. La table T_Creneau

Cette table contient la liste des créneaux horaires accompagnés de leur indice.

Nom du champ

Type de données

Description

Indice

Numérique

Indice du créneau horaire

Creneau

Texte

Créneau horaire

V-B. La table T_Jour

Elle permet d'enregistrer les indices des jours durant lesquels se déroule le processus industriel.

Nom du champ

Type de données

Description

Jour

Entier long

Numéro d'ordre du jour

V-C. La table T_Machine

Cette table permet de sauvegarder les noms des machines et les durées de passage des pièces qui peuvent être paramétrés.

Nom du champ

Type de données

Description

Indice

Entier long

Numéro d'ordre de la machine

Machine

Texte

Nom de la machine

Duree

Entier long

Durée de passage sur la machine

VI. Les requêtes pour la partie simulation

Afin de pouvoir afficher, pour chaque jour et chaque tranche horaire, le plan de charge simulé des machines, on a besoin de réaliser quelques requêtes.

VI-A. La requête affichant les tranches horaires

Cette requête paramétrée réalise le produit cartésien entre la table T_Creneau et T_Jour, pour afficher toutes les tranches horaires du process :

Image non disponible
Aperçu de la requête affichant les horaires

On constate que la requête comprend, dans la partie encerclée, des champs calculés que nous allons détailler.

VI-A-1. La formule donnant les jours

Le champ calculé affichant le(s) jour(s) pris en compte dans la simulation
Sélectionnez
DateJour: AjDate("j";[Jour]-1;ValDate([Forms]![F_Simuler_Process]![Date_Debut]))
  • [Forms]![F_Simuler_Process]![Date_Debut] : paramètre donnant la date et l'heure du début du process.

VI-A-2. La formule donnant les heures

Le champ calculé affichant les tranches horaires prises en compte dans la simulation
Sélectionnez
Horaire: AjDate("n";([Indice]-1)*Forms!F_Simuler_Process!Creneau;Forms!F_Simuler_Process!Horaire_Debut)
  • [Forms]![F_Simuler_Process]![Creneau] : paramètre donnant la durée des tranches horaires.
  • [Forms]![F_Simuler_Process]![Horaire_Debut] : paramètre donnant l'heure du début du process.

VI-A-3. La formule donnant les dates et heures

Les dates et horaires pris en compte dans la simulation s'obtiennent en fonction du paramètre définissant le 1er jour et le 1er horaire :

Le champ calculé affichant les dates et heures prises en compte dans la simulation
Sélectionnez
DateHeure: CDate(AjDate("j";[Jour]-1;ValDate([Forms]![F_Simuler_Process]![Date_Debut])) & " " & AjDate("n";([Indice]-1)*[Forms]![F_Simuler_Process]![Creneau];[Forms]![F_Simuler_Process]![Horaire_Debut]))

VI-A-4. Fonction évaluant la date et l'heure de fin du process

On évalue la date et l'heure de fin du processus à partir de la formule de base définie précédemment :

La durée de fabrication de n pièces qui passent sur m machines au total
Sélectionnez
duree_fabrication = (n-1)*duree_max + duree_total

La fonction VBA mise en œuvre pour ce calcul va permettre de filtrer la requête sur le champ date et heure :

Fonction donnant la date et l'heure de fin du processus
Sélectionnez
Public Function fin_process(ByVal nbre As Long, ByVal debut As Date, ByVal Horaire_Debut, ByVal Horaire_Fin, ByVal Creneau As Integer) As Date
' date et heure de fin du process en fonction du nombre de pièces, de la date de début du process, 
' des heures de début et de fin dans la journée et du créneau horaire.
Dim rs As DAO.Recordset
Dim leSql As String
Dim d As Long, d1 As Long, d2 As Long
Dim dt As Date
Dim j As Integer
Dim m As Long

' requête affichant la durée totale du process en se basant sur la formule (n-1)*duree_max + duree_total.
leSql = "SELECT " & (nbre - 1) & "*Max([Duree])+Sum([Duree]) AS durée " & _
"FROM T_Machine;"

' le jeu d'enregistrement correspondant.
Set rs = CurrentDb.OpenRecordset(leSql, dbOpenForwardOnly)

' la durée totale.
d = rs!durée

rs.Close
Set rs = Nothing

d1 = DateDiff("s", TimeValue(debut), Horaire_Fin)

   If d <= d1 Then ' si compris dans l'intervalle.
      fin_process = DateAdd("s", d, debut)
      
   Else ' sinon on décompose la durée.
   
      d = d - d1
      dt = CDate(Format(debut + 1, "dd/mm/yyyy") & " " & Format(Horaire_Debut, "hh:nn"))
      m = DateDiff("s", Horaire_Debut, Horaire_Fin)
      j = d \ m
      dt = DateAdd("d", j, dt)
      dt = DateAdd("s", d Mod m, dt)
      
      fin_process = dt
      
   End If

' renvoie la date et l'heure de fin du process.
fin_process = DateAdd("s", (Creneau * 60), fin_process)

End Function

VI-B. La requête affichant la charge des machines

Cette requête paramétrée réalise le produit cartésien entre la requête précédente R_Horaire2 et la table T_Machine, de manière à afficher toutes les tranches horaires du process et les quantités en attente sur chaque machine :

Image non disponible
Aperçu de la requête finale

On remarque que la requête comprend dans la partie encerclée des champs calculés que nous allons détailler.

VI-B-1. Mise en œuvre de la formule généralisée

Nous avons en fait injecté dans la requête au niveau du champ Nbre la formule généralisée vue précédemment :

La formule donnant le nombre de pièces en attente sur la machine d'indice i
Sélectionnez
nbre_attente(i) = (((d - duree_total(i-1)) \ duree_max(i-1)) + 1) - (((d - duree_total(i)) \ duree_max(i)) + 1)

À cet effet, nous avons évalué les différentes durées maximales et totales au moyen de fonctions de domaine.

VI-B-1-a. Durée totale (i-1)
La durée totale jusqu'à la machine d'indice (i-1)
Sélectionnez
Duree_Total1: SomDom("Duree";"T_Machine";"Indice<=" & ([T_Machine_1].[Indice]-1) & " or ( Indice=1)")

On choisit ici une fonction de domaine, dans la seconde version de l'exemple disponible en téléchargement nous utilisons une sous-requête à la place.

VI-B-1-b. Durée maximum (i-1)
La durée maximum jusqu'à la machine d'indice (i-1)
Sélectionnez
Duree_Max1: MaxDom("Duree";"T_Machine";"Indice<=" & ([T_Machine_1].[Indice]-1) & " or ( Indice=1)")
VI-B-1-c. Durée totale (i)
La durée totale jusqu'à la machine d'indice i
Sélectionnez
Duree_Total2: SomDom("[Duree]";"T_Machine";"Indice<=" & [T_Machine_1].[Indice])
VI-B-1-d. Durée maximum (i)
La durée maximum jusqu'à la machine d'indice i
Sélectionnez
 Duree_Max2: MaxDom("Duree";"T_Machine";"Indice<=" & [T_Machine_1].[Indice])

Puis, on a inséré dans le champ nbre de la requête principale une fonction VBA qui est la traduction de la formule généralisée mentionnée plus haut.

VI-B-1-e. Nombre de pièces en attente à l'indice i

On a injecté la formule généralisée vue précédemment au niveau de la requête en utilisant une fonction VBA fnc_nbre :

Le champ calculé indiquant le nombre de pièces en attente sur une machine donnée
Sélectionnez
Nbre: VraiFaux(T_Machine_1.Indice=12;fnc_Nbre(Forms!F_Simuler_Process!Date_Debut;[DateHeure];Forms!F_Simuler_Process!Horaire_Debut;Forms!F_Simuler_Process!Horaire_Fin;[Duree_Total2];[Duree_Max2];Forms!F_Simuler_Process!Nbre_Pieces);(VraiFaux(T_Machine_1.Indice=1;Forms!F_Simuler_Process!Nbre_Pieces;fnc_Nbre(Forms!F_Simuler_Process!Date_Debut;[DateHeure];Forms!F_Simuler_Process!Horaire_Debut;Forms!F_Simuler_Process!Horaire_Fin;[Duree_Total1];[Duree_Max1];Forms!F_Simuler_Process!Nbre_Pieces)))-fnc_Nbre(Forms!F_Simuler_Process!Date_Debut;[DateHeure];Forms!F_Simuler_Process!Horaire_Debut;Forms!F_Simuler_Process!Horaire_Fin;[Duree_Total2];[Duree_Max2];Forms!F_Simuler_Process!Nbre_Pieces))

On utilise ici la fonction VraiFaux pour tester si on est en bout de gamme (l'indice égal à 12 est juste un indicateur de fin supérieur au nombre maximum de machines), dans ce cas, on calcule le nombre de pièces fabriquées. L'expression comprend également la fonction fnc_Nbre qui donne le nombre de pièces passées sur les i machines, après une durée d.

Les champs durées et date/heure définis précédemment :

  • Duree_Max1 : durée maximum jusqu'à la machine d'indice (i-1) ;
  • Duree_Total1 : durée totale jusqu'à la machine d'indice (i-1) ;
  • Duree_Max2: durée maximum jusqu'à la machine d'indice (i) ;
  • Duree_Total2 : durée totale jusqu'à la machine d'indice (i) ;
  • DateHeure : date et heure prises en compte pour le calcul.

Les paramètres de la simulation (début et fin du process) qui sont des zones de texte situées sur le formulaire simulateur du process :

  • Forms!F_Simuler_Process!Date_Debut : paramètre indiquant la date et l'heure de début de la simulation ;
  • Forms!F_Simuler_Process!Horaire_Debut : paramètre indiquant l'heure de début du process ;
  • Forms!F_Simuler_Process!Horaire_Fin : paramètre indiquant l'heure de fin du process.
La fonction VBA donnant le nombre de pièces en attente sur les différentes machines de la gamme de fabrication
Sélectionnez
Public Function fnc_Nbre(ByVal debut As Date, ByVal fin As Date, ByVal Horaire_Debut As Date, ByVal Horaire_Fin As Date, ByVal duree_total As Integer, ByVal duree_max As Integer, ByVal nbre As Long) As Long
' nombre de pièces passées sur la machine en fonction de la durée totale et de la durée max. jusqu'à cette machine.

Dim j As Integer
Dim d1 As Long, d2 As Long
Dim d As Long

j = DateDiff("d", debut, fin)

   If j > 1 Then ' process sur plusieurs jours.
      d = (j - 1) * DateDiff("s", Horaire_Debut, Horaire_Fin)
      d1 = DateDiff("s", TimeValue(debut), Horaire_Fin)
      d2 = DateDiff("s", Horaire_Debut, TimeValue(fin))
      d = d + d1 + d2
   ElseIf (j = 1) Then ' simulation sur 1 jour entier.
      d1 = DateDiff("s", TimeValue(debut), Horaire_Fin)
      d2 = DateDiff("s", Horaire_Debut, TimeValue(fin))
      d = d1 + d2
   Else ' process se déroulant dans la journée.
      d = DateDiff("s", TimeValue(debut), TimeValue(fin))
   End If

   If (d >= duree_total) Then
      fnc_Nbre = (d - duree_total) \ duree_max + 1 ' formule mathématique définie dans l'article.
      
         If fnc_Nbre > nbre Then
            fnc_Nbre = nbre
         End If
      
   Else
      fnc_Nbre = 0   
   End If

End Function
VI-B-1-f. Date et heure de fin du process

On évalue la date et l'heure de fin du processus à partir de la formule de base définie précédemment :

La durée de fabrication de n pièces qui passent sur m machines au total
Sélectionnez
duree_fabrication = (n-1)*duree_max + duree_total

La fonction VBA mise en œuvre pour ce calcul est la suivante :

Fonction donnant la date et l'heure de fin du processus
Sélectionnez
Public Function fin_process(ByVal nbre As Long, ByVal debut As Date, ByVal Horaire_Debut, ByVal Horaire_Fin, ByVal Creneau As Integer) As Date
' date et heure de fin du process en fonction du nombre de pièces, de la date de début du process, 
' des heures de début et de fin dans la journée et du créneau horaire.
Dim rs As DAO.Recordset
Dim leSql As String
Dim d As Long, d1 As Long, d2 As Long
Dim dt As Date
Dim j As Integer
Dim m As Long

' requête affichant la durée totale du process en se basant sur la formule (n-1)*duree_max + duree_total.
leSql = "SELECT " & (nbre - 1) & "*Max([Duree])+Sum([Duree]) AS durée " & _
"FROM T_Machine;"

' le jeu d'enregistrement correspondant.
Set rs = CurrentDb.OpenRecordset(leSql, dbOpenForwardOnly)

' la durée totale.
d = rs!durée

rs.Close
Set rs = Nothing

d1 = DateDiff("s", TimeValue(debut), Horaire_Fin)

   If d <= d1 Then ' si compris dans l'intervalle.
      fin_process = DateAdd("s", d, debut)
      
   Else ' sinon on décompose la durée.
   
      d = d - d1
      dt = CDate(Format(debut + 1, "dd/mm/yyyy") & " " & Format(Horaire_Debut, "hh:nn"))
      m = DateDiff("s", Horaire_Debut, Horaire_Fin)
      j = d \ m
      dt = DateAdd("d", j, dt)
      dt = DateAdd("s", d Mod m, dt)
      
      fin_process = dt
      
   End If

' renvoie la date et l'heure de fin du process.
fin_process = DateAdd("s", (Creneau * 60), fin_process)

End Function

VII. Le formulaire de simulation

Nous allons décrire le formulaire qui présente la simulation du process sur les différentes machines de la gamme de fabrication.

Image non disponible
Aperçu du formulaire de simulation

Le programme permet de visualiser pour chaque tranche horaire le plan de charge de toutes les machines.

VII-A. La zone de liste affichant les horaires

Sur la partie gauche du formulaire se trouve une zone de liste qui affiche l'ensemble des tranches horaires prises en compte dans la simulation du process. Elles sont sous la forme Jour/Heure.

VII-B. Le graphique pour afficher la charge des machines

Sur la plus grande partie du formulaire se trouve le graphique qui affiche le plan de charge des machines dont voici le SQL :

Code SQL du graphique placé sur le simulateur
Sélectionnez
PARAMETERS [Forms]![F_Simuler_Process]![Nbre_Pieces] Value;
TRANSFORM First(R_Horaire_Machine_Piece.Nbre) AS First_Nbre
SELECT R_Horaire_Machine_Piece.Machine FROM R_Horaire_Machine_Piece 
GROUP BY R_Horaire_Machine_Piece.Machine
PIVOT R_Horaire_Machine_Piece.Machine In ("M1","M2","M3","M4","M5","M6","Total fait");

VIII. Téléchargement

Pour faciliter les tests et assurer sa portabilité, la base exemple n'utilisera pas de composants externes à Access (ActiveX ou autres).

La base exemplesimuler_process est au format Access 2000.

IX. Remerciements

Un grand Merci à toute l'équipe de Dvp et plus particulièrement à :

Pour ses remarques et conseils avisés :
. claudeleloup

Pour leur relecture :
. claudeleloup
. franouch
. Oppenheimer

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Copyright © 2015 Denis Hulo. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.