Dynamics AX Blog - sysoperation-framework - Seite 2

SysOperation-Framework: Feld im Dialog sperrenWenn innerhalb eines SysOperation-Konstruktes ein Feld im Dialog gesperrt werden soll, daß über eine parm-Methode eingebunden ist, kann man im UIBuilder Code wie den folgenden verwenden. public void postBuild() { DialogField df_SalesId; super(); df_salesId = this.bindInfo().getDialogField( this.dataContractObject(), methodStr(DEV_SalesUpdateDatacontract, parmSalesId)); if(df_salesId) { df_salesId.allowEdit(false); df_salesId.skip(true); } } |
SysOperation-Framework: Eigenschaften eines Dialogfeldes abhängig von anderen Dialogfeldern ändernStellt euch folgendes Szenario vor: Im Dialog eines SysOperation-Konstruktes muss ein Feld abhängig von anderen Feldern manipuliert werden, beispielsweise soll die Eigenschaft AllowEdit verändert werden. Im folgenden findet ihr den Code für einen DataContract und den dazugehörigen UIBuilder, in welchem letztlich die entsprechende Programmlogik einzubauen ist. Hier wir abhängig von der Auswahl im Feld Module entweder das Feld Customer account oder das Feld Vendor account freigeschalten.
DataContract[DataContractAttribute, SysOperationContractProcessingAttribute(classStr(TutorialSysOperationUIBuilder))] public class TutorialSysOperationDataContract { ModuleCustVend moduleCustVend; CustAccount custAccount; VendAccount vendAccount; }
[DataMemberAttribute, SysOperationControlVisibilityAttribute(true), SysOperationDisplayOrderAttribute('1')] public ModuleCustVend parmModuleCustVend(ModuleCustVend _moduleCustVend = moduleCustVend) { moduleCustVend = _moduleCustVend; return moduleCustVend; }
[DataMemberAttribute, SysOperationControlVisibilityAttribute(true), SysOperationDisplayOrderAttribute('2')] public CustAccount parmCustAccount(CustAccount _custAccount = custAccount) { custAccount = _custAccount; return custAccount; }
[DataMemberAttribute, SysOperationControlVisibilityAttribute(true), SysOperationDisplayOrderAttribute('3')] public VendAccount parmVendAccount(VendAccount _vendAccount = vendAccount) { vendAccount = _vendAccount; return vendAccount; }
UIBuilderpublic class TutorialSysOperationUIBuilder extends SysOperationAutomaticUIBuilder { DialogField df_ModuleCustVend; DialogField df_CustAccount; DialogField df_VendAccount; } In der methode build() werden die vom Framework generierten Dialogfelder zugänglich gemacht. Hier wird bereits erstmalig die Methode modifyDialogFields() aufgerufen, damit gleich beim Öffnen des Dialogs das jeweils gewünschte Feld freigeschalten wird. public void build() { super(); df_ModuleCustVend = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(TutorialSysOperationDataContract, parmModuleCustVend)); df_CustAccount = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(TutorialSysOperationDataContract, parmCustAccount)); df_VendAccount = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(TutorialSysOperationDataContract, parmVendAccount)); this.modifyDialogFields(); } In der Methode postRun() wird die modify()-Methode des Feldes Module überschrieben. public void postRun() { super(); // Override modified method df_ModuleCustVend.registerOverrideMethod(methodStr(FormComboBoxControl, modified), methodStr(TutorialSysOperationUIBuilder, moduleCustVend_modified), this); } In dieser überschriebenen Methode rufen wir die Methode modifyDialogFields() auf. Hier ist wichtig, daß die Methode das richtige Parameterprofil erhält und den von AX erwarteten Datentyp retourniert. private boolean moduleCustVend_modified(FormComboBoxControl _control) { this.modifyDialogFields(); return _control.modified(); } Die "Zauberei" passiert in der Methode modifyDialogFields(). Hier werden die Felder ent- oder gesperrt, je nach Auswahl des Wertes im Feld Module. private void modifyDialogFields() { df_CustAccount.allowEdit(df_ModuleCustVend.value() == ModuleCustVend::Cust); df_VendAccount.allowEdit(df_ModuleCustVend.value() == ModuleCustVend::Vend); } Natürlich können auf die selbe Art & Weise zahlreiche andere Eigenschaften von Dialogfeldern dynamisch verändert werden. |
SysOperation-Framework: Datensätze einer temporären Tabelle übergebenIm folgenden Szenario sollen an ein SysOperation-Konstrukt alle Datensätze einer temporären Tabelle übergeben werden. Dafür brauchen wir:
Controllerclass TutorialSysOperationController extends SysOperationServiceController { } |
SysOperation-Framework: Einfaches Klassenkonstrukt mit DataproviderDer nachstehende Code stellt ein einfaches Klassenkonstrukt für das SysOperation-Framework dar. Datacontract[DataContractAttribute] public class TutorialSysOperationDataContract { CustAccount custAccount; }
[DataMemberAttribute] public CustAccount parmCustAccount(CustAccount _custAccount = custAccount) { custAccount = _custAccount; return custAccount; }
Serviceclass TutorialSysOperationService extends SysOperationServiceBase { } Die Methode runService() ist die eigentliche Service-Methode. Über das Attribute SysEntryPointAttribute steuern wir hier, daß keine weiteren Berechtigungsprüfungen notwendig sind. [SysEntryPointAttribute(false)] public void runService(TutorialSysOperationDataContract _dataContract) { info("Done"); } |
SysOperation-Framework: Einfaches KlassenkonstruktDer nachstehende Code stellt ein ganz einfaches Klassenkonstrukt für das SysOperation-Framework dar. Ganz ohne Dataprovider und UIBuilder. Serviceclass TutorialSysOperationService extends SysOperationServiceBase { } Die Methode runService() ist die eigentliche Service-Methode. Über das Attribute SysEntryPointAttribute steuern wir hier, daß keine weiteren Berechtigungsprüfungen notwendig sind. [SysEntryPointAttribute(false)] public void runService() { info("Done"); }
Controllerclass TutorialSysOperationController extends SysOperationServiceController { } In der new() verknüpfen wir den Controller mit der Service-Klasse. void new() { super(); this.parmClassName(classStr(TutorialSysOperationService)); this.parmMethodName(methodStr(TutorialSysOperationService, runService)); } Die main() ist der klassische Einstiegspunkt, wenn der Controller über ein MenuItem aufgerufen wird. public static void main(Args _args) { TutorialSysOperationController controller; controller = new TutorialSysOperationController(); controller.parmArgs(_args); controller.parmExecutionMode(SysOperationExecutionMode::Synchronous); controller.startOperation(); } |
SysOperation-Framework: Asynchrone VerarbeitungÜber das SysOperation-Framework kann man Funktionen auch asynchron ausführen lassen. Dafür wird der ExecutionMode auf SysOperationExecutionMode::Asynchronous gesetzt. Dies macht beispielsweise dann Sinn, wenn eine zeitintensive Aktion gestartet werden soll, der Benutzer aber nicht zwinged auf das Ende dieser Aktion warten muss und dafür bereits an anderen Themen weiterarbeiten können soll. Allerdings funktioniert eine solche asynchrone Verarbeitung nur, wenn folgende Kriterien erfüllt sind:
|
|
|
|
|
|
|
Häufig wird eine Funktion, die über das SysOperation-Framework abgebildet wurde, aus einem Formular heraus über eine Schaltfläche aufgerufen. Dabei hat man meist die Anforderung, daß die angezeigten Daten im Formular nach der Ausführung aktualisiert werden sollen.
Ich benutze dafür gerne die folgende Logik. Diese geht davon aus, daß der Aufruf der Funktion über eine Schalfläche erfolgt ist und dadurch die main()-Methode getriggert wird.
Die eigentliche Aktualisierug erfolgt über eine Sub-Methode und könnte wie folgt aussehen:
Der Aufruf dieser Methode erfolgt in der erwähnten main():
Denkbare Variationen der refreshCallingForm()
Statt der task()-Methode der Form könnte man auch Methoden der Formdatasource aufrufen.
Verwendung von ExecuteQuery()
Verwendet man die executeQuery() der jeweiligen FomDataSource, so gehen dabei etwaige Filter sowie der Datensatz-Fokus verloren.
Verwendung von ReSearch()
Verwendung von ReRead()
Auch ein ReRead() wäre denkbar, in diesem Fall würde aber nur der aktive Datensatz aktualisiert werden.