Showing posts with label AX - Useful Things. Show all posts
Showing posts with label AX - Useful Things. Show all posts

Sunday, 15 December 2013

Add Image to Resource Node in AX and use it

adding image through resource

Upload image:

Use resource files in Axapta
In Application Object Tree, you can find resources node

Select resources node and right click; select Create from File, specify the file location for the new resource 

file. After that you can use this resource file in Axapta without specifying an absolute file path in your 

local/server system.

First, pick up the resource node from AOT;

SysResource::getResourceNode(); 

Then generate a temporary file for this resource file;
SysResource::saveToTempFile() 

Finally specify the temporary file path for controls. 

Here comes an example to show how to use a resource file as a background image of  a given form. 

{
ResourceNode            resourceNode;
FilePath  imagename;
;
resourceNode = SysResource::getResourceNode(resourcestr(ResourceName));
if (resourceNode)
{
resourceNode. AOTload();
imagename =  SysResource::saveToTempFile(resourceNode);
}
else
{
throw Error(“No file exists.”)

element.design().imageName(imagename); 
}

Example:

You can try "Resources" node to achieve your requirement.
Just Add a new resources under "Resources" node in AOT, than use following X++ code to access that image..
SysResource::getResourceNodeData(SysResource::getResourceNode('theaxapta_File'));

Tuesday, 29 October 2013

Create New user in Active directory

How to create Active Directory Users:
Administrator Tools >>  Active Directory Users and Computers
Click on User >>  To create new user in Active Directory ..
Once you create user then only you can add user to AX...

Click on the user you created for ex: sujju - RC on it >> properties..
Click on Member of - you must include administrator permission, to get administrator permissions to the user.

Else ax will not be open due to no granted permissions.

Tuesday, 15 October 2013

List Page Interaction Class

List page and form menuitem enable code

Listpage interaction class:
Code for Action pane button enable and disabling:
1. selectionChanged()
if(NetAgreement.Status == NetAgreementStatus::Approved && NetAgreement.FinalizeAgree == NoYes::No)
      this.listPage().actionPaneControlEnabled(formControlStr(NetAgreementList,FinalizeAgreement),true);
    else
        this.listPage().actionPaneControlEnabled(formControlStr(NetAgreementList,FinalizeAgreement),false);
2. selectionChanged()
public void selectionChanged()
{
    super();
    this.setButtonEnabled();
   
     if(netReservationTable.RentalApprovalState == ApprovalState::WorkflowCompleted)// && NetReservationListPage.& NetAgreement.FinalizeAgree == NoYes::No)
      this.listPage().actionPaneControlEnabled(formControlStr(NetReservationListPage,btnReserve),true);
    else
        this.listPage().actionPaneControlEnabled(formControlStr(NetReservationListPage,btnReserve),false);
   
   
   
}
Action pane button enabling and disabling in form:
Form –datasource-(table of data source)-active method:
1.Active():
if(NetAgreement.Status == NetAgreementStatus::Approved && NetAgreement.FinalizeAgree == NoYes::No)
      FinalizeAgreement.enabled(true);
    else
        FinalizeAgreement.enabled(false);
    //ended by poorna...04/09/2013
    return ret;
2.Active():
if(NetReservationTable.RentalApprovalState == ApprovalState::WorkflowCompleted)//&& NetAgreement.FinalizeAgree == NoYes::No)
      btnReserve.enabled(true);
    else
        btnReserve.enabled(false);
=====================================================

 

Listpage interaction class: example

Listpage interaction class:( NetReservationListPageInteraction-interaction class,
NetReservationListPage-listpage name , btnReserve-button name(autodeclaration yes),
NetReservation_NoFilter-listpage query, NetReservationTable-listpage table)
Class declaration:
public class NetReservationListPageInteraction extends ListPageInteraction
{
    smmLeadTable                smmLeadTable;
    smmActivityParentLinkTable  smmActivityParentLinkTable;
    QueryBuildRange             leadProcessRange;
    HierarchyName               selectedProcess;
    NetReservationTable         netReservationTable;
}
selectionChanged:
public void selectionChanged()
{
    super();
    this.setButtonEnabled();
     if(netReservationTable.RentalApprovalState == ApprovalState::WorkflowCompleted)// && NetReservationListPage.& NetAgreement.FinalizeAgree == NoYes::No)
      this.listPage().actionPaneControlEnabled(formControlStr(NetReservationListPage,btnReserve),true);
    else
        this.listPage().actionPaneControlEnabled(formControlStr(NetReservationListPage,btnReserve),false);
}
setButtonEnabled:
void setButtonEnabled ()
{
    boolean                 isCustomer;
    smmOpportunityTable     smmOpportunityTable;
    boolean                 enableContacts = false;
    DirOrgPersonRelations   dirOrgPersonRelations;
    netReservationTable = this.listPage().activeRecord(queryDataSourceStr(NetReservation_NoFilter, NetReservationTable));
   /* isCustomer = DirPartyTable::isCustomer(netReservationTable.Party);
    if (!netReservationTable.RecId || !netReservationTable.Party || isCustomer)
    {
        this.listPage().actionPaneControlEnabled(formControlStr(NetReservationListPage,createCustomer),false);
    }
    else
    {
        this.listPage().actionPaneControlEnabled(formControlStr(NetReservationListPage,createCustomer),true);
    }
    this.listPage().actionPaneControlEnabled(formControlStr(NetReservationListPage,customerButton),netReservationTable.RecId != 0 && isCustomer);
*/
}
setDBEnabled:
public void setDBEnabled()
{
    boolean                 isDraft;
    ;
        /*
    // DNS-Hussain on 12-09-2013
    netReservationTable = this.listPage().activeRecord(queryDataSourceStr(NetReservation_NoFilter, NetReservationTable));
    isDraft = netReservationTable.RentalApprovalState == ApprovalState::NotSubmitted;
    if(NetReservationTable.RentalApprovalState != ApprovalState::NotSubmitted)
    {
        NetReservationTable_ds.allowEdit(isDraft);
        NetReservationTable_ds.allowDelete(isDraft);
    }
    // end.
    this.setButtonEnabled();
     if(netReservationTable.RentalApprovalState == ApprovalState::WorkflowCompleted)// && NetReservationListPage.& NetAgreement.FinalizeAgree == NoYes::No)
      this.listPage().actionPaneControlEnabled(formControlStr(NetReservationListPage,btnReserve),true);
    else
        this.listPage().actionPaneControlEnabled(formControlStr(NetReservationListPage,btnReserve),false);
*/
}
==========================================================================================================

listpage enabling override methods(How to write methods on the list page Form in Ax 2012)

for enabling default override methods in list page we will set on property to group as

display target-- client(defautly it is auto we can change as client)




Scenario: I have a menu item that calls some class to do manipulation on the list page Form and I need to refresh the list page now. List pages do not allow writing of code on the Form, as they used interaction class.
Solution: You can write the code on list page buttons by setting DisplayTarget property to “Client” from auto. However after this change, you won’t be able to sue this button on the EP, so if you are thinking of using the same list page on the EP and planning to use the same button there, then do not do it. However f your domain is only the Form then you are good to do this.
Any ways override the clicked method and call research() of the data source to do this

How to delete a label file in Dynamics AX 2012

In this post we will look at how can we delete a label file in Dynamics AX 2012.Labels are no longer a file system like we had in 2009. We now have a new node in AOT - Label Files.

If you search in your application folder, you wont find the label file there.The application folder is located here.
"C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin\ Application\ Appl\Standard".
In Dynamics AX 2012, the label file is imported in your current model.
Now let us restart the AOS and see what happens. After restarting the AOS, go back to your application folder and try to find the label file again. This time the label file will be found.On every AOS restart, all label files will be copied to the application folder from the model store. So your label files are contained in your models but they are stored in your application folder as well.
Now let us try to delete the label file. Right click on your label file. Do you see a delete/remove option?
The answer is "No". so how do we delete the label file then? Below is the method by which a label file can be deleted easily.

  1. To create a temporary model
  2. Move our label file to the temporary model
  3. Stop the AOS
  4. Delete the temporary model
  5. Start the AOS
Let 's do step by step.
Go to Tools -> Model management -> Create model.
Enter name as TmpModel. Press OK. You will recieve an info message saying “The model TmpModel was created successfully in layer usr.”
Right click on your label file and select “Move to model”.
Select the TmpModel checkbox and press OK.
Stop the AOS.
Open command prompt (Microsoft Dynamics AX 2012 Management Shell). We will be using the command line utility AXUTIL to delete the model.
Issue the following command in the command prompt.
AXUTIL delete /model:TmpModel
You will be prompted if you want to delete the model or not. Press Y
Start the AOS.
Delete the label file from your application folder as well.
When you open AX now, you will get a dialog saying that “Your model store has been modified.” This is normal because each time you perform an operation on a model, you will get this dialog. Depending on your operation, you should select one of the option. Since we just deleted a model which just had a label file, select Skip.
Open AOT and notice that the label file is deleted now.

Sending Mail from Outlook

Sending email in AX is now as easy as 123.There are various ways by which we can send email in Dynamics AX. The code snippet shared here allows the user to send email through Microsoft Outlook using X++ code.The code is simple and easy to understand. 

    Description255             recipientEmail;
    Notes                            emailBody;
    Description255             subjectText;
    Filename                       fileName;
    SmmOutlookEmail         smmOutlookEmail = new SmmOutlookEmail();
  
    recipientEmail = "axuser@hotmail.com";
    subjectText     = "Test Email";
    fileName          = @"C:\Users\admin\Desktop\mypic.jpg";
    emailBody       = "Hi,\nThis is a test email for Dyanmics AX.\nThanks.";
  
    if (smmOutlookEmail.createMailItem())
    {
        smmOutlookEmail.addEMailRecipient(recipientEmail);
        smmOutlookEmail.addSubject(subjectText);
        smmOutlookEmail.addFileAsAttachment(fileName);
        smmOutlookEmail.addBodyText(emailBody);
        smmOutlookEmail.sendEMail(smmSaveCopyOfEMail::No,true);
    }
    else
    {
        error("Could not communicate with Microsoft Outlook Client.");
    }

So, if you want to send email directly without opening in Outlook, replace
smmOutlookEmail.sendEMail(smmSaveCopyOfEMail::No,true); 
with
smmOutlookEmail.sendEMail(smmSaveCopyOfEMail::No,false);
===============================================================================

Send task msg from current outlook in Dynamic AX


Hi,

static void AppointmentFrom
Outlook(Args _args)
 {
   COM    sysOutlookCollection;
   COM    receipiants;
   COM    collection;
   COMVariant comStartDate = new COMVariant();
   COMVariant comEndDate  = new
   COMVariant();
   COM    c;
   #SysOutLookCOMDEF
   #define.mapi("MAPI")
   #define.outlook("Outlook.Application")
   COM    sysOutlook;
   COM    sysOutlookNameSpace;
   COM    sysOutlookMAPIFolder;
   sysOutlook         = new COM(#outlook);
   sysOutlookNameSpace     = sysOutlook.getNamespace(#mapi);
   sysOutlookNameSpace.logon();  
   sysOutlookMAPIFolder    = sysOutlookNameSpace.getDefaultFolder(#OlDefaultFolders_olFolderTasks);
   collection         = sysOutlookMAPIFolder.items();
   c = collection.add();
   comStartDate.date(today());
   comStartDate.time(str2Time( "12:00:00"));
   comEndDate.date(today());
   comEndDate.time(str2Time( "12:15:00"));
   c.subject("This is the subject");
   c.body("Body of that msg");
   c.save();
   if (c)
   {
     receipiants = c.Recipients();
     receipiants.add("mdalfasith@gmail.com");
     receipiants.ResolveAll();
     c.assign();
     //c.display();
     c.send();
     info("Success msg in AX");
   }
   else
   throw error("@SYS31969");
   sysOutlookNameSpace.logoff();
 } 

Select Statement Queries

 
Select Statement Syntax for AX  
SelectStatement
=
select Parameters
Parameters
[ [ FindOptions ] FieldList from ] ] 
TableBufferVariable [ IndexClause ] Options ] WhereClause ] JoinClause ]
FindOptions
=
crossCompany | reverse | firstFast | [ firstOnly | firstOnly10 | firstOnly100 | firstOnly1000 ] | forUpdate | noFetch | [forcePlaceholders | forceLiterals] |forceselectorder | forceNestedLoop | repeatableRead
FieldList
=
Field { , Field } | *
Field
=
Aggregate FieldIdentifier ) | FieldIdentifier
Aggregate
=
sum | avg | minof | maxof | count
Options
=
[ order by , group by , FieldIdentifier [ asc | desc ] { , FieldIdentifier [ asc | desc ] }] | IndexClause ]
IndexClause
=
index IndexName | index hint IndexName
WhereClause
=
where Expression
JoinClause
=
[exists | notexists | outer ] join Parameters
 Keywords used in Select Statement

Keyword
Description
Example
asc
An option on the order by or group by clause. The sorting is ascending. (Sort is ascending by default.)
select * from custTable
    order by Name asc;
avg
Returns the average of the fields.
CustTable custTable;
;
select avg(value) from custTable;
print custTable.value;
count
Returns the number of records.
CustTable xCT;
int64 iCountRows; ;
Select COUNT(RecID) from xCT;
iCountRows = xCT.RecID;
crossCompany
Returns data for all companies that the user is authorized to read from. (A container can be added to reduce the number of companies involved.)
CustTable custTable;
container conCompanies = ['dat','dmo'];
;
select crossCompany :conCompanies
    * from custTable;
desc
An option on the order by or group by clause. The sorting is descending.
select * from custTable
    order by Name desc;
exists
A method that returns a Boolean value and a join clause.
while select AccountNum, Name from custTable
    order by AccountNum
    exists join * from ctr
    where (ctr.AccountNum ==
      custTable.AccountNum)
firstFast
A priority hint. The first row appears more quickly but the total return time for this option might be slower. The firstFast hint is automatically issued from all forms, but is rarely used directly from X++.
select firstFast custTable
    order by AccountNum;
firstOnly
Speeds up the fetch. Instructs MorphX to fetch only the first record.
static InventTable find(
    ItemId   itemId,
    boolean  update = false)
{
    InventTable inventTable;
    ;
    inventTable.selectForUpdate
        (update);
    if (itemId)
    {
         select firstonly inventTable
            index hint ItemIdx
            where inventTable.itemId
                == itemId;
    }
    return inventTable;
}
firstOnly10
Same as firstOnly, except returns 10 rows instead of one.
firstOnly100
Same as firstOnly, except returns 100 rows instead of one.
firstOnly1000
Same as firstOnly, except returns 1000 rows instead of one.
forceLiterals
Note
You are advised not to use the forceLiterals keyword in X++ select statements, because it could expose code to an SQL injection security threat.
forceLiterals instructs the kernel to reveal the actual values that are used in where clauses to the Microsoft SQL Server database at the time of optimization.
forceLiterals and forcePlaceholders are mutually exclusive.
forceNestedLoop
Forces the Microsoft SQL Server database to use a nested-loop algorithm to process a particular SQL statement containing a join algorithm. This means that a record from the first table is fetched before any records from the second table are fetched. Typically, other join algorithms, such as hash-joins and merge-joins, would be considered. This keyword is often combined with the forceSelectOrder keyword.
while select forceSelectOrder
    forceNestedLoop inventTransThis
    index hint TransIdIdx
    where inventTransThis.InventTransId
        == inventTrans.InventTransId
        && inventTransThis.StatusIssue
        <= StatusIssue::ReservOrdered
forcePlaceholders
Instructs the kernel not to reveal the actual values used in where clauses to the SQL Server database at the time of optimization. This is the default in all statements that are not join statements.
The advantage of using this keyword is that the kernel can reuse the access plan for other similar statements with other search values. The disadvantage is that the access plan is computed without taking into consideration that data distribution might not be even. The access plan is an on-average access plan.
forcePlaceholders and forceLiterals are mutually exclusive.
static void forcePlaceHoldersExample(Args _args)
{
    SalesTable salesTable;
    SalesLine salesLine;
    ;
    while select forcePlaceholders salesLine
        join salesTable
           where salesTable.SalesId ==
            salesLine.SalesId
               && salesTable.SalesId == '10'
    {
        //more code
    }
}
forceSelectOrder
Forces the SQL Server database to access the tables in a join in the specified order. If two tables are joined, the first table in the statement is always accessed first. This keyword is often combined with the forceNestedLoop keyword.
display ForecastHasPurch hasForecastPurch()
{
    ForecastPurch   forecastPurch;
    InventDim       inventDim;
    ;
    select firstOnly forcePlaceholders
        forceSelectOrder recId
        from forecastPurch
        index hint ItemIdx
        where forecastPurch.itemId == this.itemId
    exists join inventDim
        index hint DimIdIdx
        where inventDim.inventDimId ==
            forecastPurch.inventDimId
        && inventDim.configId == this.configId;
    return forecastPurch.recId;
}
forUpdate
Selects records exclusively for update. Depending on the underlying database, the records may be locked for other users.
ttsBegin;
while select forUpdate ledgerJournalTrans
    index hint NumVoucherIdx
    where ledgerJournalTrans.journalNum ==
    _journalNum &&
    ledgerJournalTrans.voucher == _voucher
{
    ledgerJournalTrans.doDelete();
    counter++;
}
if (counter
    && ledgerJournalTable.journalType
    != LedgerJournalType::Periodic)
{
    NumberSeq::release(
      ledgerJournalTable.voucherSeries,
      _voucher);
}
ttsCommit;
group by
Instructs the database to group selected records by fields.
CustTable custTable;
;
while select sum(CreditMax) from custTable
    group by CustGroup
{
    print custTable.CustGroup, " ",custTable.CreditMax;
}
index
Instructs the database to sort the selected records as defined by the index.
CustTable custTable;
;
while select AccountNum, Name from custTable
    index AccountIdx
{
    print custTable.AccountNum, " ", custTable.Name;
}
index hint
Gives the database a hint to use this index to sort the selected records as defined by the index. The database can ignore the hint.
Note
A wrong index hint can have a big performance impact. Index hints should only be applied to SQL statements that do not have dynamic where clauses or order by clauses, and where the effect of the hint can be verified.
while select forUpdate ledgerJournalTrans
    index hint NumVoucherIdx
    where ledgerJournalTrans.journalNum
        == _journalNum
join
Used to join tables on a column that is common to both tables. The join criteria are specified in the where clause because there is no on clause in X++ SQL.
Reduces the number of SQL statements that are needed if you want to loop through a table and update transactions in a related table.
For example, if you process 500 records in a table, and want to update related records in another table, and use a nested while select to do this, there will be 501 trips to the database. If you use a join, there will be a single trip to the database.
while select ledgerTable
    join ledgerTrans
        where ledgerTrans.accountNum ==
            ledgerTable.accountNum
    {
        amountMST += ledgerTrans.amountMST;
    }
maxof
Returns the maximum of the fields.
CustTable custTable;
;
select maxof(CreditMax) from custTable;
minof
Returns the minimum of the fields.
CustTable custTable;
;
select minof(CreditMax) from custTable;
noFetch
Indicates that no records are to be fetched at present. This is typically used when the result of the select is passed on to another application object, for example, a query that performs the actual fetch.
select noFetch custTable
    order by AccountNum
notExists
Chosen only if there are no posts.
while select AccountNum, Name from custTable
    order by AccountNum
    notExists join * from ctr
    where (ctr.AccountNum ==
        custTable.AccountNum)
optimisticLock
Forces a statement to run with Optimistic Concurrency Control even if a different value is set on the table.
For more information, see Optimistic Concurrency Control.
select optimisticLock custTable
    where custTable.AccountNum > '1000'
order by
Instructs the database to sort the selected records by fields in the order by list.
select * from custTable
    order by accountNum desc
    where custTable.AccountNum > "100";
outer
Returns all rows from the first-named table, including rows that have no match in the second-named table. This is a left outer join, although there is no left keyword. There is no right outer join in X++ SQL.
while select AccountNum, Name
    from custTable
    order by AccountNum
    outer join * from ctr
    where ctr.AccountNum == custTable.AccountNum
pessimisticLock
Forces a statement to run with Pessimistic Concurrency Control even if a different value is set on the table.
select pessimisticLock custTable
    where custTable.AccountNum > '1000'
repeatableRead
Specifies that no other transactions can modify data that has been read by logic inside the current transaction, until after the current transaction completes.
An explicit transaction completes at either ttsAbort or at the outermost ttsCommit.
For a stand-alone select statement, the transaction duration is the duration of the select command. However, the database sometimes enforces the equivalent of repeatableRead in individual select statements even without this keyword appearing in your X++ code (depending on how the database decides to scan the tables).
For more information, see the documentation for the underlying relational database product.
reverse
Records are returned in reverse order.
select reverse custTable
    order by AccountNum;
sum
Returns the sum of the fields. Can be used to sum all accounts, order lines, and so on.
CustTable custTable;
;
select sum(CreditMax) from custTable;


select containerLine.*
  from WHSCONTAINERLINE containerLine
 inner join WHSWORKTABLE workTable on workTable.CONTAINERID = containerLine.CONTAINERID
    inner join WHSLOADLINE whsloadline on whsloadline.RECID = containerLine.LOADLINE
inner join WHSWORKINVENTTRANS trans on trans.INVENTTRANSIDPARENT = whsloadline.INVENTTRANSID and trans.WORKID = workTable.WORKID
    where  containerLine.CONTAINERID = '0000156938'