[gelöst]Lagerplatzpostenabfrage beschleunigen

24. Juni 2016 07:19

Hallo,

ich habe folgenden Programmteil, der meiner Meinung nach viel zu langsam ist. Leider weiß ich nicht wie ich es besser machen könnte.

Code:

SummeLager := 0;
EKDeckProdPlanungszeilen.SETRANGE(Artikelkategoriecode,'DECKLAGEN');  //Anzahl der Datensätze sind hier 870
IF EKDeckProdPlanungszeilen.FINDSET THEN BEGIN
  REPEAT
    VerbrArtikelStückliste.RESET;
    VerbrArtikelStückliste.SETRANGE("Artikel Nr.",EKDeckProdPlanungszeilen.Artikelnr);
    IF VerbrArtikelStückliste.FINDSET THEN BEGIN   //Anzahl der Datensätze sind hier 2544
      REPEAT       
        WarehouseEntry.RESET;
        WarehouseEntry.SETRANGE("Location Code",'XXX');
        WarehouseEntry.SETRANGE("Bin Code",'451');
        WarehouseEntry.SETRANGE("Item No.",VerbrArtikelStückliste."Verbr. Artikel Nr.");
        //WarehouseEntry.SETRANGE("Quantity Bin",0.01,10000000);
        IF WarehouseEntry.FINDSET THEN BEGIN    //Anzahl der Datensätze sind hier 11891
          REPEAT
            WarehouseEntry.CALCFIELDS("Quantity Bin");
            IF WarehouseEntry."Quantity Bin" > 0 THEN BEGIN
              i += 1;
              SummeLager += WarehouseEntry.Quantity;
            END;
          UNTIL WarehouseEntry.NEXT = 0;
        END;
      UNTIL VerbrArtikelStückliste.NEXT = 0;
    END;

    EKDeckProdPlanungszeilen.EKDecklagerbestandNacharbeit := SummeLager;
    EKDeckProdPlanungszeilen.MODIFY;
    SummeLager := 0;
   
  UNTIL EKDeckProdPlanungszeilen.NEXT = 0;
END;


Wenn ich die Variante mit WarehouseEntry.SETRANGE("Quantity Bin",0.01,10000000) mache und den Code IF WarehouseEntry."Quantity Bin" > 0 THEN BEGIN entferne braucht die Berechnung ca. 4 Minuten.
Wenn ich es ausführe wie aktuell der Code ist, da benötigt die Ausführung ca. 2 Minuten.
Das Feld "Quantity Bin" wurde von uns hinzugefügt und ist ein FlowField mit folgende Eigenschaft: Sum("Warehouse Entry".Quantity WHERE (Item No.=FIELD(Item No.),Location Code=FIELD(Location Code),Lot No.=FIELD(Lot No.),Bin Code=FIELD(Bin Code)))

Der Sinn dieses Codes sollte sein, alle Chargen zu finden, welche noch von einen best. Artikel auf dem Lagerort XXX und dem Lagerplatz 451 sind.

lg
stony
Zuletzt geändert von stony am 24. Juni 2016 10:32, insgesamt 1-mal geändert.

Re: Lagerplatzpostenabfrage beschleunigen

24. Juni 2016 08:17

Moin stony,
du solltest, solange es sich nicht vermeiden lässt, niemals Flowfields Filtern. Das ist sehr langsam.

Du kannst nach der Filterung der Warehouse Entries einfach ein:

Code:
WarehouseEntry.CALCSUMS("Quantity Bin");
SummeLager := WarehouseEntry."Quantity Bin";


So sparst du dir die Schleife und die Geschwindigkeit sollte auch besser sein.


Microsoft Dynamics NAV Documentation
CALCSUMS Function (RECORD)

Calculates the total of a column of SumIndexFields in a C/SIDE table. Using parameters, you can specify which fields to calculate.


[Ok :=] Record.CALCSUMS (Field1, [Field2],...)



Parameters
Record
Type: Record

The record that contains the SumIndexFields that you want to calculate.

Field1, Field2, …
Type: Decimal

The fields that you want to calculate. Each field is a decimal field, defined as a SumIndexField, in the current key.

Collapse imageProperty Value/Return Value
Type: Boolean

If you omit this optional return value and if one of the fields is not a SumIndexField, a runtime error occurs. If you include a return value, you must handle any errors.

Collapse imageRemarks
Use this function to total columns in a table. This function operates only on records that meet the conditions of any filters associated with the record.

Collapse imageExample
This example shows how to use the CALCSUMS function.

CopyCode imageCopy Code
"Cust. Ledger Entry".SETCURRENTKEY("Customer No.","Date");
"Cust. Ledger Entry".SETRANGE("Customer No.", 'AAA 1050');
"Cust. Ledger Entry".SETRANGE("Date", 010196D, 123196D);
"Cust. Ledger Entry".CALCSUMS("Amount");


The first line selects a key. The second and third lines set filters for the fields Customer No. and Date in the Cust. Ledger Entry record so the total is only calculated within the specified range. The CALCSUMS function then finds the net change in account AAA 1050 for 1996. The Amount field will show the result of the calculation.

Re: Lagerplatzpostenabfrage beschleunigen

24. Juni 2016 08:45

Ich würde dafür eine Query erstellen. Dort aber bitte auch immer die zugrunde liegenden Tabellen verwenden und nicht auf FlowFields filtern.

Re: Lagerplatzpostenabfrage beschleunigen

24. Juni 2016 08:49

SilverX hat geschrieben:Ich würde dafür eine Query erstellen. Dort aber bitte auch immer die zugrunde liegenden Tabellen verwenden und nicht auf FlowFields filtern.

Korrekt. Vergiss was ich vorher geschrieben habe. Query wird am schnellsten sein.

Re: Lagerplatzpostenabfrage beschleunigen

24. Juni 2016 09:27

Hallo,

ich habe folgenden Programmteil, der meiner Meinung nach viel zu langsam ist.


Oft hilft es die richtigen Fragen zu stellen. :mrgreen:

Wenn Ihr mit Logistik arbeitet, gibt es die Tabelle Lagerplatzinhalt (Bin Content), dort ist für jeden Artikel und Lagerplatz mit Inhalt bzw. festen Lagerplatz ein Eintrag enthalten. Du hast also eine Tabelle wo nur Einträge drin sind, wo der Artikel wirklich liegt, bzw. wenn definiert, liegen könnte.
1. Abfrage gibt es Bin Content (mit Get abfragen)? Wenn nein, dann auch kein Bestand auf diesem Lagerplatz.
2. Frage, wenn es Bin Content gibt, dann Bin Content mit Flowfilter "Lot No. Filter" abfragen und calcfields auf "Quantity", wenn 0, dann kein Bestand auf diesem Lagerplatz.

Wenn Ihr nicht mit festen Lagerplätzen arbeitet, sollte das dein Programm erheblich beschleunigen.

P.S.:
1. Wenn du nur den Bestand des Artikels wissen möchtest, lässt du den FlowFilter auf "Lot No. Filter" einfach weg.
2. Den Bestand auf einem Lagerplatz findest du normalerweise in der "Bin Content" und nicht auf einem wie auch immer programmierten Flowfield in der "Warehouse Entry".

Ursache für die langsame Abfrage:

Wenn du die Abfrage so durchführst, berechnest du für jede Artikelbewegung im Logistischen Lager den Lagerplatzinhalt. Da NAV für jede Artikelbewegung einen Posten schreibt, können das auch auf einem Lagerplatz schon mal ein paar tausend Posten sein. Für jeden dieser Posten berechnest du jetzt den Lagerplatzinhalt, der jetzt wieder alle Lagerplatzposten aufsummiert, die zu diesem Lagerplatz gehören, du erzeugst also "Anzahl Lagerplatzposten" zum Quadrat Zugriffe. Das führt sicherlich nicht zu einer Beschleunigung des ganzen.
Also: Das Feld "Quantity Bin" hat nichts in der Tabelle "Warehouse Entry" zu suchen, dafür gibt es die "Bin Content", oder du summierst die "Warehouse Entry" direkt auf (Ohne Flowfield), wenn du wissen möchtest, ob der Artikel da schon mal gelegen hat :!:

Gruß Fiddi

Re: Lagerplatzpostenabfrage beschleunigen

24. Juni 2016 09:48

Ok, fiddi sticht uns aus ;-)

Re: [gelöst]Lagerplatzpostenabfrage beschleunigen

26. Juni 2016 17:27

...außerdem sehe ich kein SETCURRENTKEY im Code.

Re: [gelöst]Lagerplatzpostenabfrage beschleunigen

26. Juni 2016 21:36

enh hat geschrieben:...außerdem sehe ich kein SETCURRENTKEY im Code.

Ist nicht mehr nötig. Der SQL Server sucht sich selbst den performantesten Index raus. SETCURRENTKEY ist nur noch relevant, wenn du die Daten in einer bestimmten Sortierung benötigst.

Re: [gelöst]Lagerplatzpostenabfrage beschleunigen

27. Juni 2016 08:00

Ist nicht mehr nötig. Der SQL Server sucht sich selbst den performantesten Index raus


In den meisten Fällen ist das tatsächlich so, aber auch hier kann es Ausnahmen geben. Deshalb könnte es als letztes Mittel immer noch nötig sein.

Hier war das aber nicht das Problem.


Gruß Fiddi