Author Archive

Dynamics Ax 2012 Event Handling

Merhaba

Ax 2012 ile gelen yeniliklerden biride event teknolojisi. .Net’te kullanılan bu teknoloji x++’a da uyarlanmış. Bu konuyla ilgili bir çok dokuman mevcut. White Paper buradan indirebilirsiniz.

Ben bu yazımda basit bir örnekle standart bir tabloda event teknolojisini nasıl kullanabileceğimizi anlatmaya çalışacağım.

Adım adım ilerleyelim.

  1. FDCustTableEventHandler adında bir class oluşturalım.
  2. customerCreated adında bir metod ekleyelim ve aşağıdaki kodu kopyalayalım.
    public static void customerCreated(XppPrePostArgs _args)
    {
        CustTable custTable;
        ;
        custTable = _args.getThis();
    
        info(strFmt("%1 nolu müşteri oluşturuldu. (EventHandler)",
           custTable.AccountNum));
    }
    
  3. CustTable tablosuna gidip Insert() Metoduna sağ tıklayın. Yeni bir Event handler subsciption tanımlayalım. İsim olarak FDCreateRecord diyelim özelliklerinden resimdeki tanımları yapalım.                                                 

    Buradaki CalledWhen özelliğinde iki şık var. Pre ve Post. Pre insert işleminden önce event’i tetikler. Post ise insert işleminden sonra tetikler.

  4. Yeni bir müşteri girişi yaptığımızda yazdığımız kodun çalıştığını göreceksiniz.

Selamlar.

Dynamics Ax ile bir adresin enlem boylamını nasıl bulunur

Merhaba

Yeni başlayan projemde bir çok müşteri adresi olacak. Benim bu adreslerin enlem ve boylamlarını bilmem gerekiyor. Google Apps ta girilen adresin değerlerini veren bir servis var. XML ve JSON tipte veri veriyor.
Buradan bakabilirsiniz. Bu servisi Ax içinden çağırıp enlem ve boylamını xml dosyasından bulan bir kod yazdım.


static void FD_EnlemBoylamBul(Args _args)
{
XMLDocument         doc;
XMLNode             rootNode;
XMLNode             location, geometry, result , lat, lng;
XMLParseError       xmlError;
str                 address;
str                 xmladd;
str                 xmlfile ;
System.Net.WebClient webClient = new System.Net.WebClient();
;
address = "Rüzgarlıbahçe M.Kavak S. No:31/1 34805 Beykoz İstanbul";
xmladd=strFmt("http://maps.googleapis.com/maps/api/geocode/xml?address=%1&sensor=false",
                        address);

xmlfile = webClient.DownloadString(xmladd);

doc = new XmlDocument();
doc.loadXml(xmlfile);
xmlError = doc.parseError();
rootNode = doc.documentElement();
result   = rootNode.selectSingleNode("result");
geometry = result.selectSingleNode("geometry");
location = geometry.selectSingleNode("location");

lat = location.selectSingleNode("lat");
info(strFmt("Enlem(lat) = %1" ,lat.text()));

lng = location.selectSingleNode("lng");
info(strFmt("Boylam(lng) = %1" ,lng.text()));

}

Selamlar.

Dynamics Ax 2012 Valid Time State 2

Merhaba

Önceki yazımda  tarih kontrollü yapının nasıl kurulacağını anlatmıştım. Bu yazımda framework ile gelen sorgu özelliklerinden bahsedeceğim. Resimdeki gibi bir örnek verimiz olsun.

Birinci örneğimiz bu gün için geçerli olan sözleşme kaydını bize verir.

Select ile;

static void FD_ValidTimeState1(Args _args)
{
    FDcontractTable   FDcontractTable;
    TransDate         contractStartDate = systemDateGet() ;
    ;

    while select validTimeState(contractStartDate) FDcontractTable
        where FDcontractTable.ContractId == 'CNRT_004'
    {
        info(strFmt("%1: %2 - %3",
            FDcontractTable.ContractId,
            FDcontractTable.ValidFrom,
            FDcontractTable.ValidTo));
    }
}

Query ile;

static void FD_ValidTimeState3(Args _args)
{
    Query               query;
    QueryRun            queryRun;
    FDcontractTable     FDcontractTable;
    TransDate           contractStartDate = systemDateGet() ;
    ;
    query = new Query();
    query.addDataSource(tableNum(FDcontractTable)).addRange(fieldNum(FDcontractTable,
            ContractId)).value(queryValue('CNRT_004'));

    query.validTimeStateAsOfDate(contractStartDate);

    queryRun = new QueryRun(query);

    if(queryRun.prompt())
    {
        while(queryRun.next())
        {
            FDcontractTable = queryRun.getNo(1);
            info(strFmt("%1: %2 - %3",
                FDcontractTable.ContractId,
                FDcontractTable.ValidFrom,
                FDcontractTable.ValidTo));
        }
    }
}

İkinci örnekte ise 30 günlük aralıkta kalan bütün sözleşmeleri  verir.

Select ile;

static void FD_ValidTimeState2(Args _args)
{
    FDcontractTable   FDcontractTable;
    TransDate         contractStartDate = systemDateGet() ;
    TransDate         contractEndDate   = systemDateGet() + 30;
    ;

    while select validTimeState(contractStartDate ,  contractEndDate)
        FDcontractTable
        where FDcontractTable.ContractId == 'CNRT_004'
    {
        info(strFmt("%1: %2 - %3",
            FDcontractTable.ContractId,
            FDcontractTable.ValidFrom,
            FDcontractTable.ValidTo));
    }
}

Query ile;

static void FD_ValidTimeState4(Args _args)
{
    Query               query;
    QueryRun            queryRun;
    FDcontractTable     FDcontractTable;
    TransDate           contractStartDate = systemDateGet() ;
    TransDate           contractEndDate   = systemDateGet() + 30;

    query = new Query();
    query.addDataSource(tableNum(FDcontractTable)).addRange(fieldNum(FDcontractTable,
            ContractId)).value(queryValue('CNRT_004'));

    query.validTimeStateDateRange(contractStartDate, contractEndDate);

    queryRun = new QueryRun(query);

    if(queryRun.prompt())
    {
        while(queryRun.next())
        {
            FDcontractTable = queryRun.getNo(1);
            info(strFmt("%1: %2 - %3",
                FDcontractTable.ContractId,
                FDcontractTable.ValidFrom,
                FDcontractTable.ValidTo));
        }
    }
}

4. örneği çalıştırdığınızda Query ekranında yeni bir özellik olan Date options ile karşılaşacaksınız. Bu sekmeden 3 tip var. İsimlerinden de anlaşılacağı üzere birincisi şu andaki aktif kaydı verir. İkincisi girilen tarihteki aktif kaydı verir. Üçüncüsü ise aralıktaki aktif kayıtları verir.

Kodda kullanımı gayet güzel olmuş.

Selamlar.

Dynamics Ax 2012 Valid Time State 1

Merhaba

Bu yazımda ax 2012 ile gelen yeni Date effective framework , veya diğer adıyla Valid time state tables‘tan bahsedeceğim. Bu framework verinizde tarih veya saat aralığına göre bir işlem yapılıyorsa bu verinin girişini ve kontrollerini otomatik yapar. Örneğin sözleşmeleri tuttuğunuz bir tablo var ve sözleşmeler belli bir tarih aralığında geçerli. Siz sözleşme bittiğinde yeni bir tarih aralığı girip sözleşmenin bazı şartlarını değiştirip yeniden tanım yapabiliyorsunuz.  Adım adım ilerleyelim.

  1. FDContractTable isminde bir tablo yapalım. Bu tabloya ContractId adında string bir alan oluşturalım. Tablonun özelliklerinden ValidtimeStateFieldType özelliğini Date yapalım. Otomatik olarak ValidFrom ve Validto alanları açılmış oldu.
  2. VTSIdx adında bir indeks oluşturup ContractId , ValidFrom ve ValidTo alanlarını ekleyelim. Resimdeki özellikleri tanımlayalım. ValidTimeStateMode ta iki tanım var Gap ve NoGap . Bu özellik iki tarih arasında boşluk bırakılıp bırakılmayacağını belirleyen özelliktir.
  3. Bir form yapalım ve forma grid ekleyelim. Alanlarımız sürükleyip gride bırakalım. Oluşturduğumuz formun veri kaynağının özelliklerinde ValidTimeStateAutoQuery özelliğini DataRange yapalım.
  4. Formu açıp veri girişi yaptığınızda aynı sözleşme kodu için çakışan tarihlere giriş yaptırmadığını göreceksiniz. Yeni kayıt girerken devam eden sözleşmeyi bitirdiğini ve yeni sözleşmenin bitiş tarihine bir giriş yapmazsanız never yani sonsuz yazdığını göreceksiniz.

Daha önce bizim kodla yaptığımız bir çok kontrolü framework bizim için yapıyor. Kullanışlı bir sistem olmuş. Bir sonraki yazımda kodda bu yapının nasıl kullanılabileceğinden bahsedeceğim.

Bu framework ile alakalı çok ayrıntılı bir White Paper yayınlandı. Buradan indirebilirsiniz.

Örnek projeyi buradan indirebilirsiniz.

Selamlar.

Dynamics Ax 2012′de eski usul ana tablo yapmak

Merhaba

Bir önceki yazımda ana tablo yapısındaki ve EDT ilişkilerindeki değişikliklerden bahsetmiştim. Bu yazımda bizim eski versiyonlardan bildiğimiz alıştığımız string alanlar üzerinden ana tablo ve EDT ilişkisi kurma işini nasıl yapabileceğimizi anlatacağım. Bir örnekle anlatmaya çalışayım.

  1. String bir EDT yapalım. İsmi FDCarID olsun.
  2. FDCarTable adında bir tablo yapalım. FDCarId EDT’mizi sürükleyip Fields kısmına bırakalım ve bir sütün oluşturalım.
  3. EDT’mize dönelim ve ReferanceTable özelliğine FDCarTable yazalım. Daha sonra EDT üzerindeki Table Referances kısmına eni bir referans ekleyelim ve FDCarTable da oluşturduğumuz alan ile ilişkilendirelim.
  4. FDCarTable’a CarIdx adında bir indeks oluşturalım ve CarId’yi indekse ekleyelim. İndeks özelliklerinde aşağıdaki tanımları yapalım.

  5. FDCarTable özelliklerinden PrimaryIndex ve  ClusterIndex için CarIdx ‘i seçelim.
  6. FDCarTable için bir form oluşturalım ve formun menu item’ını oluşturalım.Bu işlemlerden sonra ana tablo yapısı hazır.
  7. FDCarRentTable isminde bir tablo oluşturalım. Fields kısmına FDCarId EDT’sini sürükleyip bırakalım. Otomatik olarak ilişki sorusu çıkacak  burayı onaylamalısınız.
  8. FDCarRentTable için bir form yapalım. gerekli tasarımları yaptığımızda ana tablo yapısı ve lookup’ların çalıştığını göreceksiniz.

Örnek projeyi indirmek için tıklayın.

Selamlar.

Dynamics Ax 2012′de ana tablo yapısındaki değişiklikler

Merhaba

Dynamics ax 2012 ile birlikte alışık olduğumuz bir çok teknolojide değişiklikler oldu. Bunlardan en temel olanlarından biride PrimaryKey yapısı. Eski versiyon eğitimlerinde sürekli söylediğim bir cümle vardı. “Ax akıllı kod kullanmak için performanstan ödüne vererek ana tablolarda string keyler kullanır.” bu cümle ax 2012 için geçerli değil. Hem akıllı kod kullanmak hemde key’i int yapmak artık mümkün. Tablolar için yeni bir Integer key oluşturmaya gerek yok. Bildiğiniz gibi her tabloda RecId alanımız mevcut. Bizim ilk eskiden beri öğrendiğimiz “her bir tablonun bir tane integer key alanı olur ve diğer tablolarla ilişkileri bu alan sayesinde kurulur” ifadesi ax içinde artık geçerli. Eski versiyonlarda olan string key hala yapabiliyoruz. Bunu başka bir yazımda anlatacağım. Bu yazımda RecId ile nasıl ana tablo yapılır bir örnekle anlatmaya çalışacağım. Adım adım ilerleyelim.

  1. Bir kitap tablomuz olsun. Birde kitap satış tablosu olsun.  FDBookTable içine BookName adında string bir alan açalım. Bu alan için bir indeks oluşturalım ve aşağıda görünen tanımları yapalım.
  2. FDBookTable genel yapısı için bu tanımları yapalım.
  3. BookNameIdx indeksini oluşturalım ve tanımları yapalım.
  4. FDBookTable özelliklerinde key tanımlarını yapalımPrimaryIndex ve ClusterIndex surrogateKey olmalı. SurrogateKey RecId index demek aslında.
  5. Int64 tipinde bir EDT oluşturalım.
  6. EDT özelliklerinde referans tablo olarak kitap tablomuzu seçiyoruz ve Table References kısmında da RecId ile referans tanımı yapıyoruz.
  7. Bu işlemlerden sonra ana tablo yapabilmek başka tablolarla ilişki kurmak için ihtiyacımız olan tanımları yapmış olduk. Bu aşamada FDBookLine isminde bir tablo oluşturup FDBookTableRecId EDT sini sürükleyip Fields kısmına bıraktığınızda sizden FDBookTable ile ilişki kurmak için bir onay sorusu çıkacaktır. Onay vermelisiniz. Aşağıdaki resimde görünen tanımları otomatik yapmış olacak. Eğer sorun olursa elle de oluşturabilirsiniz.
  8. Bir form yapalım ve veri kaynağına FDBookLine tablosunu ekleyelim. Tasarım kısmına bir Grid oluşturup veri kaynağında FDBookTableRecId alanını sürükletip Grid üzerine bırakalım. Otomatik olarak ReferanceGroup oluşmalı ve sizin BookNameIdx indeksinde eklediğiniz sütunları otomatik oluşmalıdır. Eğer oluşmuyorsa bir bu kısma kadar olan adımlarda bir eksiklik yapmışsınız demektir.
  9. Formu açmadan önce Kitap tablosunu açıp bir kaç kitap tanımı yapalım.
  10. Artık kitap satış formu açıp giriş yapabilirim. Gördüğünüz gibi Lookup ta kitap isimlerini görüyorum ve ona göre süzme işlemleri yapabiliyorum. Seçtikten sonrada Grid ekranında kitap isimlerini görüyorum ve Grid üzerinde de süzme yapabiliyorum isim üzerinden. en güzel tarafı ise FDBookLine tablosuna gidip baktığınızda kitap isimlerin yerinde Kitap tablosunun RecId’sini göreceksiniz. Bunu sağlayan bir kaç yapı var öncelikle Veri kaynağında Referance Data Sources kısmı bide Referance Group kısmı. Bu iki kısımda çok ayrıntı var ilerde bunlara da değineceğim.
  11. Benim fikrim bu teknolojiyle birlikte ana tablo tanımlarını RecId üzerinden yapmak lazım. Eski yapılan geliştirmeleri hemen değiştirmeye gerek yok ancak performans sıkıntısı olan kısımlarda değiştirmek lazım.

    Projeyi indirmek için tıklayın.

    Selamlar.

Dynamics Ax 2012′de aktif finansal boyutları bulmak

Merhaba

Belli bir kurulum için aktif boyutları bulan bir kod örneği paylaşıyorum. Bazı işlemlerde ihtiyaç oluyor.

static void FD_GetActiveFinancialDim(Args _args)
{
    DimensionAttribute          dimAttr;
    DimensionAttributeSetItem   dimAttrSetItem;
    DimensionEnumeration        dimensionSetId;
    ;

    dimensionSetId = DimensionCache::getDimensionAttributeSetForLedger();

    while select dimAttr
        where dimAttr.Type != DimensionAttributeType::MainAccount
        join RecId from dimAttrSetItem
            where dimAttrSetItem.DimensionAttribute    == dimAttr.RecId
               && dimAttrSetItem.DimensionAttributeSet == dimensionSetId
    {
        info(strFmt("%1 , %2" ,dimAttr.RecId , dimAttr.Name));
    }
}

Çıktısı şöyle;

Selamlar.

Dynamics Ax 2012′de bir müşterinin boyutlarını listelemek

Merhaba

Bu örnekte bir müşteri üzerinde tanımlanmış boyutları ve değerlerini listeleyen bir select cümleciği yazdım. Burada değer girilmemiş boyutlar gelmeyecektir. Hangi boyutların aktif olduğunu gösteren bir select ifadesini gelecek yazımda paylaşacağım.

static void FD_AddCustDefaultDim(Args _args)
{
    CustTable                           custTable;
    DimensionAttribute                  dimAttr;
    DimensionAttributeValue             dimAttrValue;
    DimensionAttributeValueSetItem      dimAttrValueSetItem;
    ;

    while select custTable
    where  custTable.AccountNum  == "1101"
    join dimAttrValueSetItem
    where dimAttrValueSetItem.DimensionAttributeValueSet ==custTable.DefaultDimension
    join dimAttrValue
         where dimAttrValue.RecId  == dimAttrValueSetItem.DimensionAttributeValue
         join dimAttr
         where dimAttr.RecId   == dimAttrValue.DimensionAttribute
    {
        info(strFmt("%1 ; %2 ; %3 ; %4", CustTable.AccountNum , CustTable.name(),
                        dimAttr.Name , dimAttrValueSetItem.DisplayValue));
    }
}

Çıktısı benim boyut kurulumuma göre şöyle oluyor.

Selamlar.

Dynamics Ax 2012′de DefaultDimension sorgu örnekleri

Merhaba

Şu yazımda BusinessUnit boyutunun değeri “20″ olan müşterileri listeleyen bir query yazmıştım. Bu query örneğinin select ifadesiyle yazılmış şeklini iki örnekle anlatacağım.

Bu örnekte gerekli bütün tabloları join’leyip istediğimiz sonuca ulaşıyoruz.

static void FD_AddCustDimensionRangeSelectAll(Args _args)
{
CustTable                           custTable;
DimensionAttribute                  dimAttr;
DimensionAttributeValue             dimAttrValue;
DimensionAttributeValueSetItem      dimAttrValueSetItem;
;

while select custTable
join dimAttrValueSetItem
where dimAttrValueSetItem.DimensionAttributeValueSet == custTable.DefaultDimension
&&    dimAttrValueSetItem.DisplayValue               == "20"
join dimAttrValue
where dimAttrValue.RecId == dimAttrValueSetItem.DimensionAttributeValue
join dimAttr
where dimAttr.RecId             == dimAttrValue.DimensionAttribute
&&    dimAttr.BackingEntityType == tableNum(DimAttributeOMBusinessUnit)

{
info(strFmt("%1 ; %2 ; %3 ; %4", CustTable.AccountNum ,
dimAttr.Name , dimAttrValueSetItem.DisplayValue , CustTable.name()));
}
}

Bu örnekte ise DimensionAttributeValue ve DimensionAttributeValueSetItem yerine Bir view kullanıyoruz.

static void FD_AddCustDimensionRangeSelect(Args _args)
{
CustTable                           custTable;
DimensionAttribute                  dimAttr;
DimensionAttributeValueSetItemView  dimAttrValueSetItemView;
;

while select custTable
join dimAttrValueSetItemView
where dimAttrValueSetItemView.DimensionAttributeValueSet == custTable.DefaultDimension
&&    dimAttrValueSetItemView.DisplayValue               == "20"
join dimAttr
where dimAttr.RecId       == dimAttrValueSetItemView.DimensionAttribute
&&    dimAttr.BackingEntityType == tableNum(DimAttributeOMBusinessUnit)

{
info(strFmt("%1 ; %2 ; %3 ; %4", CustTable.AccountNum ,
dimAttr.Name , dimAttrValueSetItemView.DisplayValue , CustTable.name()));
}
}

İki kodu da çalıştırdığınızda aynı çıktıyı alacaksınız.

Selamlar.

Dynamics Ax 2012 DimensionProvider sınıfı

Merhaba

Ax 2012 ile finansal boyut yapısındaki bir çok değişiklikten eski yazılarımda bahsetmiştim. Boyut yapısındaki bu değişiklikler üzerine kodlarımızda boyutla işlem yapmamız gerektiğinde çok zorlanacağımız düşünmüştüm. Microsoft’taki arkadaşlarda aynı düşünceyi paylaşmışlar ki DimensionProvider sınıfını yazmışlar. Bu sınıf Query yapısında boyutla ilgili işlemleri yapmamızı kolaylaştırıyor ve bizi gereksiz bir çok Join ifadesinden kurtarıyor. Aşağıdaki örneği inceleyelim.

static void FD_AddDimensionRangeToCust(Args _args)
{
    Query                       query = new Query();
    QueryRun                    queryRun;
    QueryBuildDataSource        qbds;
    DimensionProvider           dimProvider = new DimensionProvider();
    CustTable                   custTable;
    ;

    qbds = query.addDataSource(tableNum(CustTable));

    dimProvider.addAttributeRangeToQuery(query, qbds.name(),
                        fieldStr(CustTable,DefaultDimension ),
                        DimensionComponent::DimensionAttribute,
                        "20",
                        "BusinessUnit", true );

    queryRun = new QueryRun(query);
    queryRun.prompt();

    while(queryRun.next())
    {
        CustTable = queryRun.get(tableNum(CustTable));
        info(strFmt("%1 ; %2 ; %3", CustTable.AccountNum ,
                    CustTable.name() , CustTable.DefaultDimension));
    }
}

Bu örnekte BusinessUnit boyutu 20 olan müşterileri listeleyen bir Query yazdım. DimensionProvider sınıfının bir çok metodu mevcut. İhtiyaç oldukça incelemek lazım.

Eski versiyonlarda bunu yazmak gayet  kolaydı çünkü boyut müşteri tablosunda dizi tipinde bir alan olarak bulunuyordu. Ax 2012′de ise tamamen farklı tablolarda tutulan bir veri artık. Bu yüzden 3-4 tablolu bir Join ifadesi yazmaktansa bu sınıfı kullanmak çok daha kolay.

Bu Query ifadesinin Select ile nasıl yazılabileceğini bir sonraki yazımda  ele alacağım.

Selamlar.

Page 5 of 23« First...345671020...Last »