Axcapta etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Axcapta etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

18 Eylül 2014 Perşembe

AX 2012 Microsoft Dynamics Form Multiple Selected Records (Seçilen kayıtlarda dönme işlemi)

Form üzerinde bulunan Grid deki seçilmiş olan kayıtlarda işlem yapabilmek için aşağıdaki kodu yazmamış. Yeterli olacaktır.

Örnek Kod, Buttonun click olayına yazıldı. Bunu istersek class ile de yapabiliriz.

Seçili olan kayıtları döner...
void clicked()
{
    WMSOrderTrans   WMSOrderTransLocal;
    FormDataSource WMSOrderTransDs;
    ;
    super();
    WMSOrderTransDs = WMSOrderTrans.dataSource();
    for (WMSOrderTransLocal = WMSOrderTransDs.getFirst(true) ?
    WMSOrderTransDs.getFirst(true) :
    WMSOrderTransDs.cursor();
    WMSOrderTransLocal;
    WMSOrderTransLocal = WMSOrderTransDs.getnext())
    {
        info(strfmt("%1",WMSOrderTransLocal.RecId));
    }
    WMSOrderTransDs.reread();
    WMSOrderTransDs.refresh();
}




Tüm Kayıtları dönmek için kullanılabilir.
void clicked()
{
    WMSOrderTrans   WMSOrderTransLocal;
    FormDataSource WMSOrderTransDs;
    ;
    super();
    WMSOrderTransDs = WMSOrderTrans.dataSource();
WMSOrderTransLocal = WMSOrderTransDs.getFirst();
while (WMSOrderTransLocal)
{
info(strfmt("%1",WMSOrderTransLocal.RecId));

WMSOrderTransLocal = WMSOrderTransDs.getnext();
}
    WMSOrderTransDs.reread();
    WMSOrderTransDs.refresh();
}



Ali Güç

17 Eylül 2014 Çarşamba

Genel Muhasebe > Mali Boyutlar a Tablo boyutu eklemek

(ŞirketAdı)/Genel muhasebe/Kurulum/Mali Boyutları/

AOT > DataDictionary > Views açılır.

Örneğimizde BankChequeTable_TR tablosu ile işlem yapacağız.

  1. AOT açılır.
  2. DataDictionary > Views de "Yeni Views" denir. Name : DimAttributeBankChequeTable_TR verilir.
  3. Metadata da data source olarak  BankChequeTable_TR tablosu gösterilir.
  4. DimAttributeBankChequeTable_TR properties kısmında "Label : Çek ve senetler" yazılır.
  5. DimAttributeBankChequeTable_TR properties kısmında "Singular Label: Çek ve senetler" yazılır.
  6. DimAttributeBankChequeTable_TR properties kısmında "FormRef : BankChequeTable_TR" yazılır.
  7. Fields
    1. Key
      Datasource : BackingEntity(BankChequeTable_TR)
      Datafield    : RecId
    2. Value
      Datasource : BackingEntity(BankChequeTable_TR)
      Datafield    : ChequeNum
    3. Name
      Datasource : BackingEntity(BankChequeTable_TR)
      Datafield    : ChequeNum
  8. Yeni bir job oluşturulur. (Yada AOS servis Restart edilir.)
    static void DimensionCacheRefresh(Args _args)
    {
        DimensionCache::clearAllScopes();
        info("Tamamdır");
    }
 Ekran Görüntüleri.



static void DimensionCacheRefresh(Args _args)
{
    DimensionCache::clearAllScopes();
    info("Tamamdır");
}

Ali Güç

15 Eylül 2014 Pazartesi

Dynamics AX 2012 Hide Parameters for SysOperation and SSRS (SysOperation ve SSRS için Gizli Parametre)

SSRS ve SysOperation class yapısı birbirine çok benzer bir şekilde çalışmaktadır. Contract classındaki bir paramerenin görünmesini istemediğimizde SysOperationControlVisibilityAttribute(false) kodundan yararlanıyoruz.


Örnek :

[DataMemberAttribute,SysOperationDisplayOrderAttribute('3'), SysOperationControlVisibilityAttribute(false)]
public ETGCollateralNum parmCollateralNum(ETGCollateralNum _collateralNum = collateralNum)
{
    ;
    collateralNum = _collateralNum;
    return collateralNum;
}

8 Eylül 2014 Pazartesi

Table Find Method

Geliştirmeler de bir table yazılırken fieldlar tanımlandıktan sonra yazılan index e uygun olarak yazılması gereken en önemli methodlardandır.


//Standart findRecId methodu
static ETGTableName findRecId(RecId    _recId, boolean  _forUpdate = false)
{
    ETGTableName ETGTableName;
    ;
    if (_recId)
    {
        ETGTableName.selectForUpdate(_forUpdate);

        select firstonly ETGTableName
            where ETGTableName.RecId == _recId;
    }
    return ETGTableName;
}

//Standart find methodu
static ETGTableName find(ETGTableNameID _nameId, boolean  _forUpdate = false)
{
    ETGTableName ETGTableName;
    ;
    if (_nameId)
    {
        ETGTableName.selectForUpdate(_forUpdate);

        select firstonly ETGTableName
            where ETGTableName.NameId== _nameId;
    }
    return ETGTableName;
}

//Parametre tablosu find methodu
static ETGParameterTableName find(boolean _forupdate = false)
{
    ETGParameterTableName parameter;
    ;
    try
    {
        parameter.selectForUpdate(_forupdate);

        select firstonly parameter
            index KeyIdx
            where parameter.Key == 0;
        if (!parameter && !parameter.isTmp())
        {
            Company::createParameter(parameter);
        }
    }
    catch (Exception::DuplicateKeyException)
    {
        retry;
    }
    return parameter;
}

SysOperation Framework VS RunBaseBatch

SysOperation Framework

Nedir, ne zaman kullanılır.

Danışmanların hazırladıkları dökümanlarda aşağıdaki cümleleri sıkça duyarız
·          Butona basınca bir ekran açılsın , raporlarda olduğu gibi solda tarih vs.. alanlar seçebilsin , sağda ise CustTable dan müşterileri seçebilsin. Oklediğinde seçtiği müşteriler için ……. İşlemleri yapılsın.
·          Bir işlem olsun günlük ,saatlik olarak kendi kendine çalışsın. Müşterilere kendi ekstrelerini her pazartesi mail atsın gibi.

Bu tür kendi kendine tekrar eden işler veya özellikle seç butonundan kullanıcının belli kayıtları filtrelemesi gibi istekler için çözüm Ax içerisinde mevcuttur.
AX 2012 de böyle bir yapıyı kurmak için kullanacağımız yapının ismi SysOperation Framework tür. Çok basit ve öğrenmesi çok  kolaydır. çünkü bir rapor için kullandığımız Contract UIBuilder classları çok benzer şekilde bu frameworkte kullanılmaktadır. DP class ının bir benzeri burada Service classı olarak geçer. Bunun detaylarına ilerleyen bölümlerde değineceğiz.
AX 2009 da ise bu yapıyı RunBase ve RunBaseBatch classları ile yapabiliriz. AX 2012 dede RunBase yapıları bulunmaktadır fakat sonraki versiyonda desteklenmeyeceği için bu yapıyı AX 2012 de kullanmamalıyız.

Dynamics 2012


 


ETGTutorialSysOperationQueryContract

[DataContractAttribute]
class ETGTutorialSysOperationQueryContract
{
    Name            name;
    BirthDate       birthDate;
    str             packedQuery;
}
public Query getQuery()
{
     return new Query(SysOperationHelper::base64Decode(packedQuery));
}
[DataMemberAttribute
,SysOperationLabelAttribute(literalStr("Doğum Tarihi"))]
public BirthDate parmBirthDate(BirthDate _birthDate = birthDate)
{
    birthDate = _birthDate;
    return birthDate;
}
[DataMemberAttribute,SysOperationLabelAttribute(literalStr("Ad Soyad"))]
public Name parmName(Name _name = name)
{
    name = _name;
    return name;
}
[DataMemberAttribute,
     AifQueryTypeAttribute('_packedQuery', querystr(CustTable))
]
/*
    QUERY KENDİ QUERYNE GÖRE AYARLA
*/
public str parmQuery(str _packedQuery = packedQuery)
{
     packedQuery = _packedQuery;
     return packedQuery;
}
public void setQuery(Query _query)
{
     packedQuery = SysOperationHelper::base64Encode(_query.pack());
}

ETGTutorialSysOperationQueryController


class ETGTutorialSysOperationQueryController extends SysOperationServiceController
{
}
protected ClassDescription defaultCaption()
{
    // This will be the dialog's caption
    return 'SysOperation demo';
}
protected void new()
{
    // This tells the controller what method it should execute as the service. In this case, we'll run SysOperationDemoService.performDemo()
    super(classStr(ETGTutorialSysOperationQueryService), methodStr(ETGTutorialSysOperationQueryService, process), SysOperationExecutionMode::Synchronous);
}
public void run()
{
    info('Run method has been called');

    super();
}
protected boolean validate()
{
    ETGTutorialSysOperationQueryContract    contract;
    boolean                         ret = true;

    contract = this.getDataContractObject();

    if (contract.parmBirthDate()> DateTimeUtil::date(DateTimeUtil::addYears(DateTimeUtil::utcNow(), -18)))
    {
        // Failing the validate will not close the dialog, and the user will have another chance of inputting the correct values
        ret = checkFailed('The user is underage!');
    }

    return ret;
}
public static ETGTutorialSysOperationQueryController construct()
{
    ETGTutorialSysOperationQueryController      controller;

    controller = new ETGTutorialSysOperationQueryController();

    controller.parmShowDialog(true); // Actually the default value
    controller.parmShowProgressForm(false);

    return controller;
}
public static void main(Args _args)
{
    ETGTutorialSysOperationQueryController controller;

    controller = ETGTutorialSysOperationQueryController::construct();

    controller.startOperation();
}

ETGTutorialSysOperationQueryService

class ETGTutorialSysOperationQueryService extends SysOperationServiceBase
{
}
public str process(ETGTutorialSysOperationQueryContract _contract)
{
    str info = strFmt('%1 was born in %2', _contract.parmName(), _contract.parmBirthDate());
    QueryRun    queryRun;
     CustTable   custTable;
     ;
     // create a new queryrun object
     queryRun = new queryRun(_contract.getQuery());

     // loop all results from the query
     while(queryRun.next())
     {
         custTable = queryRun.get(tableNum(custTable));

         // display the accountnum
         info(custTable.AccountNum);
     }

     info(info);
    return info;
}

Dynamics 2009 

Bu class bir görevi toplu çalıştırmak için kullanılmaktadır. Örnek olarak Tutorial_RunbaseForm
 classını inceleyelim. (Bknz.Resim 03)
                                Tutorial_RunbaseForm classını çalıştırdığımızda aşağıdaki ekran çıktısı alınmaktadır. Ekranda baktığımızda tarih ve müşteri hesabının seçildiği bir parametreler grubu bulunmaktadır ve ayrıca bir Query üzerinde seçim yapabileceğimiz bir seç butonu bulunmaktadır.

Resim 03
Aşağıda AX’ın standartında olan bir toplu görev işlemini yapan bir class bulunmaktadır.  Tutorial_RunbaseForm görüntüsü bulunmatadır. (Bknz. Resim 04)
Resim 04

Kendimize ait bir çalışma yapacak olursak, Tutorial_RunbaseForm classını sağ tıklayıp Çoğalt(Duplicate) yaparak CopyTutorial_RunbaseForm yapabiliriz. Çoğaltılan classın adını ETGRunbaseFormEgitim olarak değiştirelim.

RunBaseBatch Class                               

class ETGRunbaseFormEgitim extends RunBaseBatch
{
    // Packed
    TransDate       transDate;
    CustAccount     custAccount;

    SysQueryRun     queryrun;

    DialogField     dlgtransDate;

    #define.CurrentVersion(1)
    #define.Version1(1)
    #localmacro.CurrentList
        transDate,
        custAccount
    #endmacro
}
public boolean canGoBatch()
{
    return true;
}
public Object dialog()
{
    DialogRunbase   dialog = Dialog::newFormnameRunbase(formstr(ETGRunbaseFormEgitim),this);
;
    dialog = this.dialogInternal(dialog);
    dlgtransDate = dialog.addField(extendedTypeStr(TransDate));
    dlgtransDate.value(transDate);
    return dialog;
}
public boolean getFromDialog()
{
    boolean ret;
    ret = super();
    transDate = dlgtransDate.value();
    // custAccount is handled via the edit method on the form
    return ret;
}
public void initParmDefault()
{
    this.initQuery();
    super();
}
void initQuery()
{
    Query   query = new Query();
;
    query.addDataSource(tablenum(InventTable));
    queryrun = new SysQueryRun(query);
}
protected void new()
{
    super();
}
public container pack()
{
    return [#CurrentVersion,#CurrentList,queryrun.pack()];
}
CustAccount parmCustAccount(CustAccount _custAccount  = custAccount)
{
;
    custAccount = _custAccount;
    return custAccount;
}
QueryRun queryrun()
{
    return queryrun;
}

public boolean runsImpersonated()
{
    return true;
}
public boolean showQueryValues()
{
    return true;
}
public boolean unpack(container packedClass)
{
    Version     version = RunBase::getVersion(packedClass);
    container   queryCon;
    switch (version)
    {
        case #CurrentVersion;
            [version,#CurrentList,queryCon] = packedClass;
            if (SysQuery::isPackedOk(queryCon))
                queryrun = new QueryRun(queryCon);
            else
                this.initQuery();
            break;
        default:
            return false;
    }
    return true;
}
server static ETGRunbaseFormEgitim construct()
{
    return new ETGRunbaseFormEgitim();
}
server static void main(Args args)
{
    ETGRunbaseFormEgitim   ETGRunbaseFormEgitim = ETGRunbaseFormEgitim::construct();
    if (ETGRunbaseFormEgitim.prompt())
        ETGRunbaseFormEgitim.run();
}

Excelden Veri Aktarımı

Axapta üzerinde bazen dışarıdan tablolara veri aktarımı yapmak durumunda kalırız. Bunun için Ax 2012 dışarıdan veri aktarımı için bir çok yöntem vardır. Genellikle danışmanların kullandığı yöntem olan Axapta 2009 da içe aktar yöntemi Ax 2012 de yerini Excelin bi aracı olan “Excel Add-İns” e bırakmıştır. Bu araç ile ile tablolara rahat olarak aktarım yapılabilmektedir.
Ancak bazı durumlarda bir şablon yardımıyla son kullanıcı içeri veri almak isteyebilir. Bu gibi durumlar için de Excel veya CSV ile Axapta tablolarına veri aktarmak gerekebilir. Bu konuda Excel ile aktarmayı anlatacağım. Birbirine benzesede bir sonraki konuda da csv ile aktarmadan bahsedeceğim.

Örneğin basit ve anlaşılabilir olması açısından kendi oluşturduğum bir tabloya kayıt atacağım.
excel veri aktarımı
Excel şablonu aşağıdaki gibi olacaktır.
excel veri aktarımı
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
</span></span>
<pre><pre>static void Erkn_ExcelVeriAktarimi(Args _args)
{
   SysExcelApplication application;
    SysExcelWorkbooks   workbooks;
    SysExcelWorkbook    workbook;
    SysExcelWorksheets  worksheets;
    SysExcelWorksheet   worksheet;
    SysExcelCells       cells;
    COMVariantType      type;
    int                 row;
    FileName            filename;
    Dialog              dialog;
    dialogfield         dfile;
    TestExcelAktarim    testExcelAktarim;
    ItemId              itemId;
    Name                name;
    Qty                 qty;
    SalesPrice          price;
    TransDate           transDate;
    ;
    application = SysExcelApplication::construct();
    workbooks   = application.workbooks();
    Dialog = new dialog("Dosya seçin");
    dialog.filenameLookupFilter(['xls,xlsx','*.xls;*.xlsx']); //Seçilecek dosyanın uzantıları ayarlanır
    dfile  = dialog.addField(extendedTypeStr(FileNameOpen),"Dosya"); //Dosya seçme dialoğu çıkartır
    if(!dialog.run())
        return;
    filename = dfile.value();
    if(filename == "")
        throw error("Dosya adı belirtilmemiş");
    try
    {
        workbooks.open(filename);
    }
    catch (Exception::Error)
    {
        throw error("File cannot be opened.");
    }
    workbook    = workbooks.item(1);
    worksheets  = workbook.worksheets();
    worksheet   = worksheets.itemFromNum(1);
    cells       = worksheet.cells();
    row = 1; //Baslık satırı
    ttsbegin;
    do
    {
        row++;
        //Degisken = cells.item(satırsırası,sütunsırası).excelden dönentipi belirtilir
        itemId     = cells.item(row, 1).value().bStr();
        name       = cells.item(row, 2).value().bStr();
        qty        = cells.item(row, 3).value().double();
        price      = cells.item(row, 4).value().double();
        transDate  = cells.item(row, 5).value().date();
        testExcelAktarim.clear();
        testExcelAktarim.ItemId    = itemId;
        testExcelAktarim.Name      = name;
        testExcelAktarim.Qty       = qty;
        testExcelAktarim.Price     = price;
        testExcelAktarim.TransDate = transDate;
        testExcelAktarim.insert();
        type = cells.item(row+1, 1).value().variantType();
    }
    while (type != COMVariantType::VT_EMPTY); // kayıtların bitip bitmediğini kontrol ediyor.
    ttscommit;
    application.quit();
    info("Bitti");
}
excel veri aktarımı
Sonuçta gördüğünüz gibi istediğimiz alanları tabloya yazdırmış olduk. Gelen alanları değişkene atamadan direk tablonun alanınada eşitleyebilirdik veya çeşitli manuel kontrollerden geçirebilirdik. Bu şekilde bu Jobu metoda veya classa ekleyerek istediğiniz yerde kullanabileceğiniz bir hale getirebilirsiniz.