9 Aralık 2013 Pazartesi

AXAPTA - Default Currency and Language

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

AXAPTA - Change Company

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

        ...
        Header.save();
    }

28 Kasım 2013 Perşembe

AXAPTA - Drop-down to table's container field at form

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 - Make a table field works cross-company


I learned this way from a forum . You have to just create a relation like up and care about extended data type of related fields. After that you won't need a custom lookup or supress validate method at forms. It works at AX 2009, I had no change to test with 2012.

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();
}


Don't forget to supress control's validate method!..

18 Kasım 2013 Pazartesi

AXAPTA - Skip some combobox enum items

I found the solution from a forum:

This code part should write after control's Enter methods super keyword:

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


Don't forget to set AutoDataGroup = No if control is under a parent datagroup.

14 Kasım 2013 Perşembe

AXAPTA - fast search with grid

Do not use find method for this, it works so slow with big tables. This's the way which Axapta uses with it's own forms:
 element.args().lookupField(fieldnum(SMAServiceOrderTable, ServiceOrderId));
element.args().lookupValue(_myServiceOrderId);
SMAServiceOrderTable_ds.executeQuery();

5 Kasım 2013 Salı

AXAPTA - Password field with tables

I followed up Greg on Dynamics AX blog when creating this page.

Firstly we have to add a container field at our table and change it's extended data type as CryptoBlob .

Edit method for our password field:

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


Method get password with X++ code:
Password getPassword()
{
    CryptoBlob cryptoBlob;
    ;
    cryptoBlob = this.Password;
    return (cryptoBlob == connull()) ? '' :
        cryptoblob2str(WinapiServer::cryptUnProtectData(cryptoBlob));
}


Method set password with X++ code:

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

Dot't forget PasswordStyle set to Yes of our form control.

10 Ekim 2013 Perşembe

AXAPTA - Join table A with table B and table A with table C

I can do this with a way which I got from a forum forumda . Trick is fetchMode command. Without fetchMode command can't generate a correct select command. 
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 service "CLR object cannot be marshaled to Microsoft Dynamics anytype." error

SenderTel2      = line.get_senderTel2();

If you get "CLR object cannot be marshaled to Microsoft Dynamics anytype." error message when reading value from any services property when value is null and can't hide this error even use try/catch, you have to do:

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

23 Temmuz 2013 Salı

AXAPTA - Lookup and sort

When creating lookup you will see lookup won't run with your selected sort field:

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();
}


If you may do this change, you will see your lookup how  do you want to do:

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 - Setfocus to a specified control when opening form

Should write a setfocus for control at form's firstField method:

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

12 Temmuz 2013 Cuma

AXAPTA - Timezone difference when getting server datetime value

DateTimeUtil classes utcNow method gives time as  Greenwich time. When getting and setting datetime it needs convert:

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

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

11 Temmuz 2013 Perşembe

AXAPTA - Print barcode

Blogs about barcode printing with Axapta usually same each other. There are some problems with Axapta barcode printing and none of them mentioned these problems. I wrote tricks about them at this page:

Code 128:

display BarCodeString ServiceObjectbarCode()
{
    Barcode barcode;
    ;

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


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


After drag and drop this display method to report section:

Font - BC C128 Narrow

Width - This value shouldn't be auto. Axapta terminate label before needed length. Needed length can find with a few try. I used 10 cm with my sample.
Fontsize - 24 (I couldn't success write readable barcodes below 24. Some bigger font sizes cannot read with barcode reader too, need tries).

Code 39 :
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
I didn't have trouble when using Code39 about width property when selected Auto. Like Code 128 I had trouble with font sizes below 24 and some sizes upper 24. It may be about my barcode reader.

4 Temmuz 2013 Perşembe

AXAPTA - Set cursor to a record fast with grid

Findrecord and findvalue methods are so slow for set a record for current. Instead of these filter method can be use but with filter just filtered records can be view. If you want see all records and set cursor to a specific record can use this way which I found  at a blog uses from Axapta with also original lookup forms:

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

SMAServiceOrderTable_ds.executeQuery();


It's so fast but don't forget to use indexed field for search.

24 Haziran 2013 Pazartesi

AXAPTA - Make display methods faster with cacheAddMethod

Axapta may call display methods over and over when navigating in table. If there are a lot of display methods it would be a trouble. cacheAddMethod provides save display methods at server and gives good performance increase. This method can be call after datasource's init method. If called from at wrong place it would be a reason of frozen of Axapta. Also this type display methods should be "table" methods.
This technique also works for edit methods.
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));
}


Cached display/edit methods don't update before update methods run. When necessary refresh display methods before update, you may use cacheCalculateMethod:
B_CallTrack_DS.cacheCalculateMethod(tableMethodStr(B_CallTrack, EndUserWarrantyStart));
 


Update for AX 2012:

This process eaiser with AX 2012. You can  use SysClientCacheDataMethodAttribute. There's an optiona parameter too. If you send true for this parameter update issue at upper solved with automatically. But with this way display/edit method will be cached in all forms. If you don't want this old way sill valid.


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

AXAPTA - Display method authorization check

//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 - Begin and end of the day

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

23 Mayıs 2013 Perşembe

AXAPTA - Copy to clipboard

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

19 Nisan 2013 Cuma

AXAPTA - Show company logo at reports

First you  have to upload company logo. For this:

From Basic->Setup->Company informations->Company logo upload your logo.

After that write code below which I found from  this address  as display method:

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


Pull this method to header. Don't forget arrange Height and Width values manual and change ResizeBitmap property to Yes.

25 Mart 2013 Pazartesi

AXAPTA Read text file

...
    Filename                Filename;
    System.IO.StreamReader  readFile;
    System.String           line;

    int hwnd; 
    ; 
    hwnd = infolog.hwnd(); 
    Filename = WinApi::getOpenFileName(hwnd,['TXT files','*.txt'],"","Text Files");
//    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();
...        



There are other ways, one of them is at Fatih Demirci's blog.

8 Şubat 2013 Cuma

6 Şubat 2013 Çarşamba

4 Şubat 2013 Pazartesi

AXAPTA - Catch tabbed dialog enter and exit

Use  pageActivated() for catch enter tabbed dialog, use allowPageDeactivate() for catch exit. I tried to use Lostfocus() and GotFocus() with no success.

31 Ocak 2013 Perşembe

AXAPTA - Send alert to a user

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 - Create Sales Order with X++

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