[Gelöst] Aufträge kennzeichnen.

7. Mai 2007 14:51

Hi,

es wird in nächster Zeit vorkommen, das bestimmte Artikel, in regelmäßigen Abständen, mit gleicher Menge, an einen Debitor verkauft werden.

z.b: Ein Debitor verpflichtet sich pro Monat XX Menge zu kaufen, oder pro Halbjahr, oder pro Jahr.

Nun soll/möchte ich eine Funktion schreiben welche diese Aufträge über eine Stapelverarbeitung rausfiltert, und als Auftrag wieder vorlegt.

Mein Vorschlag wäre, irgendein Code Feld Zweckentfremden, und dort dann die Periode der Wiedervorlage zu speichern (Code wie z.B.: 2T, 1M, 6M, 1J ...)

Meine Funktion würde dann die Gebuchten Rechnungen durchsuchen, den Code mit Buchungsdatum vergleichen, und je "fälligkeit" den Beleg kopieren, und als Auftrag wieder vorlegen.

Nun ist das mit dem Zweckentfremden aber so eine Sache, man weiß ja nie was später noch mal gebraucht werden kann.

Daher würde ich das ganze lieber über eine Zusatztabelle lösen, in der Tabelle würden dann "meine Codes" stehen, welche ich dann bei Auftragerfassung auswaehlen würde.

So haette ich aber das Problem, das ich dieses neue Code Feld, beim Buchen mit durchschleifen müsste, und ich die stellen nicht weiß wo ich die Buchungsroutine dafür ändern müsste, um dieses Feld hinzuzufügen.


Was würdet Ihr machen?

Danke
Zuletzt geändert von elTorito am 11. Mai 2007 14:47, insgesamt 1-mal geändert.

7. Mai 2007 14:56

Hi!

Hast du dir die Funktionalitäten der VK-Rahmenaufträge schon mal angeschaut? Diese - mit kleineren Anpassungen - machen genau das, was du haben möchtest.

Gruß, Marc

7. Mai 2007 17:16

Hallo,

auch ich dachte beim Lesen der Aufgabenstellung zuerst an VK-Rahmenaufträge. Im einfachsten Fall packst Du hier zwei zusätzliche Felder in den Kopf die das Datum der nächsten Ausführung sowie eine Datumsformel für die Intervallberechnung enthalten. Zusätzlich ein Mengenfeld für die Einzelauftragsmengen und die Datenstruktur sollte schon weitgehend komplett sein. Dann fehlt noch der Report, der die Aufträge automatisch erstellt oder an die manuelle Erstellung erinnert (je nachdem was gefordert/gewünscht ist).

Natürlich kannst Du das auch wie von dir geplant machen. Die Übergabe des Codefeldes ist nicht das Problem. Füge das Feld einfach in Table 36 für den Auftrag und 112 für die Geb. Rechnung mit der gleichen Feldnummer sowie dem gleichen Datentyp (inkl. Feld-Länge) ein, und das entsprechende Transferfields in der Codeunit 80 übernimmt für dich die Übergabe zwischen den Belegen. :-D

Gruß
Frank

8. Mai 2007 16:40

Frank hat geschrieben:
Natürlich kannst Du das auch wie von dir geplant machen. Die Übergabe des Codefeldes ist nicht das Problem. Füge das Feld einfach in Table 36 für den Auftrag und 112 für die Geb. Rechnung mit der gleichen Feldnummer sowie dem gleichen Datentyp (inkl. Feld-Länge) ein, und das entsprechende Transferfields in der Codeunit 80 übernimmt für dich die Übergabe zwischen den Belegen. :-D

Gruß
Frank


So werde ich das Lösen, bzw. habe schon damit angefangen.

Habe aber nun schon erste Problemchen, wollte auf das Feld "Customer Order No." filtern, und mit dem Auftragsdatum des letzten gefunden arbeiten.

Nur, wie filtere ich das ?

z.B.

SETFILTER("Customer Order No.", 'WAU*');

würde mir ausgeben:

WAU000022
WAU000022
WAU000022
WAU000022
WAU000022
WAU000044
WAU000044
WAU000044

Gab doch was um den Filter zu gruppieren oder so?

Danke!

8. Mai 2007 20:21

Code:
find('+')

Geht zum letzten Datensatz.
War es das was du suchst?

Es währe einfacher wenn du genauer Beschreiben würdest, was du machen willst bzw. was das Ziel sein soll!
Gruß Mikka

8. Mai 2007 21:03

elTorito hat geschrieben:Habe aber nun schon erste Problemchen, wollte auf das Feld "Customer Order No." filtern, und mit dem Auftragsdatum des letzten gefunden arbeiten.

Du müsstest zunächst einen Tabellenschlüssel in der Tabelle 36 anlegen. Dieser müsste so aussehen: Customer Order No.,Order Date

Dein Code vielleicht dann so:
Code:
SETCURRENTKEY("Customer Order No.","Order Date");
SETFILTER("Customer Order No.", 'WAU*');
IF FIND('+') THEN BEGIN
  ... Letztes Auftragsdatum gefunden
  ... und nun der restliche Code
END;

Gruß, Marc

9. Mai 2007 11:08

mikka hat geschrieben:
Code:
find('+')

Es währe einfacher wenn du genauer Beschreiben würdest, was du machen willst bzw. was das Ziel sein soll!
Gruß Mikka



Ich möchte alle gebuchten Rechnungen finden, welche im Feld "Customer Order No." mit einer bestimmten Zeichenfolge anfangen.

Die "Customer Order No." kann mehrfach vorkommen.

Von jede "Gruppe " mit gleicher "Customer Order No.", möchte ich den letzten Eintrag nehmen(neuste Buchungsdatum) , um dort dann anhand des Auftragsdatum + mein Zeitintervall, ausrechnen zu können, ob dieser Beleg, erneut faellig ist, um ihn dann in die Auftragstabelle zu kopieren.

Bei den gefilterten gebuchten Rechnungen sollen Belege, welche einen bestimmten Code in der Bemerkungszeile haben, nicht berücksichtig werden.

Quasi:
Filtern auf alle gebuchte RG die WAU* im Feld "Cutsomer Order No." haben. Den letzten Datensatz jeder WAU* Gruppe, prüfen ob in der Geb. rechnung ein Vermerk mit bestimmten Code in der Bemerkunsgezeile drin steht, wenn nein, auftrag kopieren, wenn ja, überspringen.

Also wenn ich folgende Zeichenfolgen habe:

WAU00001
WAU00001
WAU00001 (a)
WAU00002
WAU00002 (b)
WAU00003
WAU00003 (c)
WAU00004 (d)

Das will ich so filtern das ich a,b,c,d erhalte

9. Mai 2007 11:51

Über einen Filter direkt kann dies nicht gemacht werden. Du müsstest meiner Meinung nach über eine Schleife die Datensätze abarbeiten. In etwa so:

Code:
SETCURRENTKEY("Customer Order No.");
SETFILTER("Customer Order No.", 'WAU*');
IF FIND('-') THEN
  REPEAT
    MachIrgendWasMitDemRecord();

    //Sprung zum letzten Datensatz dieser Gruppe
    SETFILTER("Customer Order No.", "Customer Order No.");
    FIND('+');
    SETFILTER("Customer Order No.", 'WAU*');
  UNTIL (NEXT = 0);


Gruß
Frank

9. Mai 2007 11:57

vielleicht nicht unbedingt filtern, eine Möglichkeit wäre jeden Wert in eine Temptabelle einfügen, die braucht nur ein Feld vom Typ Code als Schlüssel haben. Da füllst du deinen wert rein und zwar mit

Temprec.code := auftragrec."no."
if temprec.insert then;

das sollte für eine "quasi" Gruppierung sorgen. Anschliessend durchläufst du nur noch die Temptabelle zum adressieren der eigentlichen Datensätze.

gruß aus Berlin

10. Mai 2007 13:44

Hmm.

also gehe die Sache nun etwas (denke ich) einfacher an.
Habe eine neue Tabelle erstellt, wo die wiederzukehrenden Auftraege eingetragen werden. Code = Auftragsnummer, dann Periode, Datum letzte Auftrag, Datum naechste Auftrag, und ob Auftrag gekündigt wurde oder nicht.

So kann ich diese Tabelle durchlaufen, direkt die "gekündigten" Auftraege rausfiltern, und mit der Auftragsnr der übrigen, mir die letzte gebuchte Rechnung rausfiltern. Und mit Lookup direkt alle "verknüpften" Rechnungen auflisten.

Nur ... das führt wieder zu ein Problem ;-)

Letzte Auftragsdatum rausfinden ist einfach:

FlowField mit CalcFormula:
Max("Sales Invoice Header"."Order Date" WHERE (Customer Order No.=FIELD(Code)))

Nächstes Auftragsdatum soll , das letzte Auftragsdatum + Periode sein also, quasi:

Max("Sales Invoice Header"."Order Date" WHERE (Customer Order No.=FIELD(Code))) + 6M

Wie kann ich das Datum in dem Feld berechnen ??

Danke

10. Mai 2007 13:57

Dazu brauchst du die Funktion Calcdate (Syntax in der Onlinehilfe) und eine Variable vom Typ Date zum Zwischenspeichern des Ergebnisses.

10. Mai 2007 14:09

Michael Schumacher hat geschrieben:Dazu brauchst du die Funktion Calcdate (Syntax in der Onlinehilfe) und eine Variable vom Typ Date zum Zwischenspeichern des Ergebnisses.


Danke. Das Tabellen Feld wo ich das Ergebnis darstellen möchte (Naechstes Auftragsdatum) wird dann wohl vom Typ DateFormula sein? Wo wende ich Calcdate dann an?

:oops:

10. Mai 2007 14:11

Nein, ganz normal vom Typ Date.

Durchsuch mal das Forum nach CALCDATE, dann hast du schon gute Beispiele.

10. Mai 2007 14:17

Nein Dateformula ist das Feld wo du 6M reinschreibst, also z.b. OrderInterval
Code:
NextOrderDate:=CALCDATE(OrderInterval,"Sales Invoice Header"."Order Date");

vorher musst du natürlich den letzten Auftrag in Sales Invoice Header angewählt haben.

10. Mai 2007 15:47

Tja. Also, da habt ihr mich mal wieder erwischt. :roll: :-|

Calcdate ist mir jetzt klar. Aber immer noch nicht wohin damit. Damit es beim Aufruf der Tabelle auch berechnet wird.

Für das Tabellenfeld habe ich ja nur 2 Trigger (OnValidate, OnLookup). Da komm ich nicht mit weiter. Also bliebe noch das Eigenschaft Feld, CalcFormula, oder InitValue, um die Funktion unterzubringen, was auch nicht klappt.

hmm...


Ich glaub ich bin heut mal wieder etwas schwer von "kapé" :-/

10. Mai 2007 18:14

Habe nun ein Formular erstellt, und dort im OnAfterRecord Trigger die Calcdate Funktion reingemacht.

11. Mai 2007 11:00

Das Formular hat nur den Nachteil, das wenn ich direkt in die Tabelle gucke, ich dieses neu berechnete Datum nicht sehe ... :roll: hmm

11. Mai 2007 11:08

Ja, leider lässt sich diese Anforderung nicht über CalcFields lösen. :roll:

Ich würde diese Datensätze vermutlich aktuallisieren, wenn eine Rechnung zu diesen Aufträgen gebucht wird. Dann also den entsprechenden Datensatz aufrufen, neues Auftragsdatum rein und dann über den Intervall das nächste Ausführungsdatum setzen.

Aber die beste Vorgehensweise hängt natürlich start davon ab, wie Du diese Tabelle eigentlich anschließend verwenden willst.

Gruß
Frank

11. Mai 2007 11:16

sollen die Auftrüge zum neuen Auftragsdatum anhand dieser Tabelle automatisch erstellt werden?
Wenn ja, würde ich so vorgehen:
In der Tabelle:
im Onvalidate-Trigger des Felds mit der Dateformula den Calcdatebefehl bezogen auf das Flowfield mit der letzten Auftragsnummer
In der Funktion die die neuen Aufträge erzeugt, den Befehl bezogen auf das Feld neues Auftragsdatum.
D.h.
Wenn du in der Tabelle das Feld mit dem Intervall änderst, wird das neue Datum neu berechnet. Wenn der Auftrag das erste mal aufgenommen wurde, steht im Intervall ja noch nichts drin, wenn eine Funktion den Auftrag in diese Tabelle schreibt, füllst Du das Intervallfeld mit Validate, dann wird das neue Datum auch berechnet. Im C/AL-Code aber nicht den Calcfields-Befehl vergessen!
Wenn nun die Funktion zum erstellen des neuen Auftrags läuft, dann schreibst du nach dem erstellen des Auftrags den neu berechneten Wert des nächsten Auftragsdatums direkt in das Feld oder du stößt nach dem Commit des neuen Auftrags den Validate vom Intervallfeld an. Sicherer ist aber die erste Variante, weil du dann zwischendurch kein Commit brauchst.

11. Mai 2007 14:47

Michael Schumacher hat geschrieben:sollen die Auftrüge zum neuen Auftragsdatum anhand dieser Tabelle automatisch erstellt werden?

Ja.

Wenn ja, würde ich so vorgehen:
In der Tabelle:
im Onvalidate-Trigger des Felds mit der Dateformula den Calcdatebefehl bezogen auf das Flowfield mit der letzten Auftragsnummer


So hab ich das nun gemacht. Gleichzeitig mit der Datumsberechnung ein Feld gefüllt ob der Auftrag vorgelegt(kopiert) werden muss oder nicht.

In der Funktion die die neuen Aufträge erzeugt, den Befehl bezogen auf das Feld neues Auftragsdatum.


Die Funktion ist als naechstes dran. Werde mir da mal die übliche "Beleg kopieren" funktion für angucken, evtl. sogar benutzen.

Wenn du in der Tabelle das Feld mit dem Intervall änderst, wird das neue Datum neu berechnet. Wenn der Auftrag das erste mal aufgenommen wurde, steht im Intervall ja noch nichts drin, wenn eine Funktion den Auftrag in diese Tabelle schreibt, füllst Du das Intervallfeld mit Validate, dann wird das neue Datum auch berechnet. Im C/AL-Code aber nicht den Calcfields-Befehl vergessen!


Habe ich nun auch so gemacht.

Wenn nun die Funktion zum erstellen des neuen Auftrags läuft, dann schreibst du nach dem erstellen des Auftrags den neu berechneten Wert des nächsten Auftragsdatums direkt in das Feld oder du stößt nach dem Commit des neuen Auftrags den Validate vom Intervallfeld an. Sicherer ist aber die erste Variante, weil du dann zwischendurch kein Commit brauchst.


Ich rechne mit dem Auftragsdatum , was in die Gebucht eRechnung geschrieben wird, so muss ich nach erstellen des Auftrages nichts weiter machen.

So. denke allmaehlich ist die Aufgabe gelöst ;-)
Ist auch Freitag schon .... Haben wir uns den Feierabend verdient?

JAAAAA !!! :-) :mrgreen:

Danke und schonmal ein schönes WE

15. Mai 2007 15:51

Pustekuchen Aufgabe gelöst ;-)

...

Bekomme das "OrderInteval" (DateFormula) Feld, nicht über C/Front beschrieben, :roll: , Validate über C/Front geht ja auch nicht so wirklich.

Also überlegt ein Code Feld zu beschreiben, und intern dann diesen Wert ins DateFormula Feld reinzuschreiben. Aber das geht wegen der unterschiedlichen Formate nicht.

Kann ich das irgendwie konvertieren/formatieren?

Danke

15. Mai 2007 17:00

elTorito hat geschrieben:Kann ich das irgendwie konvertieren/formatieren?


Habe das mal so gelöst:

Code:
CheckOrderInterval := EVALUATE(OrderInterval, FORMAT("Code OrderInterval"));
VALIDATE("OrderInterval", OrderInterval);

15. Mai 2007 19:34

Ich würde das im OnValidate-Trigger von "Code OrderInterval" so lösen:

Code:
IF EVALUATE(OrderInterval,"Code OrderInterval") THEN
  VALIDATE(OrderInterval);

16. Mai 2007 15:17

Michael Schumacher hat geschrieben:Ich würde das im OnValidate-Trigger von "Code OrderInterval" so lösen:

Code:
IF EVALUATE(OrderInterval,"Code OrderInterval") THEN
  VALIDATE(OrderInterval);


Nur das über C/Front der OnValidate nicht ausgeführt werden kann, warum auch immer.

17. Mai 2007 02:05

ok, wo hast du das denn aufgerufen?
Du kannst aber auf jeden Fall die von mir genannte verkürzte Form verwenden.