Sunday, April 12, 2015

Create a New Report Project by Using Controller Class

Normally, creating report by using controller class when the report is attached to existing form in system. Now, I will show you the recommended structure when creating this kind of project as below:
             * Project Name
                      + Data Dictionary
                                 - System Table
                                 - Temporary Table
                      + Classes
                      + Form
                      + Queries
                      + VisualStudioAXModelProjects
                      + SSRSReports
                      + MenuItems
                                 - Action
 The purpose of creating above structure are:
- Project Name: For indicating name of project. You can put whatever name that fit to your project.
- Data Dictionary: For containing data dictionary group such as table, view, extended datatype ... etc
- Classes: For containing controller class and data provider base class
- Form: For containing all form related to your project
- Queries: For containing all queries related to your project
- VisualStudioAXModelProjects: For containing VisualStudioAXModelProjects. It is where you design RDLC report in Ms Visual Studio.
- SSRSReports: For containing all SSRSReports of your project
- MenuItems: For containing MenuItems with type Action that will be place on form that you need to open your report.

Here is further detail with coding in classes:
* Controller class
public class YourControllerClassName extends SrsReportRunController
{
    InventTransferTable mmkInventTransferTable;


}

* setRange Method of Controller class
public void setRange(Args _args, Query _query)
{
    QueryBuildDataSource        mmkQBDS;
    QueryBuildRange             mmkQR;

    if(_args && _args.dataset())
    {
        switch(_args.dataset())
        {
            case tableNum(InventTransferTable):
                mmkInventTransferTable = _args.record();
                break;
        }
    }

    mmkQBDS = _query.dataSourceTable(tableNum(InventTransferTable));
    mmkQBDS.clearRange(fieldNum(InventTransferTable, RecId));
    mmkQR = mmkQBDS.addRange(fieldNum(InventTransferTable, RecId));
    if(mmkInventTransferTable)
    {
        mmkQR.value(queryValue(mmkInventTransferTable.RecId));
    }
}


* main Method of Controller Class
 public static void main(Args _args)
{
    DpcMmkSTController    mmkController = new DpcMmkSTController();
    mmkController.parmReportName(ssrsReportStr(rptST , mmkDesign));
    mmkController.parmArgs(_args);
    mmkController.setRange(_args,
             mmkController.parmReportContract().parmQueryContracts().lookup(mmkController.getFirstQueryContractKey()));
    mmkController.parmShowDialog(false);
    mmkController.startOperation();
}


 * Data Provider Base Class
[
    SRSReportQueryAttribute(queryStr(qryDpcMmkST))
]
class DpcMmkSTDPB extends SRSReportDataProviderBase
{
    tblSTHeaderTemp     mmkTblSTHeaderTemp;
    tblSTDetailTemp     mmkTblSTDetailTemp;
}


* getHeader Method of Data Provider Base Class
[
    SRSReportDataSetAttribute(tableStr(tblSTHeaderTemp))
]
public tblSTHeaderTemp getHeader()
{
    select * from mmkTblSTHeaderTemp;
    return mmkTblSTHeaderTemp;
}


* getLine Method of Data Provider Base Class
[
    SRSReportDataSetAttribute(tableStr(tblSTDetailTemp))
]
public tblSTDetailTemp getLine()
{
    select * from mmkTblSTDetailTemp;
    return mmkTblSTDetailTemp;
}


* processReport Method of Data Provider Base Class
public void processReport()
{
    Query           mmkQ;
    QueryRun        mmkQR;
    InventTransferTable mmkInventTransferTable;
    ;

    mmkQ = this.parmQuery();
    mmkQR = new QueryRun(mmkQ);
    //mmkQR.prompt();
    while(mmkQR.next())
    {
        mmkInventTransferTable = mmkQR.get(tableNum(InventTransferTable));
        this.setHeader(mmkInventTransferTable);
        this.setLine(mmkInventTransferTable);
    }
}


* setHeader Method of Data Provider Base Class
private void setHeader(InventTransferTable _InventTransferTable)
{
    CompanyInfo     mmkCompanyInfo;
    VendTable       mmkVendTable;
    InventLocation  mmkInventLocation;
    ;
    mmkcompanyInfo = CompanyInfo::find();
    mmkTblSTHeaderTemp.clear();
    mmkTblSTHeaderTemp.CompanyName = mmkCompanyInfo.Name();
    mmkTblSTHeaderTemp.CompanyAddress = mmkCompanyInfo.postalAddress().Street;
    mmkTblSTHeaderTemp.CompanyPhone = mmkCompanyInfo.phone();
    mmkTblSTHeaderTemp.CompanyFax = mmkCompanyInfo.teleFax();
    mmkTblSTHeaderTemp.CompanyLogo = FormLetter::companyLogo();
    mmkTblSTHeaderTemp.TransferID = _InventTransferTable.TransferId;
    mmkTblSTHeaderTemp.ShipDate = _InventTransferTable.ShipDate;
    mmkTblSTHeaderTemp.ReceiveDate = _InventTransferTable.ReceiveDate;
    mmkTblSTHeaderTemp.InventLocationIdFrom = _InventTransferTable.InventLocationIdFrom;
    mmkInventLocation = InventLocation::find(_InventTransferTable.InventLocationIdFrom);
    mmkTblSTHeaderTemp.InventLocationNameFrom = mmkInventLocation.Name;
    mmkTblSTHeaderTemp.InventLocationIdTo = _InventTransferTable.InventLocationIdTo;
    mmkInventLocation = InventLocation::find(_InventTransferTable.InventLocationIdTo);
    mmkTblSTHeaderTemp.InventLocationNameTo = mmkInventLocation.Name;
    mmkTblSTHeaderTemp.insert();
}


* setLine Method of Data Provider Base Class
private void setLine(InventTransferTable _InventTransferTable)
{
    InventTransferLine      mmkInventTransferLine;
    InventBatch             mmkInventBatch;
    InventDim               mmkInventDim;
    InventTable             mmkInventTable;
    InventJournalTrans      inventJournalTrans;
    ;
    while select * from mmkInventTransferLine
        where mmkInventTransferLine.TransferId == _InventTransferTable.TransferId
    {
        mmkTblSTDetailTemp.ItemId = mmkInventTransferLine.ItemId;
        mmkTblSTDetailTemp.ItemName = mmkInventTransferLine.itemName();
        mmkInventDim = InventDim::find(mmkInventTransferLine.InventDimId);
        mmkTblSTDetailTemp.BatchNo = mmkInventDim.inventBatchId;
        mmkInventBatch = InventBatch::find(mmkInventDim.inventBatchId, mmkInventTransferLine.ItemId);
        mmkTblSTDetailTemp.ExpiryDate = mmkInventBatch.expDate;
        mmkTblSTDetailTemp.UnitId = mmkInventTransferLine.UnitId;
        mmkTblSTDetailTemp.QtyTransfer = mmkInventTransferLine.QtyTransfer;
        //mmkTblSTDetailTemp.Model = InventTable::find(inventJournalTrans.ItemId).itemName(inventJournalTrans.inventDim());
        mmkInventTable = InventTable::find(mmkInventTransferLine.ItemId);
        mmkTblSTDetailTemp.Model = mmkInventTable.NameAlias;
        mmkTblSTDetailTemp.insert();
    }
}

Thursday, April 9, 2015

Calculation on RDLC Report in Ms Visual Studio 2008

At report design time, you might need some calculation directly on report design otherwise you need coding first and apply result on report. Here, I will show all report developer on how to reference a cell value for calculation on another cell of a table. Now let see an example of table below:


Field 1 Field 2 Field 3 Field 4 Field 5 Field 6 Field 7
No Item ID Item Name Unit Qty Price Total
1 001 AAA Pcs 10.00 2.00 20.00
2 002 BBB Pcs 20.00 4.00 80.00
3 003 CCC Pcs 30.00 6.00 180.00
4 004 DDD Pcs 40.00 8.00 320.00
5 005 EEE Pcs 50.00 10.00 500.00
6 006 FFF Pcs 60.00 12.00 720.00
7 007 GGG Pcs 70.00 14.00 980.00
8 008 HHH Pcs 80.00 16.00 1,280.00
9 009 III Pcs 90.00 18.00 1,620.00
10 010 JJJ Pcs 100.00 20.00 2,000.00




Sub Total 7,700.00




VAT 10% 770.00




Total 8,470.00

As you see in above table you might need to apply formula in some cell such as:
Sub Total
- Basic formula:
                  Sub Total = Sum(Total)
- RDLC Report in Ms Visual Studio Formula:
                  =Sum(Fields!Total.Value)

VAT 10%
- Basic formula:
                  VAT 10% =Sub Total * 0.1
- RDLC Report in Ms Visual Studio Formula:
                  =ReportItems!Sub Total Field Name.Value * 0.1
Total
- Basic formula:
                  Total = Sub Total + VAT 10%
- RDLC Report in Ms Visual Studio Formula:
                  =ReportItems!Sub Total Field Name.Value * 1.1

Monday, April 6, 2015

Create Yes/No Message Box in X++

During your form or report development you might require response Yes/No from user in order to start any action. In this topic, i will show you on how to create a Yes/No message box to get user response in X++.
In your void main() function you need to write code as below:

1. DialogButton diagBut;
2. str strMessage = "Do you want to print Debit or Credit Note? Click Yes for Debit Note., No for Credit Note.";
3. str strTitle = "Report Selection";
4. ;
5. diagBut = Box::yesNo(strMessage, DialogButton::Yes, strTitle);
6. if(diagBut == DialogButton::No)
7. {
8. //your own code when user click on No button

9. }
10. if(diagBut == DialogButton::Yes)
11. {
12.
//your own code when user click on Yes button
13. }

Now, I will explain above code line by line for you to understand easily.
Line 1: To declare a variable with type DialogButton 
Line 2: To declare a string variable for message body
Line 3: To declare a string variable for message title
Line 4: This is just a best practice recommended by Microsoft to separate variable declaration.
Line 5: This is a combination of message body, message title and assign message button
Line 6: This is a condition study in case user response by click on No button
Line 7: Opening of If block
Line 8: In this block you need to add any code that you want system to do
Line 9: Ending of If block
Line 10: This is a condition study in case user response by click on Yes button
Line 11: Opening of If block
Line 12: In this block you need to add any code that you want system to do
Line 13: Ending of If block

Saturday, April 4, 2015

Hide and Resize Column in RDLC Report with Ms Dynamics Ax 2012

Currently RLDC report in Ms Visual Studio does not provide possibility to resize column on report via property or coding, but we still have other way to make it happen. In this topic, I will guide you step by step to get result as shown in picture 1 and picture 2 below:

Picture 1: Detail table with 3 columns Product Name, Barcode and Model.
Picture 2: Detail table without column Barcode and Model, but Product Name's column width is equal to Product Name's column width in Picture 1 plus Barcode's column width plus Model's column width.
With above picture, you can see the different column number and column size of the same report.
Now you need to see below picture in detail in order to do as shown:
In RDLC report design in Ms Visual Studio, you need to think about logic that your report will display then you need to create column to display or hide follow your criteria.
The only formula that you need to apply for each column that will show or hide is

=IIF(First(Fields!CriteriaField.Value, "dsHeader") = "ABC", false, true)

Friday, March 27, 2015

Add Running Value to Number Column

During your report development with Ms Dynamics Ax 2012, you might require to add Number Column which identify row number for your detail data in table. In this topic i will guide you step by step to do as result shown below:



In order to do this you have to know as follow:
- A column with blue rectangle is our requirement.
- Criteria column with red rectangle.
- Apply below formula to the expression of No column in Ms Visual Studio.
          =RunningValue(Fields!ItemCode.Value,count,nothing)