Günü Sözü

"Hiçbir şey bilmeyen cahildir, ama bilip de susan ahlaksızdır. " Bertolt Brecht.
"İyilik yapabildiğim zaman mutlu olurum; ama en büyük mutluluk yapılan bir haksızlığı düzeltmektir." Tolstoy

6 Aralık 2016 Salı

Ax 2012, aot raporu ve fetch metodu / MorphX rapor toolu ile yapılan raporlarda filtreleme ve fetch metodu

not: datasource da range ile karıştırmayalım. burada yapılan işlem kayıtlarda tek tek döndürülürken istemediğimiz kayıtların raporda görünmesini engellemek. Fetch metodu; beyaz sayfa raporları dediğimiz morphx raporlama araçları ile yapılan raporlarda çok kullandığımız bir  metod.

public boolean fetch()
{
    boolean ret = false; // geri dönüş değerimizi setliyoruz default false veriyoruz.
    BankAccountTable_TR  bankAccountTable;
    QueryRun qrun;
    ;

    qrun = new QueryRun(element);

    // eğer qrun değer döndürmez ise false döndürüyoruz.
    if (! qrun.prompt())
    {
        return ret;
    }

    // query de döngü ile istediğimiz kaytların rapora gönderilmesini sağlayacağız
    while (qrun.next())
    {
// query deki kaydımızı referans tablomuza setliyoruz.
        bankAccountTable = qrun.get(TableNum(BankAccountTable_TR));

//istemediklerimizi filtreliyoruz
        if (bankAccountTable.AccountID != "OBANK")
            {
                // şartları sağlayan kayıtlarımızı raporumuza ekliyoruz yada gönderiyoruz
                element.send(bankAccountTable);
            }
    }
    ret = true; // artık geri dönüş değerini true yapabiliriz

        return ret;
}

24 Ekim 2016 Pazartesi

Ax 2012 Human Resources / İnsan Kynakları / BorAx modülü personel bilgileri import

Ax 2012 Human Resources / İnsan Kynakları / BorAx modülü personel bilgilerinin Excel den import edilmesi.

ax 2012 de insan kaynakları yada borax ta personel bilgilerini (kimlik bilgileri, banka bilgileri vs..) güncellemek yada sıfırdan (excel, csv..) import etme ihtiyacını duyabiliriz. umarım bu paylaşım faydalı olur.

önce Erd diyagramı paylaşayım.
https://www.microsoft.com/dynamics/ax/erd/ax2012r2/Erd-One-HumanRes-HR1-HcmBenefits.htm


bu job değiştirilerek insert yada parçalı update yapılabilir, aynı zamanda işlem yapılan kayıtları txt dosyasınada yazar.


static void ckr_Hr_boraxUpdImport(Args _args)
{
    SysExcelApplication application;
    SysExcelWorkbooks   workbooks;
    SysExcelWorkbook    workbook;  
    SysExcelWorksheet   worksheet;
    SysExcelCells       cells;

    COMVariantType      type;
    int                 row;

    FileName            filename;
    Dialog              dialog;
    dialogfield         dfile;

    BorAXEmplTable              _boraxEmplTable;
    BoraxEmplId                 _boraxEmplId;
    HcmWorker                   _hcmWorker;
    HcmPersonnelNumberId        _hcmPersonnelNumberId;
    DirPerson                   _dirPerson;
    DirPersonName               _dirPersonName;
    DirPartyTable               _dirPartyTable;

     boolean ret  = true;

    // txt
    TextIO file;
    container line;
    #define.filename('c:\\personelimport.txt')
    #File
    //
    ;
                file = new TextIO(#filename, 'W+');
                if (!file || file.status() != IO_Status::Ok)
                {
                    throw error("File cannot be opened.");
                }
    //txt

    application         = SysExcelApplication::construct();
    workbooks           = application.workbooks();
    Dialog              = new dialog("Dosya seçin");
    dfile               = dialog.addField(extendedTypeStr(FileNameOpen),"Dosya");

    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++;

    try
    {
    ttsbegin;
    do
    {
        row++;
        _hcmPersonnelNumberId            = cells.item(row, 1).value().bStr();
        _boraxEmplTable.clear();

        select forUpdate _boraxEmplTable where _boraxEmplTable.EmplId == _hcmPersonnelNumberId;//cells.item(row, 1).value().bStr();

         if (_boraxEmplTable)
         {
            _boraxEmplTable.PersonnelNumber = cells.item(row, 2).value().bStr();
            _boraxEmplTable.OldEmplId = cells.item(row, 2).value().bStr();
            _boraxEmplTable.EmplId = cells.item(row, 3).value().bStr();
            _boraxEmplTable.EmplName = cells.item(row, 4).value().bStr();
            _boraxEmplTable.StartDate = cells.item(row, 5).value().date();
            _boraxEmplTable.EndDate= cells.item(row, 6).value().date();
            _boraxEmplTable.TCIDNumber = cells.item(row, 7).value().bStr();
            _boraxEmplTable.update();

          select forUpdate _hcmWorker where _hcmWorker.PersonnelNumber == _hcmPersonnelNumberId;//cells.item(row, 1).value().bStr();

         if (_hcmWorker)
         {
            _hcmWorker.PersonnelNumber = cells.item(row, 2).value().bStr();
            _hcmWorker.update();

            _dirPersonName   = dirPersonName::find(_hcmWorker.Person, true);

                if (_dirPersonName)
                {
                    _dirPersonName.validTimeStateUpdateMode(ValidTimeStateUpdate::Correction);
                    _dirPersonName.FirstName = cells.item(row, 2).value().bStr();
                    _dirPersonName.MiddleName = cells.item(row, 3).value().bStr();
                    _dirPersonName.LastName= cells.item(row, 4).value().bStr();

                    _dirPersonName.update();               
                }

                // txt dosyaya yaz başla
                file.outFieldDelimiter(';');// for semicolon seperator
                line = [_hcmPersonnelNumberId,cells.item(row, 4).value().bStr(),cells.item(row, 5).value().date(), cells.item(row, 6).value().date(),
                            cells.item(row, 7).value().bStr()];
                file.writeExp(line);
                //txt bitir
         }
         type = cells.item(row+1, 1).value().variantType();
    }

    while (type != COMVariantType::VT_EMPTY);
    ttscommit;
    info("işlem başarıyla tamamlandı. hadi hayırlı olsun.");
    }

    catch
   {
        info(strFmt(" Personel Hesabı : %1 ",cells.item(row, 1).value().bStr()));
        info("işlem sırsaında bir hata oluştu :(");
    }
    application.quit();
}


20 Eylül 2016 Salı

Ax 2012 ssrs -rapor hatası: Error while setting server report parameters. Error message: The DefaultValue expression for the report parameter ‘AX_CompanyName’ contains an error: Request for the permission of type 'System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. (rsRuntimeErrorInExpression)

Error while setting server report parameters. Error message: The DefaultValue expression for the report parameter ‘AX_CompanyName’ contains an error: Request for the permission of type 'System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. (rsRuntimeErrorInExpression)

Ax 2012 de ssrs raporu çalıştırdığımızda bu hata mesajı ile karşılayor iseniz çözümü için aşağıdaki makaleden faydalanabilirsiniz.
https://technet.microsoft.com/en-us/library/hh389774.aspx


export edilen konfigürasyon dosyasını sql sunucusundaki -sql sever versiyonuna göre bu klasör yolu farklıdır-  bin klasörünün altına kopyaladığınızda bu problem düzelecektir. Örn.
\Program Files\Microsoft SQL Server\MSRS12.[SSRSInstanceName]\Reporting Services\ReportServer\bin.

19 Eylül 2016 Pazartesi

AX 2012 - sql veritabanının suspect mode düşmesi ve onarımı

database suspect moda düştü ise aşağıdaki adımları takip edelim.

https://msdn.microsoft.com/en-us/library/ms176064.aspx


EXEC sp_resetstatus [databaseadi];
ALTER DATABASE [databaseadi] SET EMERGENCY
DBCC checkdb([databaseadi])
ALTER DATABASE [databaseadi] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DBCC CheckDB ([databaseadi], REPAIR_ALLOW_DATA_LOSS)
-veri kaybı yaşanabilir
ALTER DATABASE [databaseadi] SET MULTI_USER



 Veritabanı Günlük dosyasını SQL aracılığıyla küçültme / Shrink a Database Log file through SQL

Dynamics AX 2012.

USE AXDev;

GO

— log veritabanını  SIMPLE moda alalım

ALTER DATABASE AXDev

SET RECOVERY SIMPLE;

GO

— log database 1 mb ta küçültelim

DBCC SHRINKFILE (AXDev, 1);

GO

— şimdi FULL moda alalım tekrar

ALTER DATABASE AXDev

SET RECOVERY FULL;

GO

10 Mart 2016 Perşembe

General Ledger - Trial Balance. From date is in fiscal year xxxx. to date is in fiscal year xxxx. dates must be in same fiscal year.

 Ax 2012 R3 Cu 10 cu 11

General Ledger - Trial Balance. From date is in fiscal year xxxx. to date is in fiscal year xxxx. dates must be in same fiscal year.

Getting this error while running the Trial balance. 

veya Genel muhasebe - Geçici mizan. parametrelerden iki tarih arası filtre verirken 

Geçici Mizanda iki tarih aralığında 01.01.xxxx - 31.12.xxxx parametrelerden güncelleştirme yapılmak istendiğinde " Başlangıç tarihi xxxx mali yılında. Bitiş tarihi ise xxxx mali yılında. Tarihler aynı mali yıl içinde olmalıdır. " hatası veriyor ise

aşağıdaki adımlar ile bu sorun çözülür.

1. Access the AOT (CTRL +D).

2. Navigation: Tools > Caches > "Refresh Dictionary" and "Refresh Data"

3. Delete .auc files.  ( Location -> C:\Users\xxx\AppData\Local\xxx.auc)

4. 

had the same issue was resolved by clearing the cache on the effected AOS via a job.

You can run the same and see if it solves your issue.

static void ClearCache(Args _args)

{

   LedgerCache::clearAllScopes();

   pause;

}



2 Mart 2016 Çarşamba

bir katmandan başka bir katmana projeleri taşıma, kimlik id leri korunarak taşıma


Move objects from one layer to another in AX 2012 by retaining object ids


Step 1. Create a new model and create a CUS layer project in this new model.

Step 2. Move all the CUS layer objects into this new model and export the project as an xpo.

Step 3. Export the required languages ald files from the label files created in CUS layer by navigating to AOT-> “Label Files” -> Languages

Step 4. Stop AOS.

Step 5. Backup model and business data dbs.

Step 6. Uninstall all the models in CUS layer and then start the AOS.

Step 7. Synchronize the database from the AOT. This will delete the data but we will retrieve it later.

Step 8. Create a new model in VAR layer then import the xpo from the xpo backup taken in step 2.

Step 9. Import the ald files from Step 3 into  the new model by navigating to AOT-> “Label Files”.( Right-click on the Label file node and use option “Create from File).

Step 10. Stop AOS and export this new model.

Step 11. Restore the model and business data databases that was backed up in step 5.

Step 12. Import the new model from step 10,  Start the AOS and then Synchronize Data dictionary.
 This restores the Id’s of all the new objects. So no data will be lost.

Step 13. Stop AOS, Uninstall all the models in CUS layer and then start the AOS.

Step 14. Synchronize and compile the application.

23 Şubat 2016 Salı

control class ile ms dynamics ax 2012 de ssrs rapor geliştirme örneği - using controller class in developing SSRS Reports in ms dynamics ax 2012

aşağıdaki seneryolar, controller class kullanılarak yapılacak
 
Giriş verileri temel alan bir rapor sorgusunu değiştirme
 
Following are the scenarios where Controller class can be used:
  1. Modifying a report query based on the input data
  2. Modifying report contract data based on the input data
  3. Control a report parameters dialog
  4. Open different reports/designs from the same menu item based on the input data
  5. Reports that are opened from a form
To create a controller class, extend it with SrsReportRunController.
 

Prerequisites

  1. Microsoft Dynamics AX 2012
  2. Reporting services extensions must be installed in Dynamics AX

Sample Controller Class

  1. Create a new class. Open AOT → Classes
  2. Right Click on Classes and select New Class. Name it as SSRSDemoController.
  3. example of creating a new class in Dynamics AX
     
  4. Open the Class declaration by right clicking on it and selecting View code.
  5. example of viewing code in AOT class AX
     
  6. Now write the following code:


  7. Create a new method and write the following code:

16 Şubat 2016 Salı

Default boyutlu hareketlerin excele aktarımı

how to export transactions with default dimensions to Excel
public static void main(Args _args)
{
    AssetTrans assetTrans; 
    SysExcelApplication application;
    SysExcelWorkBooks workbooks;
    SysExcelWorkBook workbook;
    SysExcelWorksheets worksheets;
    SysExcelWorksheet worksheet;
    SysExcelCells cells;
    SysExcelCell cell;
    int row;
    DimensionAttributeValueSetItemView dimAttrSet;
    DimensionAttribute dimAttr;
    str dimAttrStr;
    Map dims;
    int dimNum;
    ;
    application = sysExcelApplication::construct();
    workbooks = application.workbooks();
    workbook = workbooks.add(); 
    worksheets = workbook.worksheets();
    worksheet = worksheets.itemFromNum(1);
    cells = worksheet.cells();
    cells.range(‘A:A’).numberFormat(‘@’);
    dims = new Map(Types::String, Types::Integer);
    //generate header    row++;
    cell = cells.item(row, 1); 
    cell.value(“Voucher“);
    cell = cells.item(row, 2); 
    cell.value(“Transaction date“);
    cell = cells.item(row, 3); 
    cell.value(“Fixed asset number“);
    cell = cells.item(row, 4); 
    cell.value(“Transaction type“);
    cell = cells.item(row, 5);
    cell.value(“Amount“);
    cell = cells.item(row, 6); 
    cell.value(“Fixed asset group“);
    //generate lines    while select assetTrans
    //The following loop will provide the data to be populated in each column    {
        row++;
        //add fixed asset trans data        cell = cells.item(row,1);     
        cell.value(assetTrans.Voucher);
        cell = cells.item(row,2);
        cell.value(assetTrans.TransDate);
        cell = cells.item(row,3);
        cell.value(assetTrans.AssetId);
        cell = cells.item(row,4);
        cell.value(enum2str(assetTrans.TransType));
        cell = cells.item(row,5);
        cell.value(assetTrans.AmountCur);
        cell = cells.item(row,6);
        cell.value(assetTrans.AssetGroup);
        // add dimensions        while select dimAttrSet
            where dimAttrSet.DimensionAttributeValueSet == assetTrans.DefaultDimension
        join Name from dimAttr
            where dimattr.RecId == dimAttrSet.DimensionAttribute
        {
            if (!dims.exists(dimAttr.Name)) // if dim column does not exists            {
               //add dimension column               dims.insert(dimAttr.Name, dimNum + 7);
               dimNum++;
               cell = cells.item(1, dims.lookup(dimAttr.Name));
               cell.value(dimAttr.Name);
            }
           //add dimension value           cell = cells.item(row, dims.lookup(dimAttr.Name));
           cell.value(dimAttrSet.DisplayValue);
        }
    }
    application.visible(true); // opens the excel worksheet}

27 Ocak 2016 Çarşamba

ax 2012, X++ kodları ile özelleştirilmiş lookup. ax 2012 X++ code to create a customized lookup on form

X++ code to create a customized lookup on form
Override the lookup method on Formdatasource field(on which you want to show lookup) , and copy the following code to your method.
Comment the super() method in the lookup.

public void lookup(FormControl _formControl, str _filterStr)
{

SysTableLookup sysTableLookup; // systemclass to create //customlookup
Query query;
QueryBuildDataSource qbd;

;
sysTableLookup = SysTableLookup::newParameters(tablenum(InventTable),_formcontrol);

// Construct query on the table,
// whose records you want to show as lookup.
query = new Query();
qbd = query.addDataSource(tablenum(InventTable));
qbd.addRange(fieldnum(InventTable,ItemType)).value(SysQuery::value(enum2str
(ItemType::Item)));

// add the fields to the lookup list
sysTableLookup.addLookupfield(fieldnum(InventTable,ItemId));
sysTableLookup.addLookupfield(fieldnum(InventTable,ItemName));

// pass the query as parameter
// system will show the records in the lookup
// as per your query
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();

}


Building Lookups - Using a form for lookup building

In numerous situations, standard, automatic, or even dynamic runtime lookups cannot display the required data. For example, it might be a lookup with tab pages or a search field. In such cases, Dynamics AX offers the possibility to create an AOT form and use it as lookup.
In this recipe, we will demonstrate how to create a lookup using an AOT form. As an example, we will modify the standard customer account lookup to display only active customers.

How to do it...

  1. 1. In AOT, create a new form called CustLookup. Add a new data source with the following properties:
    PropertyValue
    NameCustTable
    TableCustTable
    AllowCreateNo
    AllowEditNo
    AllowDeleteNo
    AllowCheckNo
    OnlyFetchActiveYes
    IndexAccountIdx

  1. 2. Change the form's following design properties:
    PropertyValue
    FrameBorder
    WindowTypePopup

  1. 3. Add a new Grid to the form's design:
    PropertyValue
    NameCustomers
    ShowRowLabelsNo
    DataSourceCustTable

  2. 4. Add a new StringEdit control to the grid:
    PropertyValue
    NameAccountNum
    DataSourceCustTable
    DataFieldAccountNum
    AutoDeclarationYes

  1. 5. Add another StringEdit control to the grid, right after AccountNum:
    PropertyValue
    NameName
    DataSourceCustTable
    DataFieldName

  1. 6. Add one more StringEdit control to the grid, right after Name:
    PropertyValue
    NamePhone
    DataSourceCustTable
    DataFieldPhone

  1. 7. Add a new ComboBox control to the end of the grid:
    PropertyValue
    NameBlocked
    DataSourceCustTable
    DataFieldBlocked

  1. 8. Override the form's init() method with the following code:
    public void init()
    
    {;
    super();
    element.selectMode(AccountNum);
    }
    
  2. 9. Override the form's run() with the following code:
    public void run()
    
    {
    FormStringControl callingControl;
    boolean filterLookup;
    ;
    callingControl = SysTableLookup::getCallerStringControl(
    element.args());
    filterLookup = SysTableLookup::filterLookupPreRun(
    callingControl,
    AccountNum,
    CustTable_ds);
    super();
    SysTableLookup::filterLookupPostRun(
    filterLookup,
    callingControl.text(),
    AccountNum,
    CustTable_ds);
    }
    
  3. 10. Finally, override init() of the CustTable data source with the following code:
    public void init()
    
    {
    Query query;
    QueryBuildDataSource qbds;
    QueryBuildRange qbr;
    ;
    query = new Query();
    qbds = query.addDataSource(tablenum(CustTable));
    qbr = qbds.addRange(fieldnum(CustTable, Blocked));
    qbr.value(queryvalue(CustVendorBlocked::No));
    this.query(query);
    }
    
  4. 11. The form in AOT should look like this:























  1. 12. Locate the extended data type CustAccount in AOT, and change its property:
    PropertyValue
    FormHelpCustLookup

  1. 13. To test the results, open Accounts receivable | Sales Order Details and start creating a new sales order. Notice that now Customer account lookup is different, and it includes only active customers: