Reports: Interscoping und Aggregatsfunktionen

11. November 2014 09:43

Hallo zusammen!

Ich habe ein kleines Problem mit einem Report, den ich machen möchte und bin langsam am Ende mit meinem Latein. Ich hoffe, ich kann den Sachverhalt einigermaßen nachvollziehbar erklären.

Ich möchte eine monatliche Übersicht aller Verkaufsaufträge und deren Rechnungen machen. Dabei sollen Rechnungs- und Auftragszeilen (sowie später deren Gutschriften) in den entsprechenden Monaten zusammengezählt werden, um den jeweils aktuellen Stand des Auftrags in diesem Monat aufzuzeigen. Wenn man so will, dann soll der Report einen zeitlichen Verlauf des Auftragsstatus gruppiert nach Monaten anzeigen.

Entsprechend habe ich folgende DataSet-Struktur gewählt:

Code:
DataItem   Sales Header   
   DataItem   Sales Line
   DataItem   Sales Invoice Header
      DataItem   Sales Invoice Line


(Ich habe die Columns mal rausgelassen.)

Nun habe ich die Daten ein wenig vermengt, so dass ich beispielhaft folgende Datenstruktur rausbekomme (In diesem Beispiel hat jedes Dokument nur eine Line):
Code:
Document No. | Order No. | Document Date | Amount
----------------------------------------------------
1111         | ABCD      | 01.01.2014    | 2000.00
1112         | ABCD      | 01.01.2014    | 2000.00
2222         | XYZX      | 20.01.2014    | 9999.00
3333         | ABCD      | 10.11.2014    | -1000.00
5555         | ABCD      | 10.12.2014    | -1000.00
...


Am Ende sollte der Report etwas ähnliches wie das hier ausgeben:

Code:
January
Order No.   | Document No. | Amount
---------------------------------------------
ABCD        | -            | 4000.00 (Total)
            | 1111         | 2000.00
            | 1112         | 2000.00
XYZX        | -            | 9999.00 (Total)
            | 2222         | 9999.00
-------------------------------------

November
Order No.   | Document No. | Amount
---------------------------------------------
ABCD        | -            | 3000.00 (Total)
            | 3333         | -1000.00
-------------------------------------

December
Order No.   | Document No. | Amount
---------------------------------------------
ABCD        | -            | 2000.00 (Total)
            | 5555         | -1000.00


Was habe ich bisher gemacht?

Ich habe im Report zwei Gruppierungen. Nummer 1 gruppiert nach Month(DocumentDate.Value), Gruppe 2 nach OrderNo.. So komme ich der Struktur des Reports schon ziemlich nahe. Nun aber das kleine Problem:

Wenn ich bspw. eine Rechnung im November zu einem Auftrag im April habe, möchte ich gerne den aktuellen Restbetrag des Auftrags dort aufgelistet bekommen. Ergo benötige ich im globalen Scope eine Aufsummierung der Lines minus der Aufsummierung der Rechnungen bis zum November. Ich dachte, ich könnte das mit der Sum()-Funktion lösen, immerhin kann man dort ja einen Scope angeben. Und tatsächlich kann ich mit dem Scope "DataSet_Result" wieder zurück in den globalen Scope springen, um aus meiner Monats-Gruppierung auszubrechen. Allerdings bleibt dennoch die Filterung nach Month(DocumentDate) < Month("CurrentDate"). Da ich aber nun im globalen Scope bin, fand ich keine Lösung, auf den aktuellen Monat, bzw. auf den aktuellen Gruppen-/Data-Wert zuzugreifen. Also habe ich zwei Funktionen SetCurrentMonth(val) und GetCurrentMonth() geschrieben:

Code:
Public Shared Dim month As Integer = 0

Public Function SetCurrentMonth(val As Integer) As Integer
   month = val
   Return month
End Function

Public Function GetCurrentMonth() As Integer
   Return month
End Function


SetCurrentMonth() wird zu Beginn der Monatsgruppierung gesetzt, GetCurrentMonth() entsprechend bei der Expression genutzt:

Code:
=Sum(CDbl(iif(Month(Fields!DocumentDate.Value) < Code.GetCurrentMonth(), Fields!LineAmount, 0)), "DataSet_Result")


Dummerweise scheint Code.GetCurrentMonth() in diesem Scope 0 zurückzugeben und überhaupt scheint man solche Funktionen (Wie auch ReportVariablen, Textbox-Inhalte etc) nicht in Aggregats-Funktionen haben zu wollen. Einzeln ausgegeben bekomme ich den richtigen Monat zurück und wenn ich statt der Funktion einfach eine konstante Nummer reingebe, funktioniert auch das Aufsummieren wie gewünscht.

Nun habe ich allerdings leider keine Ideen mehr, wie ich mein Problem sonst noch (in dieser Struktur) lösen kann. Exzessive C/AL-Aufsummierungen würde ich gerne - wenn möglich - vermeiden.

Hat jemand eine Idee?

Vielen Dank im Voraus und liebe Grüße
Patrik

PS: Ich hoffe, ich habe den Sachverhalt einigermaßen schlüssig erklären können. Falls ich etwas vergessen haben sollte oder Fragen bestehen, einfach drauf los fragen!
Zuletzt geändert von Patrik am 11. November 2014 12:24, insgesamt 1-mal geändert.

Re: Reports: Interscoping und Aggregatsfunktionen

11. November 2014 10:03

Herzlich Willkommen bei uns!

Bevor wir das Technische besprechen:

Patrik hat geschrieben:Ich möchte eine monatliche Übersicht aller Verkaufsaufträge und deren Rechnungen machen.

Hast du dabei bedacht, dass Aufträge bei Erledigung gelöscht werden, und dir daher die Datenbasis fehlt? Die Auftragsnummer taucht dann nur noch im Lieferschein und als - ggf. - archivierter Auftrag auf. In der geb. Rechnung findest du die Auftragsnummer nur, wenn die Rechnung direkt aus dem Auftrag heraus (durch Funktion "Buchen") erstellt worden ist, und nicht etwa durch ungebuchte Rechnung + '"Lieferzeilen holen".

Re: Reports: Interscoping und Aggregatsfunktionen

11. November 2014 10:11

Hallo und danke für's Aufnehmen!

Das Problem sehe ich noch auf mich zukommen. Hier werden Rechnungen zu Aufträgen allerdings grundsätzlich über die Funktion "Buchen" heraus erstellt. Zumindest sollten meine Kollegen das so tun, ansonsten haben wir Probleme ;). Dahingehend muss ich eh noch über das Archiv gehen, wobei ich versuchen wollte, diese Aufträge ebenfalls in die oben beschriebene Form zu "quetschen". Mit globalen Variablen kann man da relativ "kreativ" rückwirkend die an RDLC zu übertragenen Daten ändern. Das sollte also (zumindest in meinem Kopf) funktionieren. Definitiv aber ein hilfreicher Hinweis, danke!

Liebe Grüße
Patrik

Re: Reports: Interscoping und Aggregatsfunktionen

11. November 2014 10:24

Für den Rest deiner Frage fehlt mir momentan leider die Zeit :-(
Vielleicht mag jemand anders in der Zwischenzeit übernehmen ...?

Re: Reports: Interscoping und Aggregatsfunktionen

11. November 2014 10:27

Muss ja nicht sofort sein, außerdem macht das hier ja auch jeder freiwillig. Daher danke schon mal :).

Re: Reports: Interscoping und Aggregatsfunktionen

11. November 2014 13:02

Hallo!

Ein kurzer Nachtrag mit einer weiteren kleinen Frage zum Scoping:

Wenn ich in der Gruppierung "Month => OrderNo" bin, würde ich gerne mit Sum(value, scope) eine Summe über Werte aus einer anderen Gruppierung - Nämlich "OrderNo" oder "OrderNo2", falls Namengleichheit nicht erlaubt ist - bilden. Interessanterweise war es mir aber nicht möglich, in Sum den Scope anzugeben. Ungefähr so sieht mein Aufruf aus:
Code:
Sum(Fields!LineAmount.Value, "OrderNo2")

Will ich den Report kompilieren, schmeißt mir NAV die folgende Fehlermeldung aus:
Fehler beim Überprüfen von RDL-Inhalt:
Der Value-Ausdruck für das Textfeld-Objekt 'TextboxXY' weist einen Bereichsparameter auf, der für eine Aggregatfunktion ungültig ist. Der Bereichsparameter muss auf eine Zeichenfolgenkonstante festgelegt sein, die einem der folgenden Werte entspricht: dem Namen einer enthaltenden Gruppe, dem Namen eines enthaltenden Datenbereichs oder dem Namen eines Datasets.

Das finde ich seltsam, denn die Gruppe gibt es ja. Ich habe auch zunächst mal versucht, eine Gruppe zu referenzieren, die innerhalb der Gruppe ist, von der ich den Ausdruck aus auswerte, aber selbst das funktioniert nicht. Daher stelle ich mir gerade grundsätzlich die Frage, ob es jemals jemand geschafft hat, Aggregatsfunktionen mit einer Gruppe als Scope zu nutzen?

Liebe Grüße
Patrik

Edit: Naja, so fast: Ich kann anscheinend nur Gruppen referenzieren, die in der "Verwandschaftslinie" der Gruppe sind.
Edit2: Nach weiterer Überlegung: Ich glaube, diese Frage läuft ins Leere. Eine Gruppierung außerhalb weiß ja gar nicht, in welchem Gruppeniterationsschritt sie gerade ist.