13 Ekim 2017 Cuma

AX 2012 - Bir Finansal Boyuta Göre Sıralama

AX 2012'de mali boyutlar bir RecId alanında saklı olduğu ve çeşitli tabloları refere ettiği için sıralama olayı biraz karışık. Bunun için işimizi kolaylaştırıcı bir sınıf var:

DimensionProvider           dimProvider = new DimensionProvider();
    dimProvider.addOrderByAttribute(BorAXJournalTrans_DS.query(),BorAXJournalTrans_DS.query().dataSourceNo(1).name(),
       FieldStr(BorAXJournalTrans,DefaultDimension),
        DimensionComponent::DimensionAttribute,SortOrder::Ascending,
"Departmanı");
BorAXJournalTrans_DS.executeQuery();
  
Bu sınıfı kullanmak istemiyorum derseniz bir de şöyle bir seçenek var:

RecId  depRecId = 5637152827; //departman boyutunun DimensionAttribute tablosundaki recId değeri
    BorAXJournalTrans   boraxJournalTrans;
    DimensionAttributeValueSet dimensionAttributeValueSet;
    DimensionAttributeValueSetItem dimensionAttributeValueSetItem;
    DimensionAttributeValue dimensionAttributeValue;
    DimensionAttribute dimensionAttribute;

while SELECT firstOnly10 borAXJournalTrans 
    ORDER BY DimensionAttributeValueSetItem.DisplayValue
 JOIN dimensionAttributeValueSet 
    where borAXJournalTrans.DefaultDimension == dimensionAttributeValueSet.RecId 
 JOIN dimensionAttributeValueSetItem 
    where dimensionAttributeValueSet.RecId == dimensionAttributeValueSetItem.DimensionAttributeValueSet 
 JOIN dimensionAttributeValue 
    where dimensionAttributeValueSetItem.DimensionAttributeValue == dimensionAttributeValue.RecId 
 JOIN dimensionAttribute 
    where dimensionAttributeValue.DimensionAttribute == dimensionAttribute.RecId && 
     dimensionAttribute.RecId == depRecId
    {
        info(dimensionAttributeValueSetItem.DisplayValue);
    }

9 Ağustos 2017 Çarşamba

AX 2012 - Query'ye tek bir finansal boyut için filtre eklemek

Bunu tabloları ekleyerek yapmaya kalktığınızda bir çok tabloyu birbirine bağlamak zorunda olduğunuzu göreceksiniz. Bunu sizin yerinize yapan DimensionProvider adlı bir sınıf eklenmiş AX 2012'ye:

DimensionProvider           dimProvider = new DimensionProvider();


        dimProvider.addAttributeRangeToQuery(element.query(),element.query().dataSourceNo(1).name(),
       FieldStr(MyTable,DefaultDimension),
        DimensionComponent::DimensionAttribute,
        OMOperatingUnit::find(depRecId,OMOperatingUnitType::OMDepartment).OMOperatingUnitNumber,
            "Departmanı",true);

Bu arada Unknown type: RefRecId gibi bir hata alırsanız sebebi kullandığınız tablodaki EDT'nin yanlış olması olabilir. Benim başıma gelen durumda sorun yerel bir çözümde DefaultDimension field'ına DimensionDefault yerine RefRecId EDT kullanılmasıydı. Sizinkinde RefRecId yerine başka birşey de olabilir. AX orijinal tablosu HcmEmployment tablosunda da böyle bir bug varmış.

8 Ağustos 2017 Salı

AX 2012 - Dönem kapanış kontrolü

Muhasebe için:

FiscalCalendars::checkModuleIsOpen(SysModule::Ledger, myTable.TransDate,FiscalCalendars::findPeriodByPeriodCodeDate(Ledger::fiscalCalendar(CompanyInfo::find().RecId),myTable.ETGTransDate),false)

veya

select firstOnly period
        where transDate >= period.StartDate  && transDate <= period.EndDate
            exists join ledgerPeriod
                where ledgerPeriod.FiscalCalendarPeriod == period.RecId &&
                      ledgerPeriod.Status != FiscalPeriodStatus::Open;
    if (period.RecId != 0)
        throw error("Yeni tarih için ilgili mali dönem kapalı!..");

Satış için:

FiscalCalendars::checkModuleIsOpen(SysModule::Sales, CustInvoiceJour.InvoiceDate,FiscalCalendars::findPeriodByPeriodCodeDate(Ledger::fiscalCalendar(CompanyInfo::find().RecId),CustInvoiceJour.InvoiceDate),false)

Stok kapanışı için:

InventClosing::findClosingDate(endmth(InventJournalTrans.TransDate))

2 Ağustos 2017 Çarşamba

AX 2012 - Security Development Tool Kaynaklı Derleme Hatası

Security Development Tool yetkilendirme işlemlerini oldukça kolaylaştıran harika bir araç. Ancak bizim başımıza gelen can sıkıcı bir soruna yol açabiliyor. Aşağıdaki hatayı alırsanız bilin ki sebebi bu tool:

Error executing code: SysSecurityRecorder_**** object does not have method 'MenuItemInvoked'.

Konuyla ilgili bulabildiğim tek kaynak Google translate ile fransızcadan ingilizceye çevirerek anlayabildiğim bir blog'du (Şahsen Google Translate'yi türkçe çeviriler için çok başarısız buluyorum). Buradaki iki yöntem de işime yaradı:

1. yöntem: Client bilgisayardaki AOD dosyalarını silmek.

2.yöntem: AX DB'de bu kodu çalıştırınca tek tek tüm clientlarda temizlik yapmaya gerek kalmıyor:

UPDATE SYSSQMSETTINGS SET GLOBALGUID = '{00000000-0000-0000-0000-000000000000}'


7 Temmuz 2017 Cuma

AX 2012 - TempDB ile server metoddan forma veri göndermek

TempDB tablosunda direk parametre ile gönderip doldurmaya çalıştığınızda kayıt gelmediğini göreceksiniz. Kayıtların gelmesi için ya In Memory tablo türünü seçmelisiniz ya da linkPhysicalTableInstance metodu ile iki TempDB tablosunu birbirine bağlamalısınız:

Class:

public static server void populateData(MyTempTable _tmp)
{
MyTempTable tmp;
...
...
tmp.linkPhysicalTableInstance(_tmp);
...
...
return;
}

Form:


MyClass::populateData(MyTempTable);
MyTempTable_DS.research();
MyTempTable_DS.refresh();

4 Ocak 2017 Çarşamba

AXAPTA - Tabloları eşitle

İş arkadaşımın internetten bulduğu kod, kaynağını bilmiyorum ama birçok durumda işe yarıyor:

    Dictionary              dict;
    int                     idx, lastIdx, totalTables;
    TableId                 tableId;
    Application             application;
    SysOperationProgress    progress;
    StackBase               errorStack;
    ErrorTxt                errorTxt;
    ;

    application = new Application();
    dict = new Dictionary();
    totalTables = dict.tableCnt();
    progress = new SysOperationProgress();
    progress.setTotal(totalTables);
    progress.setCaption("@SYS90206");
    errorStack = new StackBase(Types::String);

    lastIdx = 3000;
    try
    {
        for (idx = lastIdx+1; idx <= totalTables; idx++)
        {
            tableId = dict.tableCnt2Id(idx);
            progress.setText(dict.tableName(tableId));

            lastIdx = idx;
            application.dbSynchronize(tableId, false, true, false);
            progress.incCount();
        }
    }
    catch (Exception::Error)
    {
        errorTxt = strFmt("'%1' (%2) tablosunda hata var!", tableId, dict.tableName(tableId));
        errorStack.push(errorTxt);
        retry;
    }

    setPrefix("@SYS86407");
    errorTxt = errorStack.pop();
    while (errorTxt)
    {
        error(errorTxt);
        errorTxt = errorStack.pop();
    }