Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Lagerreichweite und Fertigungsauftragsendtermin Berechnung (https://www.delphipraxis.net/128927-lagerreichweite-und-fertigungsauftragsendtermin-berechnung.html)

Ykcim 9. Feb 2009 17:08

Datenbank: MySQL • Version: 5 • Zugriff über: C-Api

Lagerreichweite und Fertigungsauftragsendtermin Berechnung
 
Hallo Zusammen,

ich hoffe, dass mir hier jemand helfen kann...

Ich bin alles andere als erfahren, sodass ich auf detailliertere Antworten angewiesen bin...

Ich mochte berechnen, wie weit mein Lagerbestand reicht und wann welcher Fertigungsauftrag beendet sein muss. Dazu habe ich folgende Tabellen:

ERP1
ArtikelNr, Artikelbez, FertigungsauftragsNR, FertigungsauftragsNR Zusatz, Arbeitsgang, Fertigungsmenge, Rückmeldung
10004711....Brot, hell.........10815...............0000............. ...........10..........10.000..........9
10004711....Brot, hell.........10815...............0000............. ...........20..........10.000..........9
10004711....Brot, hell.........10815...............0000............. ...........30..........10.000..........9
10004711....Brot, hell.........10815...............0000............. ...........40..........10.000..........9
10004711....Brot, hell.........10815...............0000............. ...........50..........10.000..........
10004711....Brot, hell.........10815...............0000............. ...........60..........10.000..........
10004711....Brot, hell.........10815...............0000............. ...........70..........10.000..........
10004711....Brot, hell.........10819...............0000............. ...........10..........10.000..........9
10004711....Brot, hell.........10819...............0000............. ...........20..........10.000..........9
10004711....Brot, hell.........10819...............0000............. ...........30..........10.000..........
10004711....Brot, hell.........10819...............0000............. ...........40..........10.000..........
10004711....Brot, hell.........10819...............0000............. ...........50..........10.000..........
10004711....Brot, hell.........10819...............0000............. ...........60..........10.000..........
10004711....Brot, hell.........10819...............0000............. ...........70..........10.000..........
10004712....Brot, rot..........10818...............0000............. ...........10..........18.000..........9
10004712....Brot, rot..........10818...............0000............. ...........20..........18.000..........9
10004712....Brot, rot..........10818...............0000............. ...........30..........18.000..........9
10004712....Brot, rot..........10818...............0000............. ...........40..........18.000..........9
10004712....Brot, rot..........10818...............0000............. ...........50..........18.000..........9
10004712....Brot, rot..........10818...............0000............. ...........60..........18.000..........
10004712....Brot, rot..........10818...............0000............. ...........70..........18.000..........

Ich möchte das bei einer Abfrage immer nur der erste Arbeitsgang gezeigt wird, der nicht mit 9 als fertig gekennzeichnet ist. Aber zu der Abfrage später noch mehr...

Nächste Tabelle
Lager
ArtikelNr, Lagerbestand
10004711....25.000
10004712....30.000

Und die letzte Tabelle
Kundenbedarf
ArtikelNr, Kunde, Kundenbedarf, Lieferdatum
10004711....54........5.000.......20090312
10004711....56........4.000.......20090312
10004711....58........7.000.......20090318
10004711....54........13.000.......20090320
10004711....54........25.000.......20090329
10004712....54........15.000.......20090312
10004712....54........5.000.......20090412
10004712....56........5.000.......20090318


Ich möchte eine Abfrage haben, in der ich folgende Ergebnisse bekomme
1.
ArtikelNr, Artikelbezeichnung, Kundenummer, Kundenbedarf, Lieferdatum, Fertigungsauftragsnummer, Fertigungsmenge, Lagerbestand(25.000)
10004711.......Brot, hell.........54............5.000........20090312.. ..............................................20.0 00
10004711.......Brot, hell.........56............4.000........20090312.. ..............................................16.0 00
10004711.......Brot, hell.........58............5.000........20090318.. ..............................................9.00 0
10004711.......Brot, hell.........54............13.000.......20090320.. ..............................................7.00 0
10004711.......Brot, hell.........54............15.000.......20090329.. ............10815.............10.000..........2.00 0



2.
ArtikelNr, Artikelbezeichnung, Fertigungsauftrag,......................... wann er beendet sein muss(Datum), ........................Arbeitsgang
10004711.........Brot, hell......Der mit dem höchsten Arbeitsgang als fertig gemeldet..........wenn der Lagerbestand durch null läuft....der nächste anstehende Arbeitsgang
.................................................. ...10815.......................................... ................................20090329.......... .........................50

Ich hoffe, es ist verständlich geworden, was ich brauche... Kann mir dabei jemand helfen?

Vielen Dank!

[edit=Phoenix]Post geprüft zwecks RSS-Problem. Mfg, Phoenix[/edit]

Ykcim 10. Feb 2009 16:12

Re: Lagerreichweite und Fertigungsauftragsendtermin Berechnu
 
Schade, offensichtlich weiß hier niemand eine Lösung... :(

Kann mir denn jemand sagen, ob ich abwärt kumulieren kann.

Heiß also, das ich einen Lagerbestand von 50.000 über eine subquery ermittel und dann in Spalte A2 den Lagerbestand -den Bedarf aus A1 ausgebe.

Lager bestand: 50.000

...A1......A2...
.10.000..40.000.
.15.000..25.000.
..5.000..20.000.
und so weiter

Danke

Ykcim 12. Feb 2009 08:27

Re: Lagerreichweite und Fertigungsauftragsendtermin Berechnu
 
So sieht die Lösung aus. Ich habe es noch etwas erweitert, dass die varhandenen Fertigungsaufträge ausgegeben werden und das erforderliche Fertigstellungsdatum abhängig von Kundenbedarf und Fertigungsauftragsmenge...

Es war mir nicht möglich, das ganze auf dem MySQL-Server zu lösen, sondern nur in dem Delphi-Programm...

Delphi-Quellcode:
procedure TTest3.LagerzugangClick(Sender: TObject);
var query, query1, query2 : string;
    Cols, Cols1, Cols2 : TCols;
    Rows, Rows1, Rows2 : TRows;
    i, j :integer;
begin
//Lagerbestand
query:= 'select sum(lslgbe)from oms14 '+
        'where watenr=10013054';
unit1.connect;
unit1.ExecQuery(DB, query, cols, Rows);
//======================================}
//Kundenbedarf
query1:= 'select watenr, ltbdmg, DATE_FORMAT(ltlite,'+#39+'%d.%m.%Y'+#39+'), ltbdmg*0 as kumuliert from omslp '+
          'where watenr=10013054 '+
          'order by ltlite';
unit1.ExecQuery(DB, query1, cols1, Rows1);
//======================================}
//Fertigungsaufträge
query2:= 'Select WAAUNR as FA_Nr, WATENR as ArtikelNr, TEBEZ1 as Bezeichnung, OAAGNR as AG, OAAGBZ as Arbeitsgang, '+
          'OAAGNR*0 as Lagerzugang, WAFEMG from as400 '+
          'where OATLKZ <> 9 and WATENR=10013054 '+
          'GROUP BY WATENR, WAAUNR '+
          'ORDER BY WATENR, OAAGNR DESC';
unit1.ExecQuery(DB, query2, cols2, Rows2);
//======================================}
//Lagerzugangsdatum
i:=0; j:=0;
rows1[3,i]:=inttostr(strtoint(rows[0,0])-strtoint(rows1[1,0]));
for i := 1 to length(rows1[0]) - 1 do
  begin
    rows1[3,i]:=inttostr(strtoint(rows1[3,i-1])-strtoint(rows1[1,i]));
    if (strtoint(rows1[3,i])<0) and (strtoint(rows1[3,i-1])>=0) then
      begin
            while (strtoint(rows1[3,i])<0) and (j<length(rows2[0])) do
              begin
                //Lieferdatum zu FA
                rows2[5,j]:=rows1[2,i];
                //Fertigungsmenge zu rows1[3,i] addieren
                rows1[3,i]:=inttostr(strtoint(rows1[3,i])+strtoint(rows2[6,j]));
                // j+1
                j:=j+1;
              end;
      end;
  end;
unit1.disconnect;
//======================================}
//Datenausgabe
unit1.FillGrid(StringGrid5, Cols2, Rows2);
end;
Das ist die ExecQuery:

Delphi-Quellcode:
function ExecQuery(const Datenbank, query: string; var Cols: TCols; var Rows: TRows): Boolean;
var
   MySQLRes: PMYSQL_RES;
   MySQLRow: PMYSQL_ROW;
   AffectedRows: Int64;
   ColCount: Cardinal;
   Field: PMYSQL_FIELD;
   i: Integer;
   j: Integer;
   ErrorCode: Integer;
begin
   // Datenbank auswählen
   ErrorCode := mysql_select_db(_mycon, PChar(Datenbank));
   if ErrorCode = 0 then
   begin
     // Query ausführen
     ErrorCode := mysql_real_query(_mycon, PChar(query), length(query));
     if ErrorCode = 0 then
     begin
       // Query speichern
       MySQLRes := mysql_store_result(_mycon);
       if Assigned(MySQLRes) then
       begin
         // zurückgelieferte Anzahl der Spalten
         ColCount := mysql_num_fields(MySQLRes);
         SetLength(Cols, ColCount);
         // Spalten-Array füllen
         for i := 0 to ColCount - 1 do
         begin
           Field := mysql_fetch_field_direct(MySQLRes, i);
           Cols[i] := Field.Name;
         end;
         // Anzahl der betroffenen Zeilen ermitteln
         AffectedRows := mysql_affected_rows(_mycon);
         SetLength(Rows, ColCount, AffectedRows);
         // neu ->
         // Zeilen-array füllen
         // alle Zeilen ...
         for j := 0 to AffectedRows - 1 do
         begin
           // ... werden eingelesen
           MySQLRow := mysql_fetch_row(MySQLRes);
           // alle Spalten ...
           for i := 0 to ColCount - 1 do
           begin
             // ... werden in Rows[] übertragen
             Rows[i, j] := MySQLRow[i];

           end;
         end;
         // gespeicherte Abfrage wieder freigeben
         {mysql_free_result(MySQLRes);}
       end
     end
   end;
   result := ErrorCode = 0;
end;
und das die Fillgrid:

Delphi-Quellcode:
procedure FillGrid(SG: TStringGrid; Cols: TCols; Rows: TRows);
var
  i, j: Integer;
begin
  SG.ColCount := 0;
  SG.RowCount := 0;
  if Assigned(Rows) then
  begin
    // Wir brauchen eine Zeile mehr für die Spaltenüberschriften
    SG.RowCount := length(Rows[0]) + 1;
    SG.ColCount := length(Cols);
    SG.FixedRows := 0;
    // Spaltenüberschriften in die erste Zeile schreiben
    for i := 0 to length(Cols) - 1 do
    begin
      SG.Cols[i].Add(Cols[i]);
      SG.Cells[i, 0] := Cols[i];
    end;
    // zwei-dimensionales Zeilen-Array in den Zellen ausgeben
    for i := 0 to length(Cols) - 1 do
    begin
      for j := 0 to length(Rows[0]) - 1 do
      begin
        SG.Cells[i, j + 1] := Rows[i, j];
      end;
    end;
  end;
end;

omata 12. Feb 2009 23:58

Re: Lagerreichweite und Fertigungsauftragsendtermin Berechnu
 
Leider sind in deinen Angaben einfach zu viele Fragen offen oder Daten fehlerhaft. Deshalb hatte ich nicht wirklich Lust, mich da dran zu setzen, sorry. Wie sehen z.B. deine Tabellen-Contraints aus? Deine Beispieldaten enthalten Fehler. Deine Wunschausgabe ist leider zu kurz, da kann man nicht richtig erkennen was du da eigentlich machen willst. Textuell hast du da leider auch nichts zu geschrieben. Dir ist das alles klar, einem unbeteiligten leider nicht.
Da muss man dann nachfragen und ich muss gestehen, dass ich da damals nur einen kurzen Blick draufgeworfen hatte und dann war das Thema für mich nicht mehr interessant. Da einfach zu viel nachgefragt werden müsste.

Wie auch immer, du hast ja eine Lösung. Vielleicht geht es auch direkt auf dem Server, allerdings sind dafür einfach zu viele Fragen offen, die ich hier jetzt/und damals nicht stellen will/wollte.

Sorry.

Helfe uns in Zukunft, dir zuhelfen, indem du uns vollständig erklärst, was du eigentlich haben möchtest. Das hast du im Prinzip ja auch gemacht, versuche nächstes mal einfach präziser zu sein.

sx2008 13. Feb 2009 00:42

Re: Lagerreichweite und Fertigungsauftragsendtermin Berechnu
 
Du kommentierst deinen Sourcecode nicht richtig.
Beispiel:
Delphi-Quellcode:
// zurückgelieferte Anzahl der Spalten
ColCount := mysql_num_fields(MySQLRes);
Der Kommentar wiederholt genau das, was man aus dem Sourcecode schon entnehmen kann.
Das bringt keine Zusatzinformation.
Beispiel 2:
Delphi-Quellcode:
//Lagerbestand
query:= 'select sum(lslgbe)from oms14 '+
        'where watenr=10013054';
Ok, es geht um den Lagerbestand. Aber warum steht da die ominöse Zahl 10013054?
DAS sollte doch im Kommentar erklärt werden, denn niemand ausser Dir weiss was 10013054 bedeutet.
Für magische Zahlen und String sollte man Konstanten verwenden:
Delphi-Quellcode:
const ARTIKEL_GRUPPE_ALTES_MATERIAL = '10013054';
...
query:= 'select sum(lslgbe)from oms14 where watenr='+ARTIKEL_GRUPPE_ALTES_MATERIAL;
Beispiel 3:
Delphi-Quellcode:
i:=0; j:=0;
rows1[3,i]:=inttostr(strtoint(rows[0,0])-strtoint(rows1[1,0]));
for i := 1 to length(rows1[0]) - 1 do
  begin
    rows1[3,i]:=inttostr(strtoint(rows1[3,i-1])-strtoint(rows1[1,i]));
    if (strtoint(rows1[3,i])<0) and (strtoint(rows1[3,i-1])>=0) then
      begin
            while (strtoint(rows1[3,i])<0) and (j<length(rows2[0])) do
Aaaahhrgh! Das nenn' ich mal Spaghetticode.
Hier solltest du unbedingt einige sprechende Zwischenvariablen verwenden:
Delphi-Quellcode:
Brutto := strtoint(rows[0,0]);   // Variablenname frei erfunden. Du weisst bestimmt besser, was rows[0,0] bedeutet
Tara  := strtoint(rows1[1,0]);
rows1[3,i]:=inttostr(Brutto-Tara);
Das ist jetzt nicht bös' gemeint, dass ich deinen Code so schlecht mache.
Soll nur helfen, es besser zu machen. :hi:

Ykcim 13. Feb 2009 10:54

Re: Lagerreichweite und Fertigungsauftragsendtermin Berechnu
 
Hallo Zusammen,

vielen Dank für die Anregungen. Und ich dachte, ich hätte es schon ausführlich beschrieben - wie man sich irren kann...

Die Kommentare sind oft für mich auch einfach nur Hilfen beim entwickeln und waren jetzt weniger als Erklärungen für das Forum gedacht - ich hatte nur keine Lust sie wieder herauszunehmen...

Die Zahl 10013054 ist eine Artikelnummer, die ich zu Testzwecken Statisch eingesetzt habe, die würde später dann natürlich variabel über ein Eingabefeld mit einfließen...

Die Rows sind die aus den drei Abfragen zurückgelieferten Daten, die ich in der Procedure dann weiterverarbeite...

Ich werde versuchen, in Zukunft eindeutiger zu sein... ;-)

Vielen Dank

Ykcim


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz