Dynamics AX Blog - Dynamics AX 2012 - Finanzdimensionen - Seite 2

Momentan angezeigt werden nur Beiträge aus der Serie »Dynamics AX 2012 - Finanzdimensionen« Filter entfernen

In Dynamics AX 2012 hat sich die Handhabung von Finanzdimensionen stark verändert. Und zwar sowohl auf der Oberfläche als auch das dahinterliegende Datenmodell. Wo früher noch ein Feld - meist mit dem Namen Dimension - vom Typ Array in einer Tabelle zu finden war, so findet man nun stattdessen ein von RecId abgeleitetes Feld namens DefaultDimension (o.ä.).

In dieser Serie möchte ich speziell auf diese Änderungen eingehen und das eine oder andere Stück Code präsentieren.

 Beiträge einblenden

RSS-Feed dieser Blogserie

AX 2012: Erstellen einer DefaultDimension mit mehreren Dimensionen

Nachstehend ein Code-Beispiel, wie man eine RecId vom Typ DefaultDimension für mehrere Dimensionen generieren kann.

Im Beispiel werden die Dimension Kostenstelle mit dem Wert "10", die Dimension Abteilung mit dem Wert "IT" und die Dimension Kategorie mit dem Wert "02" zu einer DefaultDimension kombiniert.

Durch den letzten Parameter von findByDimensionAttributeAndValue() wird sichergestellt, daß fehlende Dimensionen angelegt werden (soferne möglich).

static void buildDefaultDimension(Args _args)
{
    dimensionAttributeValueSetStorage dimensionAttributeValueSetStorage;
    dimensionAttribute dimensionAttribute;
    dimensionAttributeValue dimensionAttributeValue;
    dimensionDefault dimensionDefault; 
 
    dimensionAttributeValueSetStorage = new DimensionAttributeValueSetStorage();

    // Kostenstelle
    dimensionAttribute = dimensionAttribute::findByName('Kostenstelle');
    if(dimensionAttribute)
    {
        dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, '10', false, true);
        dimensionAttributeValueSetStorage.addItem(dimensionAttributeValue);
    }

    // Abteilung
    dimensionAttribute = dimensionAttribute::findByName('Abteilung');
    if(dimensionAttribute)
    {
        dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, 'IT', false, true);
        dimensionAttributeValueSetStorage.addItem(dimensionAttributeValue);
    }

    // Kategorie
    dimensionAttribute = dimensionAttribute::findByName('Kategorie');
    if(dimensionAttribute)
    {
        dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, '02', false, true);
        dimensionAttributeValueSetStorage.addItem(dimensionAttributeValue);
    }

    dimensionDefault = dimensionAttributeValueSetStorage.save();

    info(strFmt("Default dimension recId: %1", dimensionDefault));

 

 
 

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.


 
 

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.


 
 

AX 2012: Nützliche Funktionen rund um das Thema Finanzdimensionen

Wenn man in AX beispielsweise Finanzdimensionen aus einer externen Quelle verarbeiten soll, dann können die beiden folgenden Methoden möglicherweise hilfreich sein.

Die Erste Methode namens existDimension() prüft ob es die übergebene, benannte Dimension in AX überhaupt gibt und ob der übergebene Dimensionswert ebenfalls gültig ist.

boolean existDimension(str 255 _dimensionName, str 255 _dimensionValue)
{
    boolean isValid = false;
    DimensionAttribute DimensionAttribute;
    DimensionAttributeValue DimensionAttributeValue;
       
    DimensionAttribute = DimensionAttribute::findByName(_dimensionName);           
       
    if(DimensionAttribute)
    {
        DimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(DimensionAttribute, _dimensionValue);
           
        if(DimensionAttributeValue)
        {
            isValid = true;   
        }
        else
        {
            isValid = checkFailed(strFmt("'%1' für Dimension '%2' nicht gefunden.", _dimensionValue, _dimensionName));       
        }
    }           
    else
    {
        isValid = checkFailed(strFmt("Dimension '%1' unbekannt.", _dimensionName));   
    }
    return isValid;
}

Beispielaufruf: existDimension("Costcenter", "3100");

Die Zweite Methode namens existDimensionCombination() prüft, ob die Kombination des übergebenen Hauptkontos und des übergebenen Dimensionswertes gültig ist.

boolean existDimensionCombination(str 255 _mainAccount, str 255 _dimensionName, str 255_dimensionValue)
{
    boolean isValid = false;
    FinancialDimensionValidationService FinancialDimensionValidationService;
    ledgerAccountValidationContract ledgerAccountValidationContract;
    ledgerAccountContract ledgerAccountContract;
    dimensionAttributeValueContract dimensionAttributeValueContract;
      
    FinancialDimensionValidationService = new FinancialDimensionValidationService();

    ledgerAccountValidationContract = new LedgerAccountValidationContract();
    ledgerAccountContract = new LedgerAccountContract();
    dimensionAttributeValueContract = new DimensionAttributeValueContract();
    ledgerAccountContract.parmMainAccount(_mainAccount);
    ledgerAccountContract.parmValues(new List(Types::Class));
    dimensionAttributeValueContract.parmName(_dimensionName);
    dimensionAttributeValueContract.parmValue(_dimensionValue);
    ledgerAccountContract.parmValues().addEnd(dimensionAttributeValueContract);
    ledgerAccountValidationContract.parmLedgerAccount(ledgerAccountContract);
       
    isValid = FinancialDimensionValidationService.validateLedgerAccount(ledgerAccountValidationContract);   
       
    if( !isValid)
    {
        error(strFmt("Ungültige Kombination: %1 - %2: %3", _mainAccount, _dimensionName, _dimensionValue));   
    }
      
    return isValid;
}

Beispielaufruf: existDimensionCombination("60000", "Costcenter", "3100");

In der realen AX-Entwickler-Welt wird eine solche Prüfung vermutlich etwas komplexer werden und wahrscheinlich auch eine Kombination beider Methoden notwendig sein.


 
 

AX 2012: Standardfinanzdimension eines Datensatzes setzen

Der nachstehende Code soll zeigen, wie man in Dynamics AX 2012 bei einem Datensatz - im Beispiel handelt es sich um einen Debitor - die Standardfinanzdimensionen per X++ befüllen kann.

Im Beispiel werden mehrere Dimensionen mit Werten befüllt. Bitte beachtet, daß die angeführten Dimensionen möglicherweise in Euren AX-Installationen nicht vorhanden sind.

static void setDefaultDimension4CustTable(Args _args)
{
    CustTable custTable;

    RecId getDefaultDimension(container _c)
    {
        DimensionAttribute dimensionAttribute;
        DimensionAttributeValue dimensionAttributeValue;
        DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage;
        int i;
        container dimensionCon;
        Name dimensionName;
        str 255 dimensionValue;

        dimensionAttributeValueSetStorage = new  DimensionAttributeValueSetStorage();

        for (i=1;i<=conLen(_c);i++)
        {
            dimensionCon = conPeek(_c, i);

            dimensionName  = conPeek(dimensionCon, 1);
            dimensionValue = conPeek(dimensionCon, 2);

            select dimensionAttribute
            where dimensionAttribute.Name == dimensionName;

            if(dimensionAttribute)
            {
                dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, dimensionValue, false, true);
                dimensionAttributeValueSetStorage.addItem(dimensionAttributeValue);
            }
        }

        return dimensionAttributeValueSetStorage.save();
    }
    ;

    try
    {
        ttsbegin;
        custTable = CustTable::find('9101', true);
        custTable.DefaultDimension =
            getDefaultDimension([
                                    ["Department",      '100'],
                                    ["Debitor",         '3010'],
                                    ["CustomerGroup",   '80'],
                                    ["ParentProject",   '2000'],
                                    ["CostCenter",      '07']
                                ]);

        custTable.update();
        ttscommit;

        info("Update custtable.defaultDimension sucessfull.");
    }
    catch
    {
        throw error("Error occured");
    }
}

 
 

AX 2012: Standardfinanzdimension eines Datensatzes auslesen und Inhalt prüfen

Der folgende Job demonstriert, wie man den Inhalt der Standardfinanzdimensionen eines Datensatzes - im Beispiel jene eines Debitoren - per X++ prüft.

Im Beispiel werden die Dimensionen namens CustomerGroup, Debitor und NonExistingDimension als zu prüfen angegeben. Bitte beachtet, daß nicht alle Dimensionen in jeder AX-Instanz vorhanden sind. Vor allem letztere dient lediglich zur Demonstration, wie sich der Code verhält, wenn eine Dimensionen ausgelesen werden soll, die es gar nicht gibt.

static void validateDefaultDimensionValues(Args _args)
{
    CustTable custTable = CustTable::find('9101', true);
    container validateCon;
    container helpCon;
    int ii;

    container getDimensionValue(RecId _dimensionAttributeValueSetRecId, container _c)
    {
        DimensionAttributeValueSetItem dimensionAttributeValueSetItem;
        DimensionAttributeValue dimensionAttributeValue;
        DimensionAttribute dimensionAttribute;
        Common dimensionValueEntity;
        int i;
        Name dimensionName;
        str 255 dimensionValue;
        container retCon;

        for (i=1;i<=conLen(_c);i++)
        {
            dimensionName  = conPeek(_c, i);

            if( !DimensionAttribute::findByName(dimensionName))
                error(strFmt("Dimension %1 not found", dimensionName));

            while select dimensionAttributeValueSetItem
                where   dimensionAttributeValueSetItem.DimensionAttributeValueSet   == _dimensionAttributeValueSetRecId
            {
                // Find the dimension 'value' (DimensionAttributeValue) that the set item points to.
                dimensionAttributeValue = DimensionAttributeValue::find(dimensionAttributeValueSetItem.DimensionAttributeValue);

                // Find the underlying attribute.
                dimensionAttribute = DimensionAttribute::find(dimensionAttributeValue.DimensionAttribute);

                // Use the helper class to obtain a reference to the underlying entity (can be anything)
                dimensionValueEntity = DimensionDefaultingControllerBase::findBackingEntityInstance(
                    curext(),
                    dimensionAttribute,
                    dimensionAttributeValue.EntityInstance);

                if(dimensionAttribute.Name == dimensionName)
                {
                    retCon = conIns(retCon, conLen(retCon)+1, [dimensionAttribute.Name, dimensionAttributeValue.getValue()]);
                }
            }
        }

        return retCon;
    }
    ;

    validateCon = getDimensionValue(custTable.DefaultDimension, ["CustomerGroup", "Debitor", "NonExistingDimension"]);
    for (ii=1;ii<=conLen(validateCon);ii++)
    {
        helpCon = conPeek(validateCon, ii);

        if(conPeek(helpCon, 1) == "CustomerGroup" && conPeek(helpCon, 2) != custTable.CustGroup)
        {
            warning(strFmt("Dimension %1 should be %2.", conPeek(helpCon, 1), conPeek(helpCon, 2)));
        }
        if(conPeek(helpCon, 1) == "Debitor" && conPeek(helpCon, 2) != custTable.AccountNum)
        {
            warning(strFmt("Dimension %1 should be %2.", conPeek(helpCon, 1), conPeek(helpCon, 2)));
        }
        if(conPeek(helpCon, 1) == "NonExistingDimension" && conPeek(helpCon, 2) != custTable.AccountNum)
        {
            warning(strFmt("Dimension %1 should be %2.", conPeek(helpCon, 1), conPeek(helpCon, 2)));
        }
    }
}

 
 

AX 2012: Benutzerdefinierte Finanzdimension anlegen

MIt Hilfe des folgenden Jobs kann in Dynamics AX 2012 ein neuer Eintrag für eine benutzerdefinierte Finanzdimension erstellt werden. Im Beispiel ist der Name der Dimension ParentProject und der einzufügende Wert ist 4600.

static void createCustomDimensionValue(Args _args)
{
    DimensionValueService dimensionValueService;
    DimensionValueContract dimensionValueContract;

    dimensionValueService = new DimensionValueService();
    dimensionValueContract = new DimensionValueContract();
    dimensionValueContract.parmDescription('Project 4500');
    dimensionValueContract.parmValue('4600');
    dimensionValueContract.parmDimensionAttribute('ParentProject');
    if(dimensionValueService.createDimensionValue(dimensionValueContract))
    {
        info(strFmt("Dimension value %1 for dimension %2 created", dimensionValueContract.parmValue(), dimensionValueContract.parmDimensionAttribute()));
    }
}

 
 
Seiten « 1 2 3 » 

 

 
 
 
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