Erstellen einer angepassten Arbeitsgangkalkulation

Sie haben die Möglichkeit, zur Berechnung der Dauer ausgewählter Arbeitsgänge eine angepasste, in C programmierte Routine für APS zu schreiben. Das System ruft Ihre angepasste Berechnungsroutine auf, wenn das Feld Individuelle Planregel aktiviert ist.

Informationen über die Standardroutine für die Berechnung von Arbeitsgängen

Die Standardroutine für die Berechnung von Arbeitsgängen lautet ol_opercalc. Sie gibt standardmäßig den Wert -1,0 zurück, wodurch der Algorithmus angewiesen wird, die Arbeitsgangdauer unter Verwendung der Standardmethode (und nicht der angepassten Methode) zu berechnen. Im Folgenden sehen Sie den C-Code für diese Routine.


#include "ol_api.h"
double
ol_opercalc(opercalc)
opercalc_s* opercalc;
{
return(-1.0);
}

Eingabe in die Standardroutine

Die Eingabe in ol_opercalc besteht aus einem Zeiger auf eine opercalc_s-Struktur. Wie im Folgenden dargestellt, enthält diese Struktur die für die Berechnung der Arbeitsgangdauer verwendeten Informationen.


/*------------------------------------------------------------------------*/
typedef struct attid_struct
/*------------------------------------------------------------------------*/
{
 char                   attid[MAX_OLXFSTR+1];
 char                           attvalue[MAX_OLXFSTR+1];
}
attid_s;
/*------------------------------------------------------------------------*/
typedef struct reslist_struct
/*------------------------------------------------------------------------*/
{
 char                   resource[MAX_OLXFSTR+1];
 char                   category[MAX_OLXFSTR+1];
 double                 catbufpre;
 double                 catbufpost;
 long                   numresattids;
 attid_s**      resattidlist;
}
reslist_s;
/*------------------------------------------------------------------------*/
typedef struct opercalc_struct
/*------------------------------------------------------------------------*/
{
 char                                   operation[MAX_OLXFSTR+1];
 char                           order[MAX_OLXFSTR+1];
 char                           part[MAX_OLXFSTR+1];
 double                         quantity;
 char                           startwindow[14];
 char                           endwindow[14];
 long                           oprflags;
 double                         oprsetup;
 double                         oprcycle;
 double                         oprbufpre;
 double                         oprbufpost;
 long                           oprovltype;
 double                         oprovlvalue;
 long                                   matltag;
 long                           numresources;
 reslist_s**    resourcelist;
 long                           numoprattids;
 attid_s**              oprattidlist;
 long                           numordattids;
 attid_s**              ordattidlist;
 long                           numprtattids;
 attid_s**              prtattidlist;
}
opercalc_s;

Ausgabe aus der Standardroutine

Es gibt zwei verschiedene Ausgabetypen aus ol_opercalc:

  • Den Rückgabewert der Funktion. Der erwartete Rückgabewert aus ol_opercalc entspricht entweder der Gesamtdauer des Arbeitsgangs in Stunden (vom Typ "double") oder dem Wert -1,0 (bzw. einem anderen negativen Wert). Ein negativer Wert weist das System zur Verwendung der Standardberechnungsmethode (und nicht der angepassten Methode) an.
  • Einen aus drei Parametern bestehenden Satz. Diese Parameter sind Teil der opercalc_s-Struktur:
    • oprsetup - Rüstzeit des Arbeitsgangs (Stunden)
    • oprovltype - Überlappungstyp des Arbeitsgangs
    • oprovlvalue - Überlappungswert des Arbeitsgangs

Werden diese Parameter durch den Algorithmus an ol_opercalc übergeben, dann enthalten Sie die anwenderspezifischen Werte aus der Datenbank. Sie können sie vor der Rückgabe an den Algorithmus innerhalb von ol_opercalc ändern. Anschließend führt das System folgende Aktionen durch:

  • oprsetup - Die Rüstzeit für diesen Arbeitsgang wird geändert.
  • oprovltype - Der Überlappungsversatz für diesen Arbeitsgang wird neu berechnet.
  • oprovlvalue - Der Überlappungsversatz für diesen Arbeitsgang wird neu berechnet.

Sie können die Arbeitsgangüberlappung über die Originalwerte aus der Datenbank oder durch Ändern des oprovltype-Werts aktivieren. Wenn die Option aktiviert ist, der oprsetup-Wert geändert wird und/oder der Rückgabewert von ol_opercalc auf einen anderen aktiven oprcycle-Wert hinweist (unter Berücksichtigung der für die Felder Fest geplante Stunden und Individuelle Planregel des Arbeitsgangs gewählten Einstellungen), berechnet das System den Überlappungsversatz für diesen Arbeitsgang neu.

Erstellen einer angepassten Routine

Vergewissern Sie sich bei der Erstellung einer angepassten Routine, dass der Rückgabewert dem Typ "double" entspricht. Der Rückgabewert muss der erforderlichen Gesamtdauer des Arbeitsgangs (in Stunden) entsprechen, die während des für die Produktion zur Verfügung stehenden Zeitintervalls für die festgelegte Anzahl von Teilen gilt, welche die angegebenen Ressourcen verwenden.

Anhand der folgenden ol_opercalc-Beispielroutine kann die Arbeitsgangzeit für eine bestimmte Ressource ermittelt werden.


#include "ol_api.h"
double
ol_opercalc(opercalc)
opercalc_s* opercalc;
{
    FILE* log_fp;
    int i,j;
 double dTime;
   log_fp = fopen("d:\\opercalc50.txt","a");
  fprintf(log_fp,
                "\nopercalc:  oper=>%s&LT\n",
                opercalc->operation );
        fflush(log_fp);
  fprintf(log_fp,
                "opercalc:  numoprattids=%d\n",
                opercalc->numoprattids );
        fflush(log_fp);
  for (i=0;i&LTopercalc->numoprattids;i++)
        {
   fprintf(log_fp,
    "opercalc:  opr attid   =>%s&LT\n"
    "opercalc:  opr attvalue=>%s&LT\n",
                opercalc->oprattidlist[i]->attid,
    opercalc->oprattidlist[i]->attvalue );
            fflush(log_fp);
        }
  fprintf(log_fp,
                "opercalc:  order=>%s&LT\n",
                opercalc->order );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  numordattids=%d\n",
                opercalc->numordattids );
        fflush(log_fp);
  for (i=0;i&LTopercalc->numordattids;i++)
        {
   fprintf(log_fp,
                "opercalc:  ord attid   =>%s&LT\n"
    "opercalc:  ord attvalue=>%s&LT\n",
                opercalc->ordattidlist[i]->attid,
    opercalc->ordattidlist[i]->attvalue );
            fflush(log_fp);
        }
  fprintf(log_fp,
                "opercalc:  part=>%s&LT\n",
                opercalc->part );
        fflush(log_fp);
  fprintf(log_fp,
                "opercalc:  numprtattids=%d\n",
                opercalc->numprtattids );
        fflush(log_fp);
  for (i=0;i&LTopercalc->numprtattids;i++)
        {
   fprintf(log_fp,
          "opercalc:  prt attid   =>%s&LT\n"
    "opercalc:  prt attvalue=>%s&LT\n",
                opercalc->prtattidlist[i]->attid,
    opercalc->prtattidlist[i]->attvalue );
            fflush(log_fp);
        }
        fprintf(log_fp,
                "opercalc:  quantity=%f\n",
                opercalc->quantity );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  start=>%s&LT\n",
                opercalc->startwindow );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  end=>%s&LT\n",
                opercalc->endwindow );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprflags=%d\n",
                opercalc->oprflags );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprsetup=%f\n",
                opercalc->oprsetup );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprcycle=%f\n",
                opercalc->oprcycle );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprbufpre=%f\n",
                opercalc->oprbufpre );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprbufpost=%f\n",
                opercalc->oprbufpost );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprovltype=%d\n",
                opercalc->oprovltype );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  oprovlvalue=%f\n",
                opercalc->oprovlvalue );
        fflush(log_fp);
        fprintf(log_fp,
                "opercalc:  numresources=%d\n",
                opercalc->numresources );
        fflush(log_fp);
  for (i=0;i&LTopercalc->numresources;i++)
        {
   fprintf(log_fp,
                "opercalc:  resource=>%s&LT\n",
                opercalc->resourcelist[i]->resource );
            fflush(log_fp);
   fprintf(log_fp,
                "opercalc:  category=>%s&LT\n",
                opercalc->resourcelist[i]->category );
            fflush(log_fp);
            fprintf(log_fp,
                    "opercalc:  catbufpre=%f\n",
                    opercalc->resourcelist[i]->catbufpre );
            fflush(log_fp);
            fprintf(log_fp,
                    "opercalc:  catbufpost=%f\n",
                    opercalc->resourcelist[i]->catbufpost );
            fflush(log_fp);
      fprintf(log_fp,
                    "opercalc:  numresattids=%d\n",
                    opercalc->resourcelist[i]->numresattids );
            fflush(log_fp);
      for (j=0;j&LTopercalc->resourcelist[i]->numresattids;j++)
            {
       fprintf(log_fp,
        "opercalc:  res attid   =>%s&LT\n"
        "opercalc:  res attvalue=>%s&LT\n",
                    opercalc->resourcelist[i]->resattidlist[j]->attid,
        opercalc->resourcelist[i]->resattidlist[j]->attvalue );
                fflush(log_fp);
            }
        }
  dTime = -1.0;
  if ( (!strcmp(opercalc->part,"SA-50910")) &&
    (!strcmp(opercalc->operation,
             "SA-50910                      SA-5.20")) &&
    (!strcmp(opercalc->resourcelist[0]->resource,"PNT10.1")) )
  {
   if ( opercalc->oprflags == 2 )
            {
    fprintf(log_fp, "opercalc:  per cycle\n");
    fflush(log_fp);
    if ( opercalc->quantity > 10.0 )
    {
        opercalc->oprsetup = 0.15;
     fprintf(log_fp, "opercalc:  changing oprsetup\n");
     opercalc->oprcycle = 0.25;
     fprintf(log_fp, "opercalc:  changing oprcycle\n");
     opercalc->oprovltype = 1;
     fprintf(log_fp, "opercalc:  changing oprovltype\n");
     opercalc->oprovlvalue = opercalc->quantity / 2;
     fprintf(log_fp, "opercalc:  changing oprovlvalue\n");
     opercalc->oprbufpre = opercalc->quantity / 2;
     fprintf(log_fp, "opercalc:  changing oprbufpre to qty/2=%f\n",
                        opercalc->oprbufpre);
     opercalc->oprbufpost = opercalc->quantity / 4;
     fprintf(log_fp, "opercalc:  changing oprbufpost to qty/4=%f\n",
                        opercalc->oprbufpost);
//     dTime = opercalc->oprcycle * opercalc->quantity;
     fflush(log_fp);
    }
            }
   else
            {
    fprintf(log_fp, "opercalc:  per load\n");
    fflush(log_fp);
    dTime = 1.0;
                /* opercalc->oprsetup = 0.0;
                opercalc->oprcycle = 0.1;
                opercalc->oprovltype = 1;
                opercalc->oprovlvalue = 3.0; */
            }
  }
  fprintf(log_fp, "opercalc:  dTime = >%f&LT\n", dTime );
        fflush(log_fp);
  fclose(log_fp);
  return(dTime);
}

Aufrufen der angepassten Routine

Bei der Ausführung von APS wird Ihre angepasste Routine nur dann verwendet, wenn das Feld JOBSTEP.STEPTMRL des Arbeitsgangs auf 2 (Individuelle Planregel ist aktiviert, Fest geplante Stunden enthält einen Wert) oder 3 (Individuelle Planregel ist aktiviert, Fest geplante Stunden ist leer oder enthält den Wert 0) eingestellt ist. In einem Arbeitsgang, dessen Feld STEPTMRL den Wert 2 enthält, wird eine fixe Bearbeitungszeit verwendet; enthält das Feld den Wert 3, wird eine Bearbeitungszeit pro Stück verwendet.

Wenn die individuelle Planregel deaktiviert ist, ruft das System die angepasste Routine ol_opercalc nicht auf.