Category: Dynamics AX


Dokumen HelpMicrosoft Dynamics AX 2012 for Developer” dalam bentuk file .chm bisa di unduh di tautan berikut:

“Microsoft Dynamics AX 2012 for Developer” help file in compiled format (.chm) can be downloaded below:

Microsoft Dynamics AX 2012 for Developer.chm

Export security setting dari current AOS:

  1. Administration»Periodic
  2. Data export/import
  3. Fokus ke Definition groups
  4. Input Definition group.
  5. Input Definition group name.
  6. Pilih Standard sebagai Type nya.
  7. Klick Options tab
  8. Cek “Include system tables” checkbox (system tables).
  9. Klik tombol Table setup.
  10. Masukkan daftar tabel:
    1. AccessRightsList* – menyimpan security permissions untuk User groups
    2. UserGroupInfo* – menyimpan User groups
    3. DomainInfo* – menyimpan Domains
    4. UserGroupList – menyimpan anggota User group
    5. UserInfo – menyimpan User AX
    6. SysUserInfo – menyimpan User AX setting.
    7. CompanyDomainList – menyimpan keterhubungan company/domain
  11. Klik tombol Export to.
  12. Pilih lokasi, nama, dan simpan filenya (.dat).
  13. OK

Import ke target AOS:

  1. Administration»Periodic
  2. Buka Data export/import
  3. Pilih Import
  4. Pilih Definition group atau kosongkan saja.
  5. Pilih file .dat yang sudah diexport td.
  6. Ok

Sumber: MSDN

Function monthDiff

Mencari rentang/jumlah bulan dari suatu periode. Masih mencari function terbaik.

int monthDiff(TransDate _fromDate, TransDate _toDate)
{
    TransDate   fromDate = _fromDate, toDate = _toDate;
    int         yrDiff;
    int         totalMonth;
    int         fdtDay = dayofmth(fromDate);
    //int         tdtDay = dayofmth(toDate);
    int         frMth = mthofyr(fromDate);
    int         toMth = mthofyr(toDate);
    int         countMth;
    int         fYear = year(fromDate), tYear = year(toDate);
    date        procDt;
    ;
    yrDiff = yearDiff(toDate, fromDate);

    countMth = frMth;
    totalMonth = 0;

    if(!yrDiff)
    {
        while(fYear<=tYear)
        {
            while(countMth<=12)
            {
                if((fYear == tYear) && (countMth == toMth))
                    break;

                countMth++;
                totalMonth++;
            }
            fYear++;
            countMth = 1;
        }
    }
    else
    {
        tYear = tYear - yrDiff;

        while(fYear<=tYear)
        {
            while(countMth<=12)
            {
                if((fYear == tYear) && (countMth == toMth))
                    break;

                countMth++;
                totalMonth++;
            }
            fYear++;
            countMth = 1;
        }
        totalMonth += (12 * yrDiff);
    }
    procDt =  mkdate(fdtDay,toMth,fYear-1);
    if(!(dayofmth(procDt)<fdtDay))
        procDt--;

    if(toDate<(procDt))
        totalMonth--;
    
    fYear = year(fromDate);
    if(fYear == tYear && frMth == toMth && fromDate == dateStartMth(fromDate) && toDate == dateEndMth(toDate))
        totalMonth++;

     return totalMonth;
}

Program di bawah merupakan contoh progress bar deng tipe multi bar. Tipe ini juga bisa digunakan untuk single bar dengan jumlah array 1. Dalam contoh, bar kedua menggunakan nilai dari bar pertama. Bar kedua dapat disesuaikan dengan kebutuhan misalnya detail/transaksi dari suatu tabel utama (CustInvoiceJour – CustInvoiceTrans).

Progress Bar

static void _atusProgressBar(Args _args)
{
    CustInvoiceJour         custInvoiceJour;
    Query                   q;
    QueryBuildDataSource    qbds;
    QueryRun                qr;
    SysOperationProgress    progressBar;
    int                     totalRow, counter;
    #aviFiles
    ;

    q = new Query();
    qbds = q.addDataSource(tablenum(CustInvoiceJour));

    qr = new QueryRun(q);

    totalRow = SysQuery::countTotal(qr);// Mengambil Total/Jumlah record dari query
    progressBar = SysOperationProgress::newMultiBar(2,#aviUpdate,"Progress");
    progressBar.setTotal(totalRow,1);
    progressBar.setTotal(totalRow,2);

    while(qr.next())
    {
        custInvoiceJour = qr.get(tablenum(CustInvoiceJour));
        counter++;

        progressBar.setCount(counter,1);
        progressBar.setText(strfmt("Record Processed 1: %1 - %2", counter, custInvoiceJour.InvoiceId),1);

        progressBar.setCount(counter,2);
        progressBar.setText(strfmt("Record Processed 2: %1 - %2", counter, custInvoiceJour.InvoiceId),2);
    }
    progressBar.kill();
}

Untuk memodifikasi atau membentuk range yang agak spesifik dibutuhkan syntax yang khusus. Di bawah merupakan salah satu contoh untuk memberikan filter antara dua field dalam satu tabel dimana salah satu data dalam field yang berbeda memenuhi syarat maka akan ditampilkan dalam dialog info.
Field apa saja dapat digunakan sebagai field range. Yang terpenting adalah ekspresi dari query range tersebut. Untuk membentuk suatu ekspresi harus memenuhi persyaratan:

  • Expresi harus dibuka dan ditutup dengan menggunakan single-quotes( ‘ ).
  • Semua ekspresi dan sub ekspresi harus dibuka dan ditutup dengan buka dan tutup kurung.
  • Kalau hanya menggunakan satu table, nama tabel tidak perlu di sebutkan, cukup dengan nama field.
  • Untuk tabel harus menggunakan nama datasource, bukan nama table.
  • Nilai String, bisa menggunakan string biasa dan diberi double-quotes (“), atau menggunakan queryValue().
  • Untuk nilai Base Enum, berikan nilai integernya dengan fungsi any2int() atau enum2int().
  • Untuk nilai tanggal harus menggunakan fungsi Date2StrXpp().
  • Gunakan valueEmptyString pada class SysQuery (SysQuery::valueEmptyString())
static void _atusExperiment(Args _args)
{
    CustInvoiceJour         custInvoiceJour;
    Query                   q;
    QueryBuildDataSource    qbds;
    QueryBuildRange         qRange;
    QueryRun                qr;
    TransDate               invDate, dueDate;
    str                     rangeValue;
    ;
    invDate = 011\2011;
    dueDate = 033\2011;

    q = new Query();
    qbds = q.addDataSource(tablenum(CustInvoiceJour));
    qRange = qbds.addRange(fieldnum(CustInvoiceJour, InvoiceId));

    rangeValue = '((%1.%2==%3) || (%1.%4==%5))';
    rangeValue = strfmt(rangeValue,
            qbds.name(),
            fieldstr(CustInvoiceJour, InvoiceDate) , Date2StrXpp(invDate),
            fieldstr(CustInvoiceJour, DueDate), Date2StrXpp(dueDate)
    );

    qRange.value(rangeValue);

    qr = new QueryRun(q);
    while(qr.next())
    {
        custInvoiceJour = qr.get(tablenum(CustInvoiceJour));
        info(strfmt("%1 - %2 - %3", custInvoiceJour.InvoiceId, custInvoiceJour.InvoiceDate, custInvoiceJour.DueDate));
    }
}

Sumber: Axaptapedia, Developing for Dynamics AX: Using Expressions in Query Ranges

Berikut method-method yg sering digunakan pada report.

public class ReportRun extends ObjectRun
{
     TransDate           fromDate;
     TransDate           toDate;
     real                subtotalQty, totalQty, subtotal, total,Qty;

     DialogField         dialogFrom;
     DialogField         dialogTo;

     #DEFINE.CurrentVersion(1)
     #LOCALMACRO.CurrentList
          fromDate,
          toDate
     #ENDMACRO
}

public Object dialog(Object _dialog)
{
     DialogRunBase dialog = _dialog;
     ;

     dialog.addGroup("@SYS40");
     dialogFrom = dialog.addFieldValue(typeid(FromDate),fromDate,"@SYS5209","@SYS5209");
     dialogTo = dialog.addFieldValue(typeid(ToDate), toDate,"@SYS14656","@SYS14656");
     return dialog;
}

public boolean getFromDialog()
{
     ;
     fromDate = dialogFrom.value();
     toDate = dialogTo.value();

     return true;
}
public container pack()
{
     return [#CurrentVersion, #CurrentList];
}
public boolean unpack(container packedClass)
{
     boolean _ret;
     Integer version = conpeek(packedClass,1);
     ;

     switch(version)
     {
          case #CurrentVersion:
               [version, #CurrentList] = packedClass;
               _ret = true;
               break;
          default:
               _ret = false;
               break;
     }
     return _ret;
}
boolean validate(Object calledFrom)
{
     boolean ret = true;
     if(fromdate == datenull())
          ret = checkfailed('From Date Must Be Entered');

     return ret;
}
public Query initQuery(Query _query)
{
     QueryBuildDataSource queryBuildDataSource;
     QueryBuildRange queryBuildRange;
     ;
     //memberikan nilai default pada query selection/range
     queryBuildDataSource = _query.dataSourceTable(tablenum(InventTable));
     queryBuildDataSource.clearRange(fieldnum(InventTable, ItemGroupId));
     queryBuildRange = queryBuildDataSource.findRange(fieldnum(InventTable, ItemGroupId));
     if(!queryBuildRange)
          queryBuildRange = queryBuildDataSource.addRange(fieldnum(InventTable, ItemGroupId));
     queryBuildRange.value('RM_ES,RM_MM,RM_PC');

     return _query;
}

Manfaat yg bisa didapat:

  • Dapat memanfaatkan Object Query yg sudah ada sehingga tidak perlu membuat object Query yg baru yang isinya fungsi agregat.
  • Tidak perlu membuat perintah SQL yang baru yang maksud dan fungsinya sama dengan Object Query yang dimaksud.
  • Akan sangat bermanfaat bila Object Query-nya merupakan join dari beberapa table.

Contoh AOT Job…

static void atus12(Args _args)
{
     Query q;
     QueryRun qr;QueryBuildDataSource qbd;
     QueryBuildFieldList qfl;
     EmplTable ep;
     int i;
     ;

     qr = new QueryRun(queryStr(EmployeeListAtus));
     //'EmployeeListAtus' merupakan contoh Object Query dari AOT
     q = qr.query();
     qbd = q.dataSourceTable(tablenum(EmplTable));
     qfl = qbd.fields();
     /*
     Command berikut untuk menambahkan fungsi agregat pada query.
     Fungsi Agregat : Count, Max, Min, Avg, Sum.
     Fungsi Count sebaiknya di asign pada RecId sebab RecId merupakan Int64, sisanya(fungsi) disesuaikan dengan fieldnya masing2.
     */
     qfl.addField(fieldnum(empltable,RecId),SelectionField::Count);
     qr.next();
     ep = qr.get(tablenum(empltable));
     info(strfmt("%1",ep.RecId)); //Akan menampilkan Jumlah Row...
     qfl.clearFieldList();
     qr.reset();
     i = 0;
     while(qr.next())//Akan menampilkan semua Employee ID sesuai dengan query
     {
          i++;
          ep = qr.get(tablenum(empltable));
          info(strfmt("%1 - %2",i,ep.EmplId));
     }
}