Blog Listem

9 Aralık 2013 Pazartesi

AXAPTA - Varsayılan para birimi ve dil

    custTable.Currency   = CompanyInfo::standardCurrency();
    custTable.LanguageId = Companyinfo::languageId();

AXAPTA - Şirket Değiştir

        Header.parmShippingDateRequested(this.ShippingDateRequested);
    changecompany(TargetCompanyId)
    {
        Header.parmQuotationId();
        Header.parmCurrencyCode(CompanyInfo::standardCurrency());

        ...
        Header.save();
    }

28 Kasım 2013 Perşembe

AXAPTA - Formdaki container tablo fieldına resmi sürükle-bırak yapmak

public void dropFile(str _FileName)
{
    BinData p = new BinData();
    ;
    super(_FileName);
    p.loadFile(_FileName);
    PRTSecondHandTractorStock.Picture = p.getData();
    element.redraw();
}

21 Kasım 2013 Perşembe

AXAPTA - Bir tablo alanını cross-company çalışacak hale getirmek


Bir forumdan öğrendiğim bu yöntemle tüm yapmanız gereken yukarıdaki gibi bir relation ve extended data tipine dikkat etmek. Bundan sonra formlarda lookup veya validation method yazmadan ilgili alanınız cross-company çalışacak. Bu özellik AX 2009 ile çalışıyor, 2012 ile deneme şansım olmadı.

AXAP - Cross company lookup

public void lookup(FormControl _formControl, str _filterStr)
{

      CustTable   custTable;    
      Query                   Query  = new Query();
      QueryBuildDataSource    qbds;
      SysTableLookup          SysTableLookup  =      
            SysTableLookup::newParameters(TableNum(CustTable), _formControl);
    ;
    super(_formcontrol,_filterstr);

    Query.allowCrossCompany(true);      
    Query.addCompanyRange(myTable.Company);
    qbds           = Query.addDataSource(TableNum(CustTable));
    SysTableLookup.addLookupfield(FieldNum(CustTable, AccountNum), true);      

    SysTableLookup.addLookupfield(FieldNum(CustTable, Name));
    SysTableLookup.parmQuery(Query)

    SysTableLookup.performFormLookup();
}


Kontrolün validate metodunu ezmeyi unutmayın!..

18 Kasım 2013 Pazartesi

AXAPTA - Combobox enum kullanırken bazı elementleri atlamak

Çözümünü bir forumda buldum:

Form kontrolünün Enter metodunun super sonrasına yazılacak:

    this.delete(enum2str(DTSSHOperationLineType::Part));
    this.delete(enum2str(DTSSHOperationLineType::ExternalPart));


Eğer kontrol bir grup altındaysa AutoDataGroup = No yapmayı unutmayın.

14 Kasım 2013 Perşembe

AXAPTA - Gridde hızlı kayıt bulma

Bu işi için sakın find metodunu kullanmayın, büyük tablolarda çok yavaş çalışır. Axapta'nın kendi formlarında kullandığı yöntem bu:

element.args().lookupField(fieldnum(SMAServiceOrderTable, ServiceOrderId));
element.args().lookupValue(_myServiceOrderId);
SMAServiceOrderTable_ds.executeQuery();

5 Kasım 2013 Salı

AXAPTA - Tabloda password field

Bu konuyu yazarken Greg on Dynamics AX blogundan yararlandım.

Öncelikle tablomuzda tipi container olan bir password field açıyor ve extended data tipini CryptoBlob olarak seçiyoruz.

Password alanı için edit metodumuz:

edit Password edtPassword(boolean _set = false, Password _pwd = '')
{
    CryptoBlob cryptoBlob = connull();
    ;
    if (_set)
    {
        this.Password = WinapiServer::cryptProtectData(str2cryptoblob(_pwd));
    }
    return (this.Password == connull()) ? '' : 'xxxxxxxx';
}


Kodla passwordü okumak için metodumuz:
Password getPassword()
{
    CryptoBlob cryptoBlob;
    ;
    cryptoBlob = this.Password;
    return (cryptoBlob == connull()) ? '' :
        cryptoblob2str(WinapiServer::cryptUnProtectData(cryptoBlob));
}


Kodla passwordü yazmak için metodumuz:

void setPassword(Password _pwd = '')
{
    CryptoBlob cryptoBlob = connull();
    ;
    this.Password = WinapiServer::cryptProtectData(str2cryptoblob(_pwd));
}

Ekranda okuturken ilgili kontrolün PasswordStyle değerini Yes yapmayı unutmayın.

10 Ekim 2013 Perşembe

AXAPTA - Join A tablosunu B tablosuna ve yine A tablosunu C tablosuna bağlamak

Bir forumda öğrendiğim yöntemle bunu yapabiliyorum. Püf noktası fetchMode komutu. Eğer fetchMode komudunu kullanmazsanız düzgün bir select oluşmaz. 
Query query = new Query();
QueryBuildDataSource qbds,qbds1,qbds2;
;
qbds = query.addDataSource(tableNum(SMAServiceOrderTable));
qbds1 = qbds.addDataSource(tableNum(B_RepairJournal));
qbds1.fetchMode(QueryFetchMode::One2One);
qbds1.addLink(fieldNum(B_RepairJournal,ServiceOrderId),fieldNum(SMSServiceOrderTable,ServiceOrderId));
qbds2 = qbds.addDataSource(tableNum(InventTable));
qbds2.fetchMode(QueryFetchMode::One2One);
qbds2.addLink(fieldNum(SMAServiceOrderTable,ItemId),fieldNum(InventTable,ItemId));

info(qbds.toString());

1 Ekim 2013 Salı

AXAPTA - Web servisi "CLR nesnesi Microsoft Dynamics anytype için sıralanamıyor." hatası

SenderTel2      = line.get_senderTel2();

 Axapta ile web servisi geliştirirken yukarıdaki gibi bir satırla servisten property okumaya çalışırken null değerler için "CLR nesnesi Microsoft Dynamics anytype için sıralanamıyor." hatası alıyorsanız ve hata veren satırı try/catch içine aldığınız halde hata mesajı yine de ekrana geliyorsa yapmanız gereken:

SenderTel2      = CLRInterop::isNull(line.get_senderTel2()) ? "" : line.get_senderTel2();


23 Temmuz 2013 Salı

AXAPTA - Lookup ve sort

Lookup oluşturduğunuzda sort eklediğiniz halde lookup'ın sizin belirlediğiniz sırada çıkmadığını görürsünüz:

public void lookup()
{
    SysTableLookUp          sysTableLookUp = SysTableLookup::newParameters(tablenum(SMARepairStage),RepairStageId);
    Query                   query = new Query();
    QueryBuildDataSource    qbds = query.addDataSource(tablenum(SMARepairStage));
        qbds.addSortField(fieldnum(SMARepairStage,Name));
        qbds.orderMode(OrderMode::OrderBy);
    sysTableLookup.addLookupfield(fieldnum(SMARepairStage,RepairStageId));
    sysTableLookup.addLookupfield(fieldnum(SMARepairStage,Name));
    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}


Aşağıdaki değişikliği yaparsanız lookup'ın sizin belirlediğiniz sırada çıktığını göreceksiniz:

public void lookup()
{
    SysTableLookUp          sysTableLookUp = SysTableLookup::newParameters(tablenum(SMARepairStage),RepairStageId);
    Query                   query = new Query();
    QueryBuildDataSource    qbds = query.addDataSource(tablenum(SMARepairStage));
        qbds.addSortField(fieldnum(SMARepairStage,Name));
        qbds.orderMode(OrderMode::OrderBy);
    sysTableLookup.addLookupfield(fieldnum(SMARepairStage,RepairStageId));
    sysTableLookup.addLookupfield(fieldnum(SMARepairStage,Name));
    sysTableLookup.parmQuery(query);
    sysTableLookup.parmUseLookupValue(false);
    sysTableLookup.performFormLookup();
}

22 Temmuz 2013 Pazartesi

AXAPTA - Form açılırken istenen bir kontrole set focus

Formun firstField metoduna ilgili kontrol için bir setfocus yazmak gerekiyor:

public void firstField(int _flags=1)
{
    super(_flags);
    EmplId2.setFocus();
}

12 Temmuz 2013 Cuma

AXAPTA - Server tarih-saat değerini alırken saat dilimi farkı

DateTimeUtil classının utcNow  methodu saati Greenwich olarak verir. Alırken ve verirken çevirmek gerekir:

CallDateTime.value(DateTimeUtil::applyTimeZoneOffset(DateTimeUtil::utcNow(),DateTimeUtil::getCompanyTimeZone()));
...

...
JournalLines.CallDateTime = DateTimeUtil::removeTimeZoneOffset(CallDateTime.value(),DateTimeUtil::getCompanyTimeZone());

11 Temmuz 2013 Perşembe

AXAPTA - Barkod yazdırma

İnternette bulduğum Axapta barkod yazdırma konusundaki blogların çoğunun denenmemiş ve birbirinden kopya olduğunu sanıyorum. Çünkü bazı sıkıntılar var ki bunlardan hiç bahsedilmemiş. Ben aşağıda bunlara da değindim:

Code 128 için:

display BarCodeString ServiceObjectbarCode()
{
    Barcode barcode;
    ;

    barcode = BarcodeCode128::construct();
    barcode = Barcode::construct(BarcodeType::Code128);


    barcode.string(true, ServiceObject.ItemSerialNum);
    barcode.encode();
    return barcode.barcodeStr();
}


Bu display alanı sürükledikten sonra özellikleri:

Font - BC C128 Narrow

Width - Bu değer auto olmamalı. Code 128 ile auto yapıldığında Axapta etiketi olması gerektiğinden erken sonlandırıyor. Deneme ile gerekli alan uzunluğu bulunabilir. Ben kendi örneğimde 10 cm yaptım.
Fontsize - 24 (24'ten düşük bir fontla yazdırmayı başaramadım. Daha büyük fontlar denerken de arada bazı boyutları yazıyor ama okuyucu okumuyor, deneme yanılma yöntemiyle bulmak gerekiyor malesef).

Code 39 için:
display BarCodeString ServiceOrderbarCode()
{
    Barcode barcode;
    ;

    barcode = Barcode::construct(BarcodeType::Code39);
    barcode.string(true, ServiceOrder.ServiceOrderId);
    barcode.encode();

    return barcode.barcodeStr();
}


Font - BC C39 3 to 1 HD Wide
Code39 ile width Auto olduğunda bir sıkıntı yaşamadım.
Aynı şekilde bunda da font 24'ten küçük olduğunda ve arada bazı boyutlarda okuma sorunu yaşadım. Benim yaşadığım okuma sorunları okuyucu kaynaklı da olabilir tabii.

4 Temmuz 2013 Perşembe

AXAPTA - Gridde bir kayda hızlı konumlanmak

Kayda konumlanmak için findrecord ve findvalue methodları çok yavaş. Bunun yerine filter kullanılabiliyor ancak o zaman da ekranda sadece istenen kayıtlar görüntülenebiliyor. Eğer tüm kayıtlar görüntülensin ve cursor de istediğimiz kayıtta konumlansın istiyorsanız  bir blogda rastladığım orijinal lookup formlarında da kullanılan aşağıdaki yöntemi kullanabilirsiniz:

element.args().lookupField(fieldnum(SMAServiceOrderTable, ServiceOrderId));
element.args().lookupValue(_order.ServiceOrderId);
 

SMAServiceOrderTable_ds.executeQuery();

Not: Arama için kullandığınız alanın indeksli olması gerektiğini unutmayın!..

24 Haziran 2013 Pazartesi

AXAPTA - cacheAddMethod ile display methodları hızlandırmak

Axapta normalde bir kayıttaki display methodları dolaşırken defalarca ard arda çağırabilir. Bu display method sayısı fazla olduğunda can sıkıcı hale gelebilir.  cacheAddMethod ile display methodlar serverda bir arabellekte saklanır ve oldukça güzel performans artışı sağlanabilir. Bu method "datasource"un init methodunda super sonrası çağrılabilir. Yanlış yerde çağrıldığında donmalara sebep olabiliyor. Ayrıca bu display methodların "tablo" display methodu olması gerekiyor.
Bu yöntem aynı zamanda edit methodlar için de çalışıyor.

public void init()
{
    super();
    this.cacheAddMethod(tableMethodStr(B_CallTrack, CustomerName));
    this.cacheAddMethod(tableMethodStr(B_CallTrack, EndUserWarrantyStart));
    this.cacheAddMethod(tableMethodStr(B_CallTrack, ExtendedWarrantyDate));
    this.cacheAddMethod(tableMethodStr(B_CallTrack, ModelGroupID));
}


 Ara belleğe alınan display/edit methodlar update methodu çalışmadan güncellenmezler. Update methodundan önce güncellenmeleri gerektiğinde cacheCalculateMethod u kullanabilirsiniz:
B_CallTrack_DS.cacheCalculateMethod(tableMethodStr(B_CallTrack, EndUserWarrantyStart));
 

AX 2012 için güncelleme:

AX 2012'de bu işlem çok daha basit. SysClientCacheDataMethodAttribute kullanarak bu iş basitçe halledilebiliyor. Opsiyonel olarak bir parametre eklenmiş. True gönderildiğinde yukardaki update meselesi de çözülmüş oluyor. Ancak bu şekilde tanımlama yapıldığında display/edit metod tüm formlarda cache içine alınıyor. Eğer her formda ayrı ayrı yapılmak isteniyorsa eski yöntem de halen geçerli.


[SysClientCacheDataMethodAttribute(true)]
display name dispCustName()
{
    return CustTable::find(this.CustAccount).Name;
}
 

AXAPTA - Display method yetki kontrolü

//BP Deviation documented
display CustName customerName()
{
    CustName    custName    = '';
    DictTable   dictTable   = new DictTable(tablenum(CustTable));
    ;

    if (dictTable.rights() >= AccessType::View)
    {
        custName = CustTable::find(this.CustAccount).Name;
    }

    return custName;
}

6 Haziran 2013 Perşembe

AXAPTA - Günün başı ve sonu

     info( strfmt("%1 --- %2", datetobeginUtcDateTime( today() , DateTimeUtil::getUserPreferredTimeZone() ) ,
        datetoendUtcDateTime( today(), DateTimeUtil::getUserPreferredTimeZone() )));

23 Mayıs 2013 Perşembe

AXAPTA - Clipboarda kopyalama

FileIoPermission _perm = new FileIoPermission("myfile.txt",'r');
TextBuffer txtBuff = new TextBuffer();
;
// text dosyasından
_perm.assert();
txtb.fromFile("myfile.txt");
txtBuff.toClipboard();
// string'den
txtBuff.setText("my test buffer...");
txtBuff.toClipboard();

19 Nisan 2013 Cuma

AXAPTA - Şirket logosu görüntüleme

Öncelikle Şirket logosunu yüklemeniz gerekiyor. Bunun için:
Temel->Kurulum->Şirket bilgileri->Şirket logosu bölümünden logonuzu tanımlayın.

Daha sonra bu adresten bulduğum aşağıdaki kodu report içinde display method olarak yazın:

Display Bitmap CompanyLogo()
{
    CompanyInfo companyInfo = CompanyInfo::find();
    ;
    return CompanyImage::find(companyInfo.DataAreaId, companyInfo.TableId, companyInfo.RecId).Image;
}


Bunu Header'a sürükleyin. Height ve Width değerlerini elle verip ResizeBitmap değerini Yes yapmayı unutmayın.

25 Mart 2013 Pazartesi

AXAPTA text dosya okuma

...
    Filename                Filename;
    System.IO.StreamReader  readFile;
    System.String           line;
      ;
    super();
    Filename = WinApi::getOpenFileName(element.hWnd(),['TXT files','*.txt'],"","Text Files");
    if (!Filename)
        return;

    readFile = new System.IO.StreamReader(filename,System.Text.Encoding::get_UTF8());
    while (true)
    {

        line = readFile.ReadLine();
        if(System.String::IsNullOrEmpty(line))
           break;
        warning(line);
    }
       
    readFile.Close();
    readFile.Dispose();
...        



Text dosya okumanın çeşitli farklı yöntemleri var. Biri de Fatih Demirci'nin bloğundaki.

8 Şubat 2013 Cuma

6 Şubat 2013 Çarşamba

AXAPTA - DoInsert ile Insert arasındaki fark nedir?

DoInsert insert metoduna yazılan X++ kodlarını görmezden gelir, Insert ise çalıştırır:
http://dynamicsuser.net/forums/t/53377.aspx

Calling DoInsert ensures that any Axapta X++ code written in insert method of the record is not executed.

4 Şubat 2013 Pazartesi

AXAPTA - Tabbed Dialog kontrole giriş-çıkışları yakalamak

Giriş için pageActivated() , çıkış için de allowPageDeactivate() metodunu kullanabilirsiniz. Lostfocus() ve GotFocus() metodları ile ben bu sonuca ulaşamadım.

31 Ocak 2013 Perşembe

AXAPTA - bir kullanıcıya uyarı mesajı göndermek

static void sendAlertToUser(UserId _UserId,EventSubject _Subject,EventMessage _Message)
{
    EventInbox        inbox;
    EventInboxId      inboxId;
    SysClientSessions sessions;
    ;
    inboxId = EventInbox::nextEventId();
    inbox.initValue();
    inbox.ShowPopup            = NoYes::Yes;
    inbox.Subject              = _Subject;
    inbox.Message              = _Message;
    inbox.SendEmail            = true;
    inbox.UserId               = _UserId;
    inbox.InboxId              = inboxId;
    inbox.AlertCreatedDateTime = DateTimeUtil::getSystemDateTime();
    inbox.insert();
}

AXAPTA - kodla sipariş oluşturma

...
    SalesTable                  salesTable;
    NumberSeq                   NumberSeq;
    SalesLine                   salesLine;
    AxSalesLine                 axSalesLine = new axSalesLine();
    AxSalesTable                axsalesTable = new axSalesTable();
    ;
...
    ttsbegin;
    axsalesTable.parmSalesId();
    if (ServiceOrder.CustName == "")
        axsalesTable.parmCustAccount(ServiceOrder.CustAccount);// Cust Account
    else
        axsalestable.parmOneTimeCustomer(Dialog_OneTime.value());

    axsalesTable.parmDlvMode(Dialog_DLVMode.value());
    axsalesTable.parmDlvTerm(Dialog_DLVTerm.value());
    axsalesTable.save();
    while select forupdate Lines where Lines.RepairJournalId == _RepairJournalId && Lines.SalesId == "" &&
        Lines.CSApproval == B_Approval::Approved && Lines.ItemId != "" && Lines.Qty > 0
    {
        axSalesLine = AxSalesLine::construct();
        axSalesLine.parmSalesId(axsalesTable.parmSalesId());
        axSalesLine.parmItemId(Lines.ItemId);
        axSalesLine.parmSalesQty(Lines.Qty);
        axSalesline.parmSalesPrice(Lines.ProjSalesPrice);
        axSalesline.parmCurrencyCode(Lines.ProjCurrencyCode);
        axSalesline.parmSalesUnit(Lines.Unit);
        Lines.SalesId = axsalesTable.parmSalesId();
        Lines.update();
        axSalesLine.save();
    }
    ttscommit;
...