[GELÖST] Frage zu Report

14. April 2008 13:00

Hi,

ich habe eine Tabelle in der Folgende Informationen stehen:

Debitornr.,Menge an Umsatz, Verkäufer, posting date

In der Tabelle werden alle Umsatze angezeigt, die an einen Debitor verkauft wurden. D.H. wurde am 01.01.07 ein produkt verkauft und am 03.01 noch mal, taucht der debitor 2x in der tabelle auf.

ich möchte mir nun einen report bauen, der mir den debitor einmal anzeigt,
und dann die menge umsatz summiert!

hinzu soll kommen, dass der report vergleichen soll, ob der debitor im vorjahr auch schon umsatz hatte oder ein neukunde ist!

zur ersten aufgabenstellung war dies mein ansatz, geht aber nicht:


Turnover Statistics Customer - OnPreDataItem()
SETFILTER(Salesperson,verkäufer);

Turnover Statistics Customer - OnAfterGetRecord()
SETFILTER("Posting Date",'01.01.2007..31.12.2007');
IF FIND('-') THEN
CurrReport.CREATETOTALS("Quantity Therapy");
Zuletzt geändert von tac0211 am 17. April 2008 20:36, insgesamt 1-mal geändert.

14. April 2008 13:17

Inwiefern "geht es nicht"?
Wenn du Summen per CREATETOTALS bildest, sind diese nur in den Footer-Sections anzeigbar.
Musst du unbedingt in den Body-Sections die Zahlen bereit stellen, dann musst du die Summe manuell über Variablen bilden.

Was du glaub ich brauchst sind Groups. Gruppiere auf Debitor, dann kannst du dir alle Zahlen, die du pro Debitor brauchst, bequem im Group Footer ausgeben lassen.

14. April 2008 13:19

danke! ich versuche es mal eben!

14. April 2008 13:23

hm, funktioniert nicht!

ih habe nun einen group footer anzeigen lassen! der nimmt mir immer nur die totals von der letzten menge! d.h. ich hätte eigentlich 8 (2 und 6) und der zeigt mir nur 6 an!

14. April 2008 14:07

Wie hast du denn die Gruppen überhaupt gebildet? Was hast du dafür eingegeben? Welche Sections verwendest du und was wird darin angezeigt?

14. April 2008 14:13

ich habe gerade einfach wieder alles über den haufen geschmissen!

ich werde jetzt mal neu machen und dann kopiere ich es hier rein! moment

14. April 2008 14:21

also einfach datums und verkäuferfilter ins pre data item!

dann on after get record:

currreport.totalfields(menge);

und als group total fields habe ich customer no. angegeben! jetzt sollte er pro customer die verkaufte menge ausummieren! tut er auch! aber nach einem customer ist dann wieder ende!

14. April 2008 14:34

Hm, der Befehl lautet richtigerweise aber CREATETOTALS und nicht totalfields.
Außerdem muss der Schlüssel auf deinem DateItem das Feld "Customer No." enthalten.

14. April 2008 14:35

jawohl! ;-)
er lautet createtotals .. habe den kopf heute echt nciht auf den schultern! das mit dem schlüssel stimmt natürlich auch!

14. April 2008 14:37

das ist der key...

Customer No.,Posting Date,Item category Code,Product Code,Document Type

customer no. kann mehrfach vorkommen! daher dieser lange key!

14. April 2008 14:38

Hast du einen Filter auf "Customer No."?
Sonst gehen mir nämlich die Gründe aus, warum nach einem Debitor schluss mit lustig ist ...
Zeigt er keine weiteren Debitoren an oder weisen die "nur" falsche Werte aus?

14. April 2008 14:38

also: nu summiert der weingstens richtig! auch der die debitornummer wird nur noch einmal angezeigt und dann daneben die richtig summierte menge!

nun muss der nur noch über alle debitoren laufen! komischer weise macht der das ur mit einer nummer!

14. April 2008 14:40

hat sich erledigt! der datumsfilter war schuld! sorry

14. April 2008 14:48

eine frage noch! wie würdest du einen vergleich machen, ob der debitor in diesem jahr schon umsatz gemacht hat und im letzten noch nicht?

nur wenn er im letzten jahr noch keinen umsatz gemacht hat, dann soll er angezeigt werden

14. April 2008 15:15

Ich würd eine Funktion schreiben, die fast genauso funktioniert wie der Code in deinem OnAfterGetRecord-Trigger - nur mit anderem Datumsfilter.
Kommt dabei heraus, dass der Debitor letztes Jahr Umsatz gemacht hat, dann fülle eine Boolean-Variable und frage sie in der Section via CurrReport.SHOWOUTPUT(deineVariable) ab.

14. April 2008 15:16

das ist eine gute idee! danke!

15. April 2008 08:15

gut:

Code:


Turnover Statistics Customer - OnAfterGetRecord()
SETRANGE("Posting Date",von,bis);
IF FIND('-') THEN BEGIN
  vergleich("Customer No.");
  IF jarueck = FALSE THEN BEGIN
    MESSAGE('%1',jarueck);
    CurrReport.CREATETOTALS("Quantity Therapy");
  END ELSE
    CurrReport.SKIP;
END;

Turnover Statistics Customer - OnPostDataItem()

vergleich(debitor : Code[10]) ja : Boolean
"Turnover Statistics Customer".SETRANGE("Posting Date",von2,bis2);
"Turnover Statistics Customer".SETRANGE("Customer No.",debitor);
IF "Turnover Statistics Customer".FIND('-') THEN
  bool := bool=TRUE;

Zuletzt geändert von tac0211 am 15. April 2008 08:18, insgesamt 1-mal geändert.

15. April 2008 08:39

Das sieht auf den ersten Blick schon mal gut aus :-)
Allerdings würde ich in der Funktion vergleich eine neue Record-Variable nehmen. Außerdem solltest du die Debitorennr. so groß wie möglich definieren - dies ist bei Debitoren Code20 und nicht Code10.
Wo setzt du von2 und bis2?
Wenn du es ein klein wenig performanceoptimierter schreiben möchtest, dann kannst du die Funktion Vergleich auch so schreiben:

vergleich(debitor : Code[20]) : Boolean
Code:
TurnoverStatCust.COPYFILTERS("Turnover Statistics Customer"");
TurnoverStatCust.SETRANGE("Posting Date",von2,bis2);
TurnoverStatCust.SETRANGE("Customer No.",debitor);
EXIT("TurnoverStatCust.ISEMPTY);


Die Syntax deines 1. Quelltextes ist noch nicht ganz korrekt:

Turnover Statistics Customer - OnAfterGetRecord()
Code:
IF vergleich("Customer No.") THEN BEGIN
   CurrReport.CREATETOTALS("Quantity Therapy");
END ELSE
  CurrReport.SKIP;


Ein Teil des Textes gehört - wenn ich mich jetzt nicht verguckt habe - in Turnover Statistics Customer - OnPreDataItem statt in OnAfterGetRecord:
Code:
SETRANGE("Posting Date",von,bis);

15. April 2008 09:01

danke für die antwort!

also von2 und bis2 werden in der request form gefüllt!



verstehe das mit dem ISEMPTY nicht! habe ich noch nie gehört! was macht das?

grüße chris

15. April 2008 09:08

ach so, ist das im prinzip schon der return parameter für die bool variable???


hm, also so läuft der jetzt irgendwo ins nirvana! ich meine ziel aoll ja sein, den debitor auszugeben, wenn dieser im vorjahr nicht gefunden wird!

Code:

Turnover Statistics Customer - OnPreDataItem()
LastFieldNo := FIELDNO("Customer No.");
SETRANGE("Posting Date",von,bis);

Turnover Statistics Customer - OnAfterGetRecord()
IF FIND('-') THEN BEGIN
  vergleich("Customer No.");
  IF vergleich("Customer No.") THEN BEGIN
    CurrReport.CREATETOTALS("Quantity Therapy");
  END ELSE
    CurrReport.SKIP;
END;

Turnover Statistics Customer - OnPostDataItem()

vergleich(debitor : Code[20]) : Boolean
turnover.COPYFILTERS("Turnover Statistics Customer");
turnover.SETRANGE("Posting Date",von2,bis2);
turnover.SETRANGE("Customer No.",debitor);
EXIT(turnover.ISEMPTY);


was ich auf jeden fall noch anpassen muss ist, dass ich in der requestform nur die jahresdaten (2007,2008) angeben muss und der report dann automatisch das gesamte jahr 2008 mit dem gesamten jahr 2007 vergleicht! aber ich denke das ist die kleiner herausforderung. sollte mit date2dmy funktionieren denke ich!

15. April 2008 09:22

Ja. Du musst nicht unbedingt mit einer neuen Variable arbeiten. Wichtig ist nur, dass du den Rückgabewert abfragst. Ob mit oder ohne Variable spielt keine Rolle.

ISEMPTY: Bitte schau in der C/AL-Onlinehilfe nach. Der Name sagt es aber schon ganz gut aus.

15. April 2008 09:26

hm... dauert echt arsch lange! obwohl ich vorher schon ein datumsfilter gesetzt habe! man man ;-)

und noch immr rödelt er ;-)


ne, also der läuft immer noch und zeigt nicht mal was an! also irgendwas kann da nicht stimmern! der filtert zu erst den verkäufer weg! das sind fie filter im dataitem! wenn ich das manuell mache, dann komme ich da sofort auf 5 datensätze!

davon liegen drei im datumsbereich 2007!

wenn ich nun den verkäufer filter nur auf das jahr 2006 anwende, findet der gar keinen debitor!

in dem fall sollte er mir ja schon eien ausgabe machen! sowas doofes!
ich glaube ich wende auch mal eben die customer no. im data item an! dann sehe ich wie schnell der wirklich ist1

ne, und noch immer nix! da stimmt was nicht!


also:
der isempty gibt mir einen bool wert zurück, wenn die tabelle nach dem filtern auf die deitornr. leer ist, also kein datensatz gefunden wurde. was mir nun nicht klar ist, wo ich diese bool im on after get record vernünftig abfragen kann! denn nur das

Code:
if vergleich("cust no.") then begin
  currreport.createtotals 


kann es dann noch nicht gewesen sein oder? ich muss mit dem rückgabewert der funktion doch sagen oib der nun aufsummieren soll oder nicht, oder?

15. April 2008 10:08

Warum du scheinbar in eine Endlosschleife kommst, kann ich dir spontan auch nicht sagen - dazu bräuchte in den Report vor mir.

Was den zweiten Teil angeht:
IF Vergleich("cust. no.") ist schon Abfrage des Funktionsergebnisses.
Liefert die Funktion ein True, dann heißt das doch im Umkehrschluss: ISEMPTY = true.

ich hätte die Funktion ohnehin ganz anders benannt: KeineVorjahreswerte.

Dann liest sich das schon besser:
Code:
IF KeineVorjahreswerte("Cust No.") then
  CurrReport.CREATETOTALS(...);


Wenn das deine Frage nicht beantwortet, dann habe ich sie nicht verstanden.

15. April 2008 10:11

doch, beantwortet die frage recht gut ;-)
danke!

aber ich scheine tatsächlich in eine endlosschleife zu laufen! habe die deb nr. mal mit einer meddage ausgeben lassen! er zeigt immer wieder die selbe an!

seltsam, echt!

dabei filter ich jetzt schon nur noch auf einen satumsbereich in dem die 5x vorkommt im jahr 2007! und dann soll der bene durch das ganze jahr 2006 laufen! aber vielelicht vergleicht der jetzt jeden einzelnen datensatz miteinander!

15. April 2008 10:14

Veröffentliche bitte mal den gesamten Quelltext aus OnPreDataItem und OnAfterGetRecord.

Wenn auf deinem DataItem ein DataItemTableView gesetzt ist, verrate bitte auch diesen.
Bestimmt nur eine Kleinigkeit :-)