1. September 2010 16:25
Hallo,
ich möchte in einer Codeunit alle Customer zählen, die eine Rechnung haben.
Bisher verwende ich folgenden Code:
- Code:
Counter:= 0;
Customer.SETRANGE("Responsibility Center",'DE');
IF Customer.FIND('-') THEN
REPEAT
SalesInvoiceHeader.RESET;
SalesInvoiceHeader.SETRANGE("Bill-to Customer No.",Customer."No.");
IF SalesInvoiceHeader.FIND('-') THEN
Counter:= Counter + 1
UNTIL Customer.NEXT=0;
MESSAGE(FORMAT(Counter));
Der Vorgang dauert aber über eine Stunde.
Wie kann ich das beschleunigen?
Danke für die Hilfe
Zuletzt geändert von ralf5 am 3. September 2010 13:22, insgesamt 2-mal geändert.
1. September 2010 16:34
Dafür gibt es einen COUNT Befehl.
1. September 2010 16:38
Und den SetCurrentKey-Befehl.
1. September 2010 16:42
Kowa hat geschrieben:Dafür gibt es einen COUNT Befehl.
Wenn du dir die Funktion ansiehst, wirst du feststellen, das dass nicht mit count geht, oder?
1. September 2010 16:51
Versuche den Ansatz, auf die Customer einen Flowfilter (Rechnungsbuchungszeitraum) zu setzen,
anschliessend prüfen, ob Feld "Verkauf(MW)" ungleich 0 und den Zähler hochsetzen.
Das sollte eigentlich schneller sein, da nur eine Tabelle gefragt wird.
Leider kann auf das neue Feld kein Filter gesetzt werden, da es ein Flowfiled ist.
1. September 2010 16:57
Hallo McClane,
vielen Dank,
McClane hat geschrieben:Und den SetCurrentKey-Befehl.
mit SetCurrentKey gehts tatsächlich wesentlich schneller. Bisher brauche ich nur noch 4 Minuten.
Anschließend will ich in den Customer die Datensätze markieren:
Customer.Gefunden=TRUE;
Customer.MODIFY;
Kann ich das noch weiter optimieren, dass ich so auf 30 Sekunden komme?
Gruß
Ralf
1. September 2010 17:04
Customer.Mark(true) und anschließend Markedonly sparen die modifies. Ich nehme an, dass du diese Markierung nicht fest in der Datenbank brauchst.
Sonst kannst du noch in der Tabelle Customer einen Key auf das Responsibility Center definieren, aber das dürfte nicht mehr viel bringen.
1. September 2010 17:29
McClane hat geschrieben:Customer.Mark(true) und anschließend Markedonly sparen die modifies. Ich nehme an, dass du diese Markierung nicht fest in der Datenbank brauchst.
Sonst kannst du noch in der Tabelle Customer einen Key auf das Responsibility Center definieren, aber das dürfte nicht mehr viel bringen.
Leider muss ich die Markierung fest in der DB haben. Den Key auf das Responsibility Center zu setzen hat nichts gebracht.
Gruß
Ralf
1. September 2010 17:43
ralf5 hat geschrieben:Kowa hat geschrieben:Dafür gibt es einen COUNT Befehl.
Wenn du dir die Funktion ansiehst, wirst du feststellen, das dass nicht mit count geht, oder?
Die habe ich schon angesehen
. Mit einem Boolean Flowfield in Tabelle 18
- Code:
Exist("Sales Invoice Header" WHERE (Sell-to Customer No.=FIELD(No.)))
kann man auf dieses Feld filtern und dann COUNT verwenden.
Alternativ kann man auch über ein COUNT-Flowfield die Anzahl der Rechnungen pro Debitor ermitteln.
- Code:
Count("Sales Invoice Header" WHERE (Sell-to Customer No.=FIELD(No.)))
1. September 2010 18:40
@Kai
OK, also nicht nur COUNT
Habe dann auch soeben mein erstes FlowField erstellt. Geht ja ganz einfach.
Habe die Geschwindigkeit gemessen, annähernd gleich. Das Flowfield braucht 2,84 Sekunden länger.
Mensch das muss doch irgendwie schneller gehen?
Gruß
Ralf
2. September 2010 01:05
Hallo,
einen Merker für 'hat Rechnung bekommen' im Debitorenstamm per Batch- Programm zu setzen, ist keine gute Idee, denn deine Daten sind nie aktuell.
Es gibt allerdings eine Möglichkeit das ganze zu lösen. wenn du beim Buchen einer Rechnung in der CU80 das Flag beim Debitoren setzt, musst du nur noch einen Schlüssel auf diesem Flag definieren. Dann kannst du mit 'Cust.SETRANGE(Flag, true)' und Cust.Count den Wert ermitteln. Weitere Filter auf dem Customer sind dann natürlich auch noch möglich, und evtl. in den Flag- Schlüssel einzubeziehen.
Gruß, Fiddi
2. September 2010 08:20
ralf5 hat geschrieben:@Kai
OK, also nicht nur COUNT
Habe dann auch soeben mein erstes FlowField erstellt. Geht ja ganz einfach.
Habe die Geschwindigkeit gemessen, annähernd gleich. Das Flowfield braucht 2,84 Sekunden länger.
Mensch das muss doch irgendwie schneller gehen?
Gruß
Ralf
Schonmal versucht anstatt dem FIND:
- Code:
IF SalesInvoiceHeader.FIND('-') THEN
... ISEMPTY zu verwenden:
- Code:
IF NOT SalesInvoiceHeader.ISEMPTY THEN
3. September 2010 11:47
@Fiddi
Danke. Das wäre eigentlich die beste Lösung. Geht aber leider nicht, da die Abfrage zu einem Stichtag stattfinden soll und die Buchungstabellen nicht geändert werden dürfen.
@ m_schneider
ISEMTY bringt auch keine Verbesserung: Zeiten:
3 min 33,891 sec mit ISEMPTY
3 min 33,063 sec mit Find('-')
3 min 32,828 sec mit FINDFIRST
Sieht so aus, als hätte ich das minimum erreicht, oder?
3. September 2010 12:55
ralf5 hat geschrieben:Sieht so aus, als hätte ich das minimum erreicht, oder?
Yep, wenn auf einer Native - worauf du schätzungsweise arbeitest - die Schlüssel stimmen, dann ist meist nicht mehr viel zu zaubern, wenn kein grundsätzlicher Fehler in der Logik steckt. Jetzt könntest du noch einen Fortschrittsbalken einbauen, damit der Anwender sieht, dass die Kiste voran kommt. Das kostet dann allerdings wiederum etwas Zeit.
Oder an der Hardware was machen :)
3. September 2010 13:19
Na dann mal vielen Dank an
Alle für die guten Tipps.
Hat mich ein großes Stück weitergebracht.
Gruß
Ralf
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.