Praktisches Beispiel für die Verwendung des runBaseBatch-Frameworks
20.03.2011Microsoft Dynamics AX (Axapta)
|
Dieser Beitrag bezieht sich auf die Versionen:
Dynamics AX 4.0, Dynamics AX 2009
Dynamics AX 4.0, Dynamics AX 2009
|
|
|
|
|
|
Dieser Beitrag bezieht sich auf die Versionen:
Dynamics AX 4.0, Dynamics AX 2009
|
Vor einiger Zeit habe ich schon einmal einen Eintrag über das runBaseBatch-Framework geschrieben, damals ging's hauptsächlich um die Aufrufreihenfolge der einzelnen Methoden und wofür einige von diesen Methoden verwendet werden können bzw. verwendet werden sollten.
Nun habe ich mir basierend auf diesem Eintrag und vor allem aufgrund von Erfahrungswerten eine eigene Klasse namens tutorial_ClassWithQueryRun geschrieben, die einige oft benötigte Anforderungen vereinigt.
Diese Klasse vereint folgende Fähigkeiten:
Die erste Anforderung an meine Klasse war, daß sie stapelfähig sein musste. Dazu muss sie in erster Linie von runBaseBatch abgeleitet sein, und einige Methoden wie pack, unPack, canGoBatch müssen entsprechend überschrieben werden.
Die nächste Anforderung war, daß der Benutzer über einen Dialog Parameter festlegen kann. Dafür verantwortlich sind u.a. dialog, getFromDialog, putToDialog und natürlich die main-Methode.
Weiters sollte über diesen Dialog der Benutzer die Möglichkeit erhalten, einen definierten Query durch Filter und drgl. zu erweitern. Dazu mussten folgende Methoden angepasst/erstellt werden: initQuery, showQueryValues und showQuerySelectButton.
Die Methoden filenameLookupFilter, filenameLookupInitialPath und filenameLookupTitle wurden dazu verwendet, dem Benutzer im Dialog die Eingabe des Dateinamens zu erleichtern.
Starten wir also mit der classDeclaration. Hier erfolgt die Ableitung von runBaseBatch, weiters werden sämtliche Objektvariablen deklariert, die innerhalb der Methoden benötigt werden. Außerdem wird hier über das Makro currentList festgelegt, welche dieser Variablen in den Nutzungsdaten gespeichert werden.
In der pack-Methode werden nun über einen Container jene Variablen in die Nutzungsdaten geschrieben, die z.B. für die korrekte Abarbeitung innerhalb der Stapelverarbeitung von Nöten sind.
Die Methode unPack ist das Gegenstück zur pack-Methode, ist sie doch für das Auslesen der Werte aus den Nutzungsdaten zuständig. Wichtig hierbei ist natürlich, daß die Werte innerhalb des Containers in der gleichen Reihenfolge ausgelesen werden, wie sie geschrieben wurden. Weiters ist hier dafür zu sorgen, daß unterschiedliche Nutzungsdaten der Klasse über die entsprechende Versionsinfo korrekt berücksichtigt werden. Wird zum Beispiel die Klasse insofern angepasst, daß entweder die Reihenfolge der Variablen im Macro currentList geändert wird, oder - und das ist der wohl üblichere Fall - daß neue Variablen in die Nutzungsdaten aufgenommen werden, ist das Makro currentVersion anzupassen.
In nachstehender Methode wurde beispielsweise berücksichtigt, daß in der ersten ausgelieferten Version der Klasse die Variable dialogDate noch nicht in den Nutzungsdaten gespeichert wurde. Erst mit Version 2 (=aktuelle Version) wurde auch diese Variable über die pack-Methode in die Nutzungsdaten geschrieben.
Über die Methode allowSaveLast kann gesteuert werden, ob Werte aus den Nutzungsdaten oder die Standardwerte aus der Methode initParmDefault verwendet werden sollen.
In der Methode canGoBatch legt man fest, ob eine Klasse im Stapel ausgeführt werden können soll.
Die Methode runImpersonated steuert (unter AX 2009), ob die Klasse, sofern sie im Stapel ausgeführt wird, am AOS ausgeführt wird, oder über die manuell vom Benutzer zu startende Stapelverarbeitung.
Die main-Methode wird aufgerufen, wenn die Klasse über eine Schaltfläche in einem Formular, einen Eintrag im Menu (beides setzt sein entsprechendes MenuItem voraus) oder aber direkt aus dem AOT aufgerufen wird. Über den Aufruf von prompt wird der Dialog der Klasse geöffnet.
Die dialog-Methode dient dazu, dem Benutzer die Möglichkeit zu geben, bestimmte Parameter und dergleichen festzulegen. Dazu werden dem Dialog die gewünschten Dialog-Felder hinzugefügt.
GetFromDialog wird aufgerufen, wenn der Benutzer den Dialog mit OK bestätigt. Die Methode dient dazu, die eingetragenen Werte/Parameter auszulesen und wie im Beispiel über entsprechende parm-Methoden der Instanz zu übergeben.
Die Methode putToDialog dient dazu, um die Dialogfelder des Dialogs mit Werten zu befüllen. Diese Methode wird unter anderem beim Betätigen der Schaltflächen Löschen und Standard aufgerufen.
Die Methode dialogClear kann dazu verwendet werden, um Dialogfelder bzw. deren Inhalten zurückzusetzen. Diese Methode zu überschreiben macht natürlich nur dann Sinn, wenn die Methode showClearButton entsprechend true retourniert und somit die Schaltfläche Löschen im Dialog angezeigt wird.
Die folgenden drei Methoden werden dazu verwendet, den Benutzer bei der Eingabe des Speicherortes für die durch die Klasse zu erstellende Datei zu unterstützen. So werden der auszuwählende Dateityp genauso gesteuert, wie der Initial-Ablagepfad und der Titel des "Speichern untern"-Windows-Dialoges.
Die Schaltfläche Löschen im Dialog kann über die Methode showClearButton gesteuert werden. Wird die Schaltfläche eingeblendet, sollte die Methode dialogClear entsprechend überschrieben worden sein.
Soll im Dialog die Schaltfläche Standard angezeigt werden, so muss die Methode showDefaultButton entsprechend übersteuert werden. Diese Schaltfläche setzt die Felder des Dialoges auf die Standard-Werte zurück. In diesem Fall sollte aber auch die Methode initParmDefault entsprechenden Code enthalten.
Ob man dem Benutzer die Möglichkeit gibt, den Query mit Filterkriterien, Sortierung usw. zu erweitern kann man über die Methode showQuerySelectButton steuern. Diese legt fest, ob die Schaltfläche Auswählen im Dialog angezeigt wird.
In dieser Methode wird festgelegt, ob die Auswählen-Schaltfläche im Dialog angezeigt wird. Soll diese angezeigt werden, so muss übrigens auch die Methode queryRun überschrieben sein
Bestätigt der Benutzer den Dialog mit OK, so wird die validate-Methode aufgerufen. Hier können Dialogfelder bzw. deren Inhalt geprüft werden. Bevorzugterweise sollte man jedoch die Variablen der Instanz prüfen und nicht die Felder selbst. Auf diese Art und Weise kann man - so wie ich dies beinahe immer mache - die validate-Methode nochmals manuell in der run-Methode aufrufen, um vor der Abarbeitung der Klasse zu prüfen, ob alle notwendigen Parameter übergeben würden. Unabhängig davon, ob die Klasse über den Dialog (also über ein MenuItem) oder aus X++-Code heraus aufgerufen wurde.
Die construct-Methode muss überschrieben werden, um eine Instanz der Klasse bilden zu können.
Die Methode initParmDefault wird u.a. ausgeführt, wenn die Klasse erstmalig über ein MenuItem aufgerufen wird und es somit noch keine Nutzungsdaten gibt. Außerdem wird sie aufgerufen, wenn der Benutzer die Schaltfläche Standard betätigt.
Im Beispiel werden hier all jene Variablen, die der Benutzer auch im Dialog ggf. ändern kann, durch Standard-Werte befüllt. Wichtig ist der Aufruf der initQuery, die den zu verwendenden Query erstmalig initialisiert.
Die initQuery wird u.a. beim erstmaligen Aufruf der Klasse über ein Menuitem von der initParmDefault aufgerufen und generiert ein Query- sowie ein QueryRun-Objekt. Hier werden im Beispiel diverse QueryBuildRanges (Filter) aufgebaut. Auch die Sortierung des Queries kann hier festgelegt werden.
Die parm-Methoden werden u.a. dazu verwendet, um innerhalb einer Instanz der Klasse die Variablen abzufragen bzw. zu setzen.
In der Methode queryRun wird das in der initQuery aufgebaute queryRun-Objekt zurückgegeben.
Das eigentliche Herzstück der Klasse ist natürlich die run-Methode. Hier ist die eigentliche Logik zu implementieren. Im konkreten Fall wird nach der Prüfung der Parameter eine Datei erstellt. Danach wird der Query durchlaufen und bestimmte Werte werden in die Datei geschrieben. Der Benutzer wird währenddessen über eine Fortschrittsanzeige informiert, wie weit der Vorgang fortgeschritten ist.
Da es das Ziel der Klasse ist, eine Datei auf Basis eines Queries zu erstellen, muss diese Datei zu einem bestimmten Zeitpunkt erstellt werden. Dafür sind die Methoden createFileServer bzw. createFileClient zuständig.
Die Methode closeFile wird lediglich dazu verwendet, die Instanz des textIO zu entfernen.
Welcher Titel im Dialog angezeigt werden, kann mit Hilfe der Methode caption gesteuert werden.
Die Methode description sollte dazu verwendet werden, um dem Benutzer im Formular Stapelverarbeitungsliste eine Beschreibung des Stapelverarbeitungsauftrages zur Verfügung zu stellen.
Die Methode howToUseClass wird zu keinem Zeitpunkt automatisch aufgerufen, sie dient dem Entwickler lediglich als Information, wie die Klasse über X++ aufzurufen ist.
Die oben beschriebene Klasse wurde in Dynamics AX 2009 entwickelt, sie läuft aber auch in Dynamics AX 4.0.
Die Klasse steht hier als XPO-File zum Download zur Verfügung, Verwendung natürlich auf eigene Gefahr!