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

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

AX 2012: LedgerDimension generieren II

Update 11.05.2014: Da die unten stehende Code-Beispiele nicht in allen Applikationen zu funktionieren scheinen, habe ich unter folgendem Beitrag ein weiteres Code-Beispiel veröffentlicht.

Im folgenden ein kurzes Code-Snippet, welches zeigt wie man beispielsweise Finanzdimensionen mit einem Haupt-/Sachkonto zu einer RecId verbindet, welche beispielsweise als LedgerDimension in einer Sachkontenjournal-Zeile (Allgemeine Erfassung; LedgerJournalTrans.LedgerDimension) verwendet werden kann.

static void mergeDimensions(Args _args)
{
    SalesLine salesLine;
    MainAccount mainAccount;
    LedgerDimensionAccount ledgerDimensionAccount;

    // Get source dimension values (for example from SalesLine-Record)
    select firstonly salesLine
    where salesLine.SalesId == "20001"
       && salesLine.DefaultDimension;

    // Get main account
    mainAccount = MainAccount::findByMainAccountId('0500');

    // Merge main account and source dimension values and return RecId which can be used as ledgerDimension
    ledgerDimensionAccount = DimensionDefaultingService::serviceCreateLedgerDimension(mainAccount.RecId, salesLine.DefaultDimension);

    info(strFmt("DefaultDimension (Source RecId): %1 LedgerDimension (Merged RecId): %2", salesLine.DefaultDimension, ledgerDimensionAccount));
}

Das zweite Snippet macht prinzipiell das selbe wie oben, allerdings wird hier statt einem Haupt-/Sachkonto ein Debitorenkonto verwendet.


 
 

Markierte Datensätze eines Formulares verarbeiten/iterieren

Um in Dynamics AX die markierten Datensätze einer Formular-Datenquelle (FormDataSource) zu verarbeiten/iterieren kann folgendes Code-Beispiel helfen:

void markSelected()
{
    inventTrans inventTransSelected;
    inventTrans inventTrans4Update;

    ttsbegin;
    inventTrans4Update.setTmpData(inventTrans);    //DIES IST NUR BEI TEMPORÄREN TABELLEN NOTWEDNIG
    for (inventTransSelected = inventTrans_ds.getFirst(true) ? inventTrans_ds.getFirst(true) : inventTrans_ds.cursor();
         inventTransSelected;
         inventTransSelected = inventTrans_ds.getnext())
    {
        select firstonly forUpdate inventTrans4Update
        where inventTrans4Update.RecId == inventTransSelected.RecId;

        inventTrans4Update.Marked = NoYes::Yes;
        inventTrans4Update.update();
    }
    ttscommit;

    inventTrans_ds.executeQuery();
}

Im Beispiel werden die markierten Datensätze der Tabelle InventTrans durchlaufen und ein Feld Marked auf TRUE aktualisiert.

In Dynamics AX 2012 kann übrigens statt dessen auch die Klasse MultiSelectionHelper dafür verwendet werden.


 
 

Eine Tabelle um ein Passwort-Feld erweitern

Im folgenden eine kurze Anleitung, wie man eine Tabelle um ein Feld erweitert, in welchem ein verschlüsseltes Passwort gespeichert werden kann.

  • Zwei EDTs erstellen
    • Vom Typ Container DEV_ServerPassword, extends CryptoBlog
    • Vom Typ String DEV_ServerPasswordStr (Länge 128)
  • Neues Feld in Tabelle vom EDT DEV_ServerPassword
  • Neue Methode in Tabelle, über diese statische Methode kann später der Wert ausgelesen werden
static DEV_ServerPasswordStr password()
{
    CryptoBlob cryptoBlob = connull();
    ;
    cryptoBlob = DEV_Parameters::find().ServerPassword;
    
    if (cryptoBlob != connull())
        return cryptoblob2str(WinapiServer::cryptUnProtectData(cryptoBlob));
    else
        return '';
}
    
  • Neue Methode in der Datasource der Form
edit DEV_ServerPasswordStr setPassword(boolean _set = false, DEV_ServerPasswordStr _pwd = '')
{
    CryptoBlob cryptoBlob = connull();
    ;
    if (_set && _pwd != 'xxxxxxxx')
    {
        cryptoBlob = WinapiServer::cryptProtectData(str2cryptoblob(_pwd));
    
        DEV_Parameters.ServerPassword = cryptoBlob;
        DEV_Parameters.update();
    }
    
    if (DEV_Parameters.ServerPassword != connull())
    {
        return 'xxxxxxxx';
    }
    else
    {
        return  '';
    }
 }
  • Diese edit()-Methode ins Design des Formulares hineinziehen und auf dem Control die Eigenschaft PasswortStyle=YES setzen

 


 
 

AX 2012: SysOperation-Framework: Security-Hinweis

Wenn man in einer Service-Klasse das Attribute SysEntryPointAttribute auf True gesetzt hat (wie ich dies beispielsweise in diesem Blog-Beitrag getan habe), darf man nicht vergessen, die jeweilige Methode in den Knoten Permissions > Server Methods eines Security-Privileges einzufügen. Nur das Hinzufügen des MenuItems der jeweiligen Controller-Klasse reicht nicht aus! Sonst kann der Benutzer unter Umständen zwar den Dialog der Funktion aufrufen, diese dann aber nicht starten.

Weiters sollte man beachten, daß man Tabellen, die von dieser Klasse verwendet/befüllt werden gleichermassen über ein Privilege berechtigt.

Screenshot Privilege


 
 

Modal Form in Dynamics AX erstellen/aufrufen

Um in Dynamics AX ein Formular modal aufzurufen, kann man folgendes Code-Fragment aus der clicked()-Methode einer Schaltfläche (Button) verwenden:

void clicked()
{
    FormRun formRun;
    Args args = new Args();

    super();
    
    args.name(formStr(MyFormName));
    args.record(SalesLine);

    formRun = classFactory::formRunClassOnClient(Args);

    formRun.init();
    formRun.run();
    If (!formRun.closed())
    {
        formRun.wait(true);
    }
}

Auf diese Art & Weise kann man praktisch jedes Formular als modales - also als ein Formular öffnen, welches erst geschlossen werden muss, bevor mit der Anwendung weitergearbeitet werden kann - öffnen.


 
 

Word-Dokument per Code erstellen II

Microsoft WordAnbei ein einfach gehaltener Job, der ein einfaches Word-Dokument mit Überschriften per Code erstellt. Voraussetzung ist ein lokal installiertes Microsoft Word.

static void CreateWordFile(Args _args)
{
    COM wordApplication;
    COM wordDocuments;
    COM wordDocument;
    COM wordRange;
    COM wordSelection;
    COM wordStyles;
   
    #define.Heading1(-2)
    #define.Heading2(-3)
    #define.Heading3(-4)
    #define.Heading4(-5)
    #define.Heading5(-6)   
   
    void insertHeader(str _str, int _level)
    {
        COM wordStyle;
        wordSelection = wordApplication.selection();

        switch( _level )
        {
            case 1:
                wordStyle = wordStyles.item(#Heading1);
                break;
            case 2:
                wordStyle = wordStyles.item(#Heading2);
                break;
            case 3:
                wordStyle = wordStyles.item(#Heading3);
                break;
            case 4:
                wordStyle = wordStyles.item(#Heading4);
                break;
            case 5:
                wordStyle = wordStyles.item(#Heading5);
                break;
            default:
                wordStyle = wordStyles.item(#Heading3);
        }       
       
        wordSelection.style(wordStyle);

        wordSelection.TypeText(_str);

        wordSelection.TypeParagraph();
    }   
   
    wordApplication = new COM("word.application");
    wordApplication.visible(TRUE);
    wordDocuments = wordApplication.Documents();
    wordDocument = wordDocuments.add();
    wordDocument.saveas(@"c:\temp\LoremIpsum.doc");
    wordDocument.activate();

    wordStyles = wordDocument.styles();

    wordRange = wordDocument.range(0,0);   
   
    // Let's go
    insertHeader("Lorem ipsum", 1);
    wordSelection.TypeText("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam");
    wordSelection.TypeParagraph();
   
    insertHeader("Lorem ipsum", 2);
    wordSelection.TypeText("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam");
    wordSelection.TypeParagraph();
   
    wordSelection.TypeText("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut");
    wordSelection.TypeParagraph();
   
    // Finish
    wordDocument.save();
    wordDocument.close();
    wordApplication.quit();   

}

So sieht das Word-Dokument aus, daß mit obigem Code erstellt wurde:

Lorem Ipsum Word-file


 
 

AX 2012: LedgerDimension generieren

Die folgende Methode erstellt eine sog. LedgerDimension (EDT RecId) unter Verwendung des angebenen Hauptkontos und der angegebenen Finanzdimension.

static recid createLedgerDimensionRecId()
{
    AccountNum accountNum = '60000';
    str 255 dimensionValue = '300';
    Name DimensionName = 'Kostenstelle';
    
    MainAccount MainAccount;
    LedgerDimensionAccount LedgerDimensionAccount;
    DimensionAttributeValue DimensionAttributeValue;
    DimensionAttribute DimensionAttribute;
    dimensionAttributeValueSetStorage dimensionAttributeValueSetStorage;
    dimensionDefault dimensionDefault;
    
    DimensionAttribute = DimensionAttribute::findByName(DimensionName);
    if (dimensionValue)
    {
        DimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(DimensionAttribute, dimensionValue, false, true);
        if (!DimensionAttributeValue)
        {
            throw error(strFmt("@SYS24602", "@SYS13911", dimensionValue));
        }
    }    
    
    // Konto
    MainAccount = MainAccount::findByMainAccountId(accountNum);
    if(MainAccount)
    {
        LedgerDimensionAccount = DimensionDefaultingEngine::getLedgerDimensionFromAccountAndDim(
            MainAccount.RecId,
            DimensionHierarchy::getAccountStructure(MainAccount.RecId));

        if( !LedgerDimensionAccount)
        {
            throw error("LedgerDimensionAccount konnte nicht ermittelt werden.");
        }
    }
    // Konto und Dimension verbinden
    if (DimensionAttributeValue && LedgerDimensionAccount)
    {
        dimensionAttributeValueSetStorage = new DimensionAttributeValueSetStorage();
        if(dimensionAttribute)
        {
            dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, dimensionValue, false, true);
            dimensionAttributeValueSetStorage.addItem(dimensionAttributeValue);
        }
         
        dimensionDefault = dimensionAttributeValueSetStorage.save();
        
        LedgerDimensionAccount =
        DimensionDefaultingService::serviceCreateLedgerDimension(LedgerDimensionAccount, dimensionDefault);
    }
    
    return LedgerDimensionAccount;
}

Wichtig: Die Methode prüft nicht, ob es die Dimension gibt, d.h. werden ungültige Werte für DimensionName oder DimensionValue angegeben, bricht die Methode mir einer Fehlermeldung ab.


 
 
Seiten « 1 ... 24 25 26 27 28 29 30 ... 52 » 

 

 
 
 
Beiträge des aktuellen Monats
Juni 2025
MoDiMiDoFrSaSo
 1
2345678
9101112131415
16171819202122
23242526272829
30 
 
© 2006-2025 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