Dynamics AX Blog - Dynamics AX 2012 - Seite 34

Momentan angezeigt werden nur Beiträge, welche für die Dynamics AX-Version »Dynamics AX 2012« relevant sind. Filter entfernen

RSS-Feed dieser Version

AX 2012: Einen Bericht mit den SQL Reporting Services erstellen

Mit der Version Dynamics AX 2012 halten die SQL Reporting Services (SSRS) nun endgültig Einzug im Leben eines jeden AX-Entwicklers. Zeit also, sich mit diesem Thema etwas intensiver zu beschäftigen. Die Ergebnisse meiner ersten Gehversuche mit den SSRS präsentiere ich Euch nun in diesem Beitrag.

Szenario: Es soll ein Bericht erstellt werden, bei welchem der Umsatz pro Verkaufsgruppe ausgewertet werden kann.

 

Schritt 1: Erstellen eines Queries in Dynamics AX

Ich gehe davon aus, daß der geneigte Leser schon einmal einen Query erstellt hat, deshalb werde ich darauf nur sehr oberflächlich eingehen.

Basis-Tabellen meines Queries sind die Tabellen
  • CustInvoiceTrans
  • CustInvoiceJour
  • CommissionSalesGroup

Die Tabelle CustInvoiceTrans wird per InnerJoin mit der CustInvoiceJour über die im Screenshot gezeigten Felder verknüpft, die Tabelle CommissionSalesGroup wird per OuterJoin über das Feld SalesGroup verknüpft.

  Query

Seit AX 2012 muss die Eigenschaft Dynamic der Fields-Gruppe aller beteiligten Tabellen entsprechend gesetzt werden, im einfachsten Fall wird diese auf Yes gesetzt, um im Visual Studio später alle Felder der Tabellen verwenden zu können.


 
 

Datensatzvorlagen ermitteln

Wer einmal in die Verlegenheit kommt, ermitteln zu müssen ob für eine bestimmte Tabelle Datensatzvorlagen vorhanden sind, für den kann folgendes Code-Beispiel hilfreich sein.

Im Beispiel wird ermittelt, wieviele Benutzer- bzw. Unternehmensvorlagen es für die Tabelle InventTable gibt und ob der aktuelle Benutzer sich den Vorlagendialog anzeigen lässt, wenn er/sie einen neuen Artikel anlegt.

static void SysRecordTemplatesActive(Args _args)
{
    tableId tableId = tableNum(inventTable);
    common common = new sysdictTable(tableId).makeRecord();
    SysRecordTemplateStorageUser storageUser       = SysRecordTemplateStorage::newCommon(common, SysRecordTemplateType::User);
    SysRecordTemplateStorageCompany storageCompany = SysRecordTemplateStorage::newCommon(common, SysRecordTemplateType::Company);
    sysRecordTemplateSelect sysRecordTemplateSelect;
    container userTemplates;
    container companyTemplates;
    ;
    // Liste der Vorlagen
    userTemplates = storageUser.get();
    info(strFmt("Anzahl Benutzervorlagen für Tabelle %1: %2", new sysdictTable(tableId).label(),
                                                              conLen(userTemplates)));

    companyTemplates = storageCompany.get();
    info(strFmt("Anzahl Unternehmensvorlagen für Tabelle %1: %2", new sysdictTable(tableId).label(), 
                                                                  conLen(companyTemplates)));
    
    // Soll der aktive Benutzer nach Vorlagen gefragt werden?
    sysRecordTemplateSelect = SysRecordTemplateSelect::newTableId(tableId);
    sysRecordTemplateSelect.load();
    
    info(strFmt("Datensatzvorlagen für die Tabelle %1 in Verwendung: %2", new sysdictTable(tableId).label(),
                                                                          enum2str(sysRecordTemplateSelect.parmPrompt()))); 
}

 
 

AX 2012: Having-Clause über addHavingFilter

Ein neues Feature von Dynamics AX 2012 ist, daß man nun bei einem Query auch eine HAVING-Clause hinzufügen kann.

Diese Bedingung dient dazu, berechnete Werte einer GROUP BY-Clause in der WHERE-Clause berücksichtigen zu können. Dieses Feature habe ich in der Vergangenheit vor allem dazu gerne verwendet, wenn es darum ging über eine SQL-Abfrage doppelte (bzw. vielfache) Datensätze in einer Tabelle zu finden. In den bisherigen Versionen von Dynamics AX war dieses Unterfangen über X++ nur etwas umständlich abzubilden.


 
 

AX 2012: AddQueryFilter

In Dynamics AX 2012 verfügt das Query-Objekt nun über eine neue Methode addQueryFilter, mit dessen Hilfe man die Datenbank anweisen kann, Filterkriterien zur WHERE-Clause statt wie in bisherigen Versionen zur ON-Clause einer OUTER-JOIN-Verknüpfung hinzuzufügen. Dies wiederum bewirkt, daß keine "leeren" Datensätze verarbeitet werden.


 
 

AX 2012: ValidTimeState

Wer schon einmal eine Tabelle aufbauen musste, wo die einzelnen Datensätze über Datumsfelder nur für einen bestimmten Zeitraum gültig sind - ähnlich den Handelsvereinbarungen -, weiß wieviel Entwicklungsaufwand daintersteckt, wenn sichergestellt werden muss, daß sich die Gültigkeitsbereiche der einzelnen Datensätze nicht überschneiden.

Dynamics AX 2012 stellt hierfür eine neue Tabelleneigenschaft validTimeStateFieldType zur Verfügung, mit deren Hilfe sich Dynamics AX selbst um vieles kümmert.

Beim Anlegen einer solchen Tabelle muss nur auf die folgenden Punkte geachtet werden:

  1. Eigenschaft ValidTimeStateFieldType der Tabelle auf Date oder UtcDateTime setzen. Dadurch erstellt AX zwei neue Felder ValidFrom und ValidTo in der Tabelle.


     
  2. Man muss einen eindeutigen Index erstellen, der die entscheidenden Felder der Tabelle sowie die Felder ValidFrom und ValidTo enthält.


     
  3. Bei diesem Index müssen bestimmte Eigenschaften gesetzt werden.

 

Ab diesem Zeitpunkt kümmert sich Dynamics AX vollständig um das Aktualisieren von nicht mehr gültigen Datensätzen und die entscheidenden Prüfungen beim Anlegen von neuen Datensätzen.

Aber auch das Selektieren des jeweils gültigen Datensatzes für ein bestimmtes Datum wird wesentlich erleichert. Dafür stellt Dynamics AX das Keyword validTimeState zur Verfügung.

static void AX2012_ValidTimeStateUtcDateTime(Args _args)
{
    AX2012_ValidTimeStateUtcDateTime AX2012_ValidTimeStateUtcDateTime;
    utcDateTime myUtcDateTime = 1988-07-20T13:34:45;
    ;
    select validTimeState(myUtcDateTime) *
    from AX2012_ValidTimeStateUtcDateTime;

    info(strFmt("%1", AX2012_ValidTimeStateUtcDateTime.salesPrice));
}

 


 
 

Arbeiten mit dem aufrufenden Objekt einer Form (Caller) II

Um in einem Objekt auf das aufrufende Objekte zuzugreifen, habe ich anhand von einigen Zeilen Code ja schon demonstriert (siehe hier und hier). Dabei hatte ich aber immer ausser Acht gelassen, daß das aufrufende Objekt ja auch eine Klasse sein kann.

Nun also hier ein entsprechendes Beispiel:

if (element.args() && 
    element.args().caller() && 
    classidget(element.args().caller()) == classnum(nameOfClass )) 
{
    nameOfClass = element.args().caller();
    someValue = nameOfClass.someMethod();
}

 
 

Tipp: Label eines Extended Datatypes (EDT) ermitteln

Manchmal braucht man einfach nur den Label eines Extended Datatypes (EDT), um diesen zum Beispiel als Bestandteil einer Info-/Fehlermeldung ausgeben zu können:

new SysDictType(extendedtypenum(costingversionid)).label()

 
 
Seiten « 1 ... 31 32 33 34 35 36 37 38 » 

 

 
 
 
Beiträge des aktuellen Monats
April 2024
MoDiMiDoFrSaSo
1234567
891011121314
15161718192021
22232425262728
2930 
 
© 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