Dynamics AX Blog - sysoperation-framework - Microsoft Dynamics AX (Axapta) - Seite 2

Momentan angezeigt werden nur Beiträge der Kategorie »Microsoft Dynamics AX (Axapta)« Filter entfernen

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 Kategorie
Momentan angezeigt werden nur Beiträge, bei denen das Schlagwort »sysoperation-framework« eingetragen wurde. Filter entfernen

SysOperation-Framework: Aufrufendes Formular aktualisieren

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:

private void refreshCallingForm(args _args)
{
    FormRun callerFormRun;
    #Task

    if(_args && _args.caller() && _args.caller() is formRun)
    {
        callerFormRun = _args.caller();
        callerFormRun.task(#taskF5);
    }
}

Der Aufruf dieser Methode erfolgt in der erwähnten main():

public static void main(Args _args)
{
    TutorialSysOperationController controller;
    SysOperationStartResult sysOperationStartResult;

    controller = new TutorialSysOperationController();
    controller.parmArgs(_args);
    controller.parmExecutionMode(
        SysOperationExecutionMode::Synchronous);

    sysOperationStartResult =
    controller.startOperation();

    controller.refreshCallingForm(_args);
}

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.

private void refreshCallingForm(args _args)
{
    FormDataSource fds;
    
    if(_args && 
       _args.record() && 
       _args.record().isFormDataSource())
    {
        fds = _args.record().dataSource();
        fds.executeQuery();
    }
}

Verwendung von ReSearch()

private void refreshCallingForm(args _args)
{
    FormDataSource fds;
    
    if(_args && 
       _args.record() && 
       _args.record().isFormDataSource())
    {
        fds = _args.record().dataSource();
        fds.research(true);
    }
}

Verwendung von ReRead()

Auch ein ReRead() wäre denkbar, in diesem Fall würde aber nur der aktive Datensatz aktualisiert werden.

private void refreshCallingForm(args _args)
{
    if(_args && 
       _args.record() && 
       _args.record().isFormDataSource())
    {
        _args.record().reread();
    }
}

 
 

SysOperation-Framework: Feld im Dialog sperren

Wenn 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 ändern

Stellt 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.

Dialog

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;
}

 

UIBuilder

public 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 übergeben

Im folgenden Szenario sollen an ein SysOperation-Konstrukt alle Datensätze einer temporären Tabelle übergeben werden.

Dafür brauchen wir:

  • Im DataContract eine parm-Methode, die einen Container aufnimmt
  • Im Controller eine Logik, welche die Datensätze einer aufrufenden Datenquelle iteriert und in einen Container packt, und diesen über die obige Methode an das Service übergibt
  • In der Service-Klasse Logik, welche den übergebenen Container auspackt und verarbeitet

 

Controller

class TutorialSysOperationController extends SysOperationServiceController
{
}

 
 

SysOperation-Framework: Einfaches Klassenkonstrukt mit Dataprovider

Der 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;
}

 

Service

class 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 Klassenkonstrukt

Der nachstehende Code stellt ein ganz einfaches Klassenkonstrukt für das SysOperation-Framework dar. Ganz ohne Dataprovider und UIBuilder.

Service

class 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");
}

 

Controller

class 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:

  • Die Funktion wurde im AOT als Service eingebunden
  • Dieses Service wurde zur Servicegruppe AxClient hinzugefügt und bereitgestellt
  • Der Benutzer hat die Option Geschäftliche Arbeitsgänge in CIL ausführen aktiviert

 
 
Seiten « 1 2 3 4 » 

 

 
 
 
Beiträge des aktuellen Monats
März 2024
MoDiMiDoFrSaSo
 123
45678910
11121314151617
18192021222324
25262728293031
 
© 2006-2024 Heinz Schweda | Impressum | Kontakt | English version | Mobile Version
Diese Webseite verwendet Cookies, um Benutzern einen besseren Service anzubieten. Wenn Sie weiterhin auf der Seite bleiben, stimmen Sie der Verwendung von Cookies zu.  Mehr dazu