Dynamics AX Blog - Microsoft Dynamics AX (Axapta) - Seite 7

In den letzten Jahren, in denen ich mich fast hauptsächlich mit der Entwicklung im Umfeld von Microsoft Dynamics AX (vormals Axapta) beschäftigt habe, ist das eine oder andere Code-Fragment entstanden, von dem ich mir vorstellen könnte, daß es auch für andere AX-Entwickler ganz nützlich sein könnte. Aber auch Tips und Tricks zu dem mächtigen ERP-System werde ich in dieser Kategorie präsentieren.
RSS-Feed dieser KategorieSysOperation-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(); } |
Shared Project per Code erstellen, Objekte hinzufügen und dabei Gruppen je Objekttyp erzeugenMit Hilfe des hier gezeigten Jobs kann man per Code ein Shared Project erstellen, Objekte hinzufügen und diese dabei in Gruppen je Objekttyp einordnen lassen. static void AddNodeToSharedProject(Args _args) { projectNode projectNode; TreeNode treeNode; ProjectName projectName = "MyProject"; #AOT #AOTExport void addTreeNodeToProjectNode(treeNode _treeNode) { TmpIdRef tmpIdRef; tmpIdRef.clear(); tmpIdRef.Name = SysTreeNode::getPath(_treeNode); tmpIdRef.Mode = SysTreeNode::path2ApplObjectType(tmpIdRef.Name); tmpIdRef.useMode = UtilFileType::Application; tmpIdRef.insert(); SysProjectFilterRunBase::addProjectNodes(tmpIdRef, projectNode); } projectNode = infolog.projectRootNode(); projectNode = projectNode.AOTfindChild(#expProjectShared); projectNode = projectNode.AOTfindChild(projectName); // Create shared project if neccessary if( !projectNode) { projectNode = SysTreeNode::createProject(projectName, ProjectSharedPrivate::ProjShared); } // Add objects (and create groups) treenode = TreeNode::findNode(#TablesPath+#AOTRootPath+tableid2name(tablenum(AccountingDistribution))); addTreeNodeToProjectNode(treenode); treenode = TreeNode::findNode(#TablesPath+#AOTRootPath+tableid2name(tablenum(VendGroup))); addTreeNodeToProjectNode(treenode); treenode = TreeNode::findNode(#ClassesPath+#AOTRootPath+classStr(PriceDisc)); addTreeNodeToProjectNode(treenode); } Auf die gleiche Art & Weise kann man natürlich auch ein Private Project erstellen, einfach die Vorkommnisse von Shared durch Private ersetzen. Das erstellte Projekt sieht wie folgt aus: |
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:
|
CreateNavigationPropertyMethodsSchon mal im Code den Aufruf der Methode product() einer InventTable-Instanz gesehen und sich dabei gewundert, woher diese Methode kommt und warum man sich diese nicht ansehen kann? inventTable.product() Verantwortlich für diese Methode ist die Eigenschaft CreateNavigationPropertyMethods einer (Foreign key-)Relation. Über die Eigenschaft NavigationPropertyMethodNameOverride der Relation kann man Einfluss auf den Namen dieser Methode nehmen. |
Zwei Maps zu einer zusammenführenVor kurzem wollte ich zwei Maps zu einer zusammenführen, habe dafür aber keine geeignete Funktion gefunden, deshalb habe ich mir die folgende selbst geschrieben. private Map mergeMaps(Map _map1, Map _map2) { Map retMap; MapEnumerator mapEnum; // Initate first map from second map if empty if( !_map1) { _map1 = new Map(_map2.keyType(), _map2.valueType()); } // Check compatibility if(_map1 && _map2) { if(_map1.keyType() != _map2.keyType() || _map1.valueType() != _map2.valueType()) { throw error(Error::wrongUseOfFunction(funcName())); } } retMap = _map1; mapEnum = _map2.getEnumerator(); while(mapEnum.moveNext()) { if( !retMap.exists(mapEnum.currentKey())) { retMap.insert(mapEnum.currentKey(), mapEnum.currentValue()); } } return retMap; } |
Eigenschaft PreviewPartRef einer Tabelle nutzen
Verantwortlich dafür ist die Eigenschaft PreviewPartRef einer Tabelle, mit der man sich rasch solche Vorschauansichten aufbauen kann. Folgende Schritte sind dafür notwendig:
Ich habe mir beispielsweise für die Tabelle CustGroup ein einfaches Form erstellt und wie oben beschrieben eingebunden. Ohne meine Anpassung sieht die Vorschau üblicherweise wie folgt aus:
|
|
|
|
|
|
|
Der nachstehende Code stellt ein einfaches Klassenkonstrukt für das SysOperation-Framework dar.
Datacontract
Service
Die Methode runService() ist die eigentliche Service-Methode. Über das Attribute SysEntryPointAttribute steuern wir hier, daß keine weiteren Berechtigungsprüfungen notwendig sind.