Monday, 17 September 2012

Sql And X++ Queries


Exists Join Sql Query :

Select CONTAINERID,* From WHSCONTAINERLINE
    Where Exists
     (Select LOADLINE,INVENTTRANSID,LOADID From WHSLOADLINE
          Where WHSLOADLINE.INVENTTRANSID ='10904263'
                  And WHSLOADLINE.RECID = WHSCONTAINERLINE.LOADLINE)
while select containerLine
    where containerLine.ContainerId == _workTable.ContainerId
        exists join loadLine
            where loadLine.InventTransId    == _workInventTrans.InventTransIdParent
                       && loadLine.RecId            == containerLine.LoadLine

Exists Operator

Exists is a logical SQL operator that helps to check the sub-query result, either True or False. It is used to check either a row is returned through this sub-query or not? If one or more rows are returned, then this operator returns True otherwise False when no rows are returned. To check how to use Exists operator in SQL, Click here.
Syntax: Select column_name(s) From table_name Where Exists (Select column_name From table_name Where condition);
Example: Let we have two tables for which we will use Exists operator:

Product Table

Product IDProduct NameUnitPriceSupplier ID
1Chang24-12 oz bottles$102
2Chais48-6 oz jars$221
3Aniseed Syrup12-550 ml$1814
4Exotic Liquid36 boxes$193
5Gumbo Box10 boxes$21.515

Supplier Table:

Supplier IDSupplier NameCityPostal Code
1Tokyo TradersLondon100
2Kelly’s HomesteadTokyo48104
3Cajun DelightNew Orleans70117
4Exotic LiquidArborEC1 4SD
Query:
Select Sr_Name From Supplier Where Exists (Select Pr_Name From Products Where Supplier_ID = Supplier.Supplier_ID And Price < 20);
Here, the SQL statement result is True, and it returns a list of products whose price is less than 20.
========================================================================

Inner Join Sql Query :


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'
   ======================================================================



print CompanyInfo::current();
=============================================================================================================================
Get days in month ex - jan ( 1- 31 will display )
static void dayOfMthExample(Args _arg)
{
   date d = today();
   date    endDate,startDate;
   int i;
   int start,end;
   int yr;
   ;
   //i = dayOfMth(d);
   yr  =   year(d);
   endDate = endmth(d);
   startDate   =   mkdate(1,mthofyr(d),yr);
   //i = dayofmth(endDate);

   start   =   dayofmth(startDate);
   end     =   dayofmth(endDate);

   //info(strfmt("Today's day of the month is %1" , int2Str(i)));
   //info(strfmt("%1 - %2",start,end));
   for(i=start; i <= end; i++)
   {
       info(strfmt("%1",i));
   }

}
 =======================================================================
 Will Display User – its roles In specific company
static void userRoleTesting(Args _args)
{
   UserInfo t2;
    SecurityRole t3;
    SecurityUserRole t1;
  // while select * from t1 join t2 where t1.user  == t2.id join t3 where  t3.RecId == t1.SecurityRole && t1.USER == curUserId()
    while select User, SecurityRole from t1
        join company from t2 where t2.id == t1.User
        join Name from t3 where t1.SecurityRole == t3.RecId &&
           t1.User == curUserId() &&
           t2.company == curext()
    {
        info(strFmt("%1,%2,%3",t1.User,t1.SecurityRole, t3.Name));
    }
}
====================================================================
How to Get string values separated by commas
 CustInvoiceJour custInvoiceJour,custinvoicejourloc;
    container con;
    int i;
    str multipleRecords;
    multipleRecords = args.parm();
    info(strFmt("%1",multipleRecords));
    con = str2con(multipleRecords);
  
    for(i=1;i<=conLen(con);i++)
    {
        custInvoiceJour.RecId = conpeek(con,i);
         info(strFmt("%1",custInvoiceJour.RecId));
        select custinvoicejourloc where custinvoicejourloc.RecId == custInvoiceJour.RecId;
         info(strFmt("%1",custinvoicejourloc.SalesId));
    }

==========================================================================================================

 
1. How  to use Print  Record statements :

while  select sum(AmountMST), custTable.AccountNum,custTable.Currency,custTable.CustGroup from custtrans join custtable  group by custTable.AccountNum  where custTrans.AccountNum  == custTable.AccountNum
{
       info(strFmt("%1,%2", custTrans.AmountMST, custTrans.AmountMST));

           // projTable = queryRun.get(tableNum(ProjTable));info(strFmt("%1, %2, %3",projTable.ProjId,projTable.Name,projTable.Type));

}

2.  How  to do print  b/w 2 tables :

CustTable custtable;
    CustTrans custtrans;
    CustBalTmp custBalTmp;
    while select AccountNum  from custtable {
      while select sum(AmountMST) from custTrans where custTrans.AccountNum  == custTable.AccountNum

            custBalTmp.AmountMST = custTrans.AmountMST;
            custBalTmp.AccountNum = custTable.AccountNum;
            custBalTmp.Currency = custTable.Currency;
            custBalTmp.CustGroup = custTable.CustGroup;
             custBalTmp.insert();

    }

3.  Use  Group by in Select statement :
while select sum(InvoiceAmountMST) from custinvoicejour  group by custInvoiceJour.OrderAccount where custInvoiceJour.invoicedate == today()
    {
        info(strFmt("%1,%2",custInvoiceJour.OrderAccount, custInvoiceJour.InvoiceAmountMST));
    }

Customer 1101 :  10.00
Customer 1102:  58.00
Customer 1104 :  20.00

while select * from custinvoicejour where custInvoiceJour.invoicedate == today()
    {
        info(strFmt("%1,%2",custInvoiceJour.SalesId, custInvoiceJour.InvoiceAmount));
    }
SO : 101271   Invoice Amount : 10.00
SO : 101273   Invoice Amount : 3.00
SO : 101274   Invoice Amount : 55.00
SO : 101276   Invoice Amount : 20.00

4. How  to call DP class from job :
static void CallDpClass(Args _args)
{MachineBreakDownSlipTmp ACWATransferhistoryTmp;
MachineBreakDownSlip_queryDP dataprovider = new MachineBreakDownSlip_queryDP();
dataProvider.processReport();
NSGFinalSettlementForToledoTmp = dataProvider.getMachineBreakDownSlipTmp();
pause
;}
 

static void CopyOfMano(Args _args)
{
    ProdRouteTrans  prodRouteTrans;
    ACWAPIPETotalItemProdPerMonthTmp  acwaPIPETotalItemProdPerMonthTmp;
    SandTestDP   dataprovider = new SandTestDP();
    ACWAPIPETotalItemProdPerMonthContract    contract    = new ACWAPIPETotalItemProdPerMonthContract();
    ;
    contract.parmFromDate(str2Date("07/05/2006",213));
    contract.parmToDate(str2Date("07/05/2006",213));
    contract.parmProdUnitId("2");
    contract.parmResource("301");
    dataProvider.parmDataContract(contract);
    dataProvider.processReport();
    acwaPIPETotalItemProdPerMonthTmp = dataProvider.getACWAPIPETotalItemProdPerMonthTmp();
}
 

5. Add  some days  to date  :
static void AddingMonthsToDOJ(Args _args){   int anInteger;   date aDate;   ;   aDate = 1\1\1998;   anInteger = 90;   aDate = aDate + anInteger;   info(strFmt("PPEndDate = %1",aDate));
}
o/p - PPEndDate = 4/1/1998


6. DateStartMth(today());  -To find  Date start of the month. 

6. calculate  age from DOB:

static void CalculateAgeFromDOB(Args _args)
{
    HcmWorker hcmWorker;
    int fromYear,toYear;
    ;
    hcmWorker = HcmWorker::find(5637144617);
    fromYear = year(hcmWorker.BirthDate);
    toYear   = year(systemDateGet());
    info(strFmt("Age = %1",toYear-fromYear));
}

7. Run  report through job :
static void RunSSRSReport(Args _args)
{
    SrsReportRun srsReportRun;
    SelectedEmployeesClass      selEmpsToSent = new SelectedEmployeesClass();
    ;
    srsReportRun = new SrsReportRun("Payslip.PrecisionDesign1");
    srsReportRun.init();
    srsReportRun.reportCaption("Payslip.PrecisionDesign1");
    srsReportRun.reportParameter('Month').value(2);
    srsReportRun.reportParameter('Year').value(2012);
    srsReportRun.showDialog(false);
    // Print to a file named ReportExample in HTML/PDF format.
    srsReportRun.printDestinationSettings().printMediumType(SRSPrintMediumType::File);
    srsReportRun.printDestinationSettings().fileFormat(SRSReportFileFormat::PDF);
    srsReportRun.printDestinationSettings().overwriteFile(true);
    srsReportRun.printDestinationSettings().fileName(@"C:\InventTruckTransactionReport.pdf");
    if( srsReportRun )
    {
        srsReportRun.executeReport();
    }
}
Run  Menu item of Report :
static void Job17(Args _args)
{
    MenuFunction CustRptMI;
    Args ArgsLoc;
    ;
    CustRptMI = new MenuFunction(menuItemOutputStr(Payslip),MenuItemType::Output);
    ArgsLoc = new Args();
    ArgsLoc.parm("Month=2");
    ArgsLoc.parm("Year=2012");
    ArgsLoc.pack();
    CustRptMI.run(ArgsLoc);
    CustRptMI.wait();
}

8 To create Sales order through code :
static void createSaleorder(Args _args)
{
SalesTable salesTable;
SalesLine salesLine;
NumberSeq NumberSeq;
CustAccount CustAccount = '3012';
ItemId itemId = '1151';
SalesFormLetter salesFormLetter;
SalesFormLetter_Invoice invoice;
;
// Order header (salesTable)
// New order number from number range produce
NumberSeq = NumberSeq::newGetNum(SalesParameters::numRefSalesId() , true);
salesTable.SalesId = NumberSeq.num();
// Initialize the order header
salesTable.initValue();
salesTable.CustAccount = CustAccount;
// Initialization of the supplier-specific ordering data
salesTable.initFromCustTable();
// Create order header
salesTable.insert();
// Order position (PurchLine)
salesLine.clear();
// Assign order number and item number
salesLine.SalesId = salesTable.SalesId ;
salesLine.ItemId = itemId;
salesLine.createLine(NoYes::Yes, // Validate
NoYes::Yes, // initFromSalesTable
NoYes::Yes, // initFromInventTable
NoYes::Yes, // calcInventQty
NoYes::Yes, // searchMarkup
NoYes::Yes); // searchPrice
// Create a new object of the SalesFormLetter_Invoice by using the construct-method in SalesFormLetter
invoice = SalesFormLetter::construct(DocumentStatus::Invoice);
// Post the invoice
invoice.update(salesTable, SystemDateGet(), SalesUpdate::All, AccountOrder::None, false,true);
}

9. To Find  Date DIFF in hours :
static void DateDiffInHours(Args _args)
{
    Activation DateTime ActivationDateTime;
    ACWAPIPEServiceRequestTable ACWAPIPEServiceRequestTableFrom,ACWAPIPEServiceRequestTableTo;
    int HourVal,TimeVal;
    str HourwithTime;
    int64 sdjfsh;
    select ACWAPIPEServiceRequestTableFrom where ACWAPIPEServiceRequestTableFrom.RecId == 5637144835;
    select ACWAPIPEServiceRequestTableTo where ACWAPIPEServiceRequestTableTo.RecId == 5637146080;
    //sdjfsh = DateTimeUtil::getDifference(ACWAPIPEServiceRequestTableTo.createdDateTime,ACWAPIPEServiceRequestTableFrom.createdDateTime)/60;
    sdjfsh = DateTimeUtil::getDifference(ACWAPIPEServiceRequestTableTo.createdDateTime,ACWAPIPEServiceRequestTableFrom.createdDateTime);
    info(strFmt("%1",sdjfsh));
    HourVal = int642int(sdjfsh/60);
    TimeVal = sdjfsh - (HourVal*60);
    HourwithTime = int2str(HourVal) + ":" + int2str(TimeVal);
    info(strFmt("%1",HourwithTime));
  //  info(strFmt("%1",DateTimeUtil::anyToDateTime(ACWAPIPEServiceRequestTableTo.createdDateTime-ACWAPIPEServiceRequestTableFrom.createdDateTime)));
 }
Find  Difference of Dates :
static void Difference of dates(Args _args)
{
    NSGEosTransactions     NSGEosTransactions;
    str date1,date2;
    date todate,fromdate;
     int date3;
    str date4;
    select NSGEosTransactions;
    date1 =date2str(NSGEosTransactions.EmplStartDate(),213,2,4,2,4,4);
    fromdate = str2date(date1,213);
    date2 = date2str(NSGEosTransactions.TransDate,213,2,4,2,4,4);
    todate   = str2date(date2,213);
    date3 =  todate - fromdate;
    print date3;
    info(strFmt(date3));
    pause;   
}
Diff of dates :
static void Diff of dates (Args _args)
{
;
print str2Date("25/12/2012",123) - str2Date("22/11/12",123) + 1;
pause;
}
Add hours to time :
static void addhoursToTime(Args _args)
{
utcDateTime t, t1;
t = DateTimeUtil::utcNow();
t1 = DateTimeutil::addMonths(t,6);
print(t1);
pause;
}
10  Delete file :
static void deleteFile(Args _args)
{
    str fileName;
    ;
    fileName = "c:\\TEMP\\000123_2_2012.pdf";
    WINAPI::deleteFile(fileName);
}

 11. To get Employee TurnOver :
static void EmplTurnover(Args _args)
{
    NSGEmployeesTurnover    NSGEmployeesTurnover;
    int                     month;
    RecId                   joinedthismonth, leftthismonth;
    StartDate               monthStart;
    EndDate                 monthEnd;
    HcmWorker               emplTable;
    NSGEoSTransactions      eosTrans;
    EmplContract            activeContract;
    NSGEmployeesTurnOver    turnoverEmployees, turnoverEmployeesDel;
    SystemSetup             parameters = SystemSetup::find();
    NSGEmployeesTurnoverTmp      employeesTurnoverTmp;
    ;
    NSGEmployeesTurnover::PopulateData();
    //Added by britto
    for(month = 1; month <= 12; month++)
    {
        //Getting the month start and end...
        monthStart      = mkdate(1, month, parameters.CurrentYear);
        monthEnd        = endMth(monthStart);
        //Getting the employees joined in that month based on joining date field...
        select count(RecId) from emplTable
            where emplTable.JoiningDate >= monthStart
                && emplTable.JoiningDate <= monthEnd;
        joinedthismonth = emplTable.RecId;
        //Getting the terminated employees within this month...
        select count(RecId) from eosTrans
            where eosTrans.TransDate >= monthStart
                && eosTrans.TransDate <= monthEnd
                && eosTrans.EosTransType != NSGEoSTransType::Clearance;
        leftthismonth = eosTrans.RecId;
        //Inserting the data...
        employeesTurnoverTmp.MonthsOfYear = month;
        employeesTurnoverTmp.JoinedThisMonth = int642int(joinedthismonth);
        employeesTurnoverTmp.LeftThisMonth = int642int(leftthismonth);
        employeesTurnoverTmp.insert();
    }
}

12.  Get  Hierarchy Structure :
static void getDimensionCombinationValues(Args _args)
{
    // DimensionAttributeValueCombination stores the combinations of dimension values
    // Any tables that uses dimension  combinations for main account and dimensions
    // Has a reference to this table’s recid
    DimensionAttributeValueCombination  dimAttrValueComb;
    //GeneralJournalAccountEntry is one such tables that refrences DimensionAttributeValueCombination
    GeneralJournalAccountEntry          gjAccEntry;
    // Class Dimension storage is used to store and manipulate the values of combination
    DimensionStorage        dimensionStorage;
    // Class DimensionStorageSegment will get specfic segments based on hierarchies
    DimensionStorageSegment segment;
    int                     segmentCount, segmentIndex;
    int                     hierarchyCount, hierarchyIndex;
    str                     segmentName, segmentDescription;
    SysDim                  segmentValue;
    ;
    //Get one record for demo purpose
    gjAccEntry = GeneralJournalAccountEntry::find(5637760032); //5637765403);
    setPrefix("Dimension values fetching");
    //Fetch the Value combination record
    dimAttrValueComb = DimensionAttributeValueCombination::find(gjAccEntry.LedgerDimension);
    setPrefix("Breakup for " + dimAttrValueComb.DisplayValue);
    // Get dimension storage
    dimensionStorage = DimensionStorage::findById(gjAccEntry.LedgerDimension);
    if (dimensionStorage == null)
    {
        throw error("@SYS83964");
    }
    // Get hierarchy count
    hierarchyCount = dimensionStorage.hierarchyCount();
    //Loop through hierarchies to get individual segments
    for(hierarchyIndex = 1; hierarchyIndex <= hierarchyCount; hierarchyIndex++)
    {
        setPrefix(strFmt("Hierarchy: %1", DimensionHierarchy::find(dimensionStorage.getHierarchyId(hierarchyIndex)).Name));
        //Get segment count for hierarchy
        segmentCount = dimensionStorage.segmentCountForHierarchy(hierarchyIndex);
        //Loop through segments and display required values
        for (segmentIndex = 1; segmentIndex <= segmentCount; segmentIndex++)
        {
            // Get segment
            segment = dimensionStorage.getSegmentForHierarchy(hierarchyIndex, segmentIndex);
            // Get the segment information
            if (segment.parmDimensionAttributeValueId() != 0)
            {
                // Get segment name
                segmentName = DimensionAttribute::find(DimensionAttributeValue::find(segment.parmDimensionAttributeValueId()).DimensionAttribute).Name;
                //Get segment value (id of the dimension)
                segmentValue        = segment.parmDisplayValue();
                //Get segment value name (Description for dimension)
                segmentDescription  = segment.getName();
                info(strFmt("%1: %2, %3", segmentName, segmentValue, segmentDescription));
            }
        }
    }
    /* http://ramdynamicsax.wordpress.com/2012/03/29/creation-and-posting-of-purchase-order-in-ms-dynamics-ax-2012/ */
}
13 Print  Dialog :

boolean myDialog(str FromChequeNum="1000", str NumOfCheque="300")
{
    Dialog dialog = new Dialog("@SYS23133");
    DialogField dialogAccountId = dialog.addField(
        extendedTypeStr(BankAccount));
    DialogField dialogFromChequeNum = dialog.addField(
        extendedTypeStr(BankChequeStartNum),
        "@SYS4083");
    DialogField dialogNumOfCheque = dialog.addField(
        extendedTypeStr(BankChequeQty),
        "@SYS14578");
    ;
    dialogAccountId.Value("456");
    dialogAccountId.Active(false);
    dialogFromChequeNum.Value(FromChequeNum);
    dialogNumOfCheque.Value(NumOfCheque);
    if (dialog.run())
    {
        FromChequeNum = dialogFromChequeNum.Value();
        NumOfCheque = dialogNumOfCheque.Value();
        return true;
    }
    return false;
}

 Join With  Where
static void JOINWhere(Args _args)
{
    EmpPayRoll EmpPayRoll;
    HcmWorker HcmWorker;
    while SELECT * FROM EmpPayRoll
    WHERE ((EmpPayRoll.EmplId == 'DNG9001'))
    && ((EmpPayRoll.Month == 8)) && ((EmpPayRoll.Year == 2012))
    JOIN * FROM HcmWorker
    where EmpPayRoll.EmplId == HcmWorker.PersonnelNumber && ((HcmWorker.NSGSponsership == 0))
    print EmpPayRoll.EmplId;
    pause;
}
15 . Send  Mail :
static void SendMail(Args _args)
{
    SysMailer pccSysMailer;
    Args argsRep = new Args();
    Args argsInv= new Args();
    Reportrun reportInv;
    ReportRun reportRep;
    // Set permissionSet,permissionSet1;
    InteropPermission PCCpermInteropPermission;
    str                                     receiverMailAddress;
    str                                     mailBody;
    str                                     mailSubject;
    str                                     CcMailAddress;
    str  FromMailAdd;
    UserInfo userinfo;
    str     smtpServer;
    int     SMTPPort;
    SysEmailParameters parameters = SysEmailParameters::find();
    ;
    select userinfo where userinfo.id == curUserId();
    FromMailAdd = sysUserInfo::find(curUserId()).Email;     //FromMailAdd = "manokaran@dynamicnetsoft.com";
    receiverMailAddress = "britto@dynamicnetsoft.com";
    PCCpermInteropPermission = new InteropPermission(InteropKind::ComInterop);
    PCCpermInteropPermission.assert();
    pccSysMailer = new Sysmailer();
    smtpServer  = parameters.SMTPRelayServerName;
    SMTPPort    = parameters.SMTPPortNumber;
    //pccSysMailer.SMTPRelayServer('10.12.2.12',25,'service.mfp@saudipcc.com','',false);
    pccSysMailer.SMTPRelayServer(smtpServer, SMTPPort,"britto@dynamicnetsoft.com",'',false);
    pccSysMailer.fromAddress("britto@dynamicnetsoft.com", "Petro Chevron Company");
    pccSysMailer.tos().appendAddress(receiverMailAddress);
    pccSysMailer.attachments().add("C:\\TEMP\\032012.txt");
    //pccSysMailer.ccs().appendAddress("ansar@dynamicnetsoft.com");
    mailBody            = "Dear Customer," +
    "\n\n Please  find attached Purchase Order Document for Document Number Purchased on "
    + "\n\n\n" +
    "Regards, \n" + userinfo.name + "\n\n\n" + "NOTE: This is electronically generated mail from Microsoft Dynamics AX. Please do not reply to this mail. ";
    pccSysMailer.subject(strfmt("Purchase Order Document"));
    pccSysMailer.htmlBody(mailBody);
    pccSysMailer.sendMail();
    info("Email has been sent to the appropriate vendor.");
}
 16

=========================================================================
static void Job36(Args _args)
{
    Timezone userTimeZone = DateTimeUtil::getUserPreferredTimeZone();
    HcmEmploymentValidFrom HcmEmploymentValidFrom;
    HcmEmploymentValidFrom = DateTimeUtil::applyTimeZoneOffset(HcmDateTimeUtil::startOfCurrentDay(), userTimeZone);
    info(strFmt("%1",DateTimeUtil::date(HcmEmploymentValidFrom)));
}

=========================================================================
Use Join and Group by :
static void Job2(Args _args)
{
    CustTable custTable;
    CustTrans custTrans;
    custgroup custGrouploc;
   
    while select * from custGrouploc
    {
       info(strFmt("CustGroup : %1",custGrouploc.CustGroup));
          
  while select AccountNum,sum(AmountMST) from custTrans join custTable group by custTrans.AccountNum
      where custTrans.AccountNum == custTable.AccountNum && custTable.CustGroup == custGrouploc.CustGroup
    {
        info(strFmt("AccountNum : %1, Amount : %2",custTrans.AccountNum , custTrans.AmountMST));
    }
    
    }
}
==============================================================
static void Job5(Args _args)
{
  BiddingTable biddingTable;
    BidTenderDocumentTable  bidTenderDocumentTable;
    BidTenderRiskFactorsTable bidTenderRiskFactorsTable;
   BiddingTenderEvaluationTable   biddingTenderEvaluationTable;  
    
while select * from biddingTable join biddingTenderEvaluationTable
where biddingTable.BidId == biddingTenderEvaluationTable.BidId
   /*&& biddingTenderEvaluationTable.OpportunityId == biddingTable.OpportunityId*/
join  bidTenderRiskFactorsTable where bidTenderRiskFactorsTable.BidId == BiddingTable.BidId
join bidTenderDocumentTable where/* bidTenderDocumentTable.OpportunityId == biddingTable.OpportunityId && */
        bidTenderDocumentTable.BidId == biddingTable.BidId && biddingTable.BidId == "JEDSFC-SAIT-000011R"
    {
    info(strFmt("%1", BiddingTable.BidId));
    }
}

select * from GENERALJOURNALACCOUNTENTRY join GENERALJOURNALENTRY on
GENERALJOURNALACCOUNTENTRY.GENERALJOURNALENTRY= GENERALJOURNALENTRY.RECID
join FISCALCALENDARPERIOD on
GENERALJOURNALENTRY.FISCALCALENDARPERIOD = FISCALCALENDARPERIOD.RECID
join  DIMENSIONATTRIBUTEVALUECOMBINATION on
GENERALJOURNALACCOUNTENTRY.LEDGERDIMENSION = DIMENSIONATTRIBUTEVALUECOMBINATION.RECID
join MAINACCOUNT on DIMENSIONATTRIBUTEVALUECOMBINATION.MAINACCOUNT = MAINACCOUNT.RECID
join  GENERALJOURNALACCOUNTENTRYDIMENSION on
GENERALJOURNALACCOUNTENTRY.RECID = GENERALJOURNALACCOUNTENTRYDIMENSION.GENERALJOURNALACCOUNTENTRY
and FISCALCALENDARPERIOD.TYPE = '1' or FISCALCALENDARPERIOD.TYPE = '0'
where GENERALJOURNALACCOUNTENTRY.POSTINGTYPE != 19 and GENERALJOURNALENTRY.LEDGER = '5637146334'


======================================================================
Job To find Mandatory Fields in a table



static void mandatoryFieldsOfATable(Args _args)
{
SysDictTable sysDictTable;
SysDictField sysDictField;
TableId tableId;
Counter counter;
;
sysDictTable = new SysDictTable(tablenum(CustTable));

for(counter = 1;counter <= sysDictTable.fieldCnt(); counter++)
{
sysDictField = new sysDictField(sysDictTable.id(), sysDictTable.fieldCnt2Id(counter));

if(sysDictField.mandatory())
info(sysDictField.name());
}
}
   ======================================================================
1. How  to write update for the record :  
ttsBegin;

select  forUpdate RecId from HcmEmploymentLeave  where HcmEmploymentLeave.PersonnelNumber  == HcmEmploymentLeaveLinesTable.PersonnelNumber
                                                      && HcmEmploymentLeave.AbsenceID        == HcmEmploymentLeaveLinesTable.AbsenceID;
HcmEmploymentLeave.NoOfDays                     = HcmEmploymentLeave.NoOfDays - totalnoofdays;

HcmEmploymentLeave.update();

ttsCommit;

======================================================================
Create Dynamic Query : ( joining two tables
static void CustTableSales1(Args _args)
{
    Query       query;
    QueryRun    queryrun;
    QueryBuildDataSource    qbds1;
    QueryBuildDataSource    qbds2;
    QueryBuildRange         qbr1;
    QueryBuildRange         qbr2;
    CustTable               custTable;
    ;
    query   = new query();
    qbds1   =   query.addDataSource(tablenum(CustTable));
    qbds1.addSortField(fieldnum(custTable,AccountNum),Sortorder::Descending);
    qbr1    = qbds1.addRange(fieldnum(custTable,custGroup));
    qbr1.value(queryvalue('10'));
    qbr2    =  qbds1.addRange(fieldnum(custTable,Blocked));
    qbr2.value(queryvalue(CustVendorBlocked::No));
    qbds2   = qbds1.addDataSource(tablenum(SalesTable));
    qbds2.relations(false);
    qbds2.joinMode(joinmode::ExistsJoin);
    qbds2.addLink(fieldnum(CustTable,AccountNum),fieldnum(SalesTable,CustAccount));
    queryrun    = new queryrun(query);
    while(queryrun.next())
    {
    custTable   = queryrun.get(tablenum(custTable));
    info(strfmt("%1 - %2",custtable.AccountNum,custTable.Name));
    }
}

Important Technical Points

1. Difference between  insert and doinsert() method in Table Methods?
 Calling DoInsert ensures that any Axapta X++ code written in insert method of the record is not executed.
 doinsert() is used for bypassing the insert method on that table.
Calling Insert always executes the Axapta X++ code written in the Insert method of the record.

Sunday, 16 September 2012

SSRS Report

What is SSRS..???
SQL Server Reporting Services (SSRS): is a server-based report generation software system. It can be used to prepare and deliver a variety of interactive and printed reports. It is administered via a web interface.
Report Server: This is the primary database that stores all the information about reports that was originally provided from the RDL files used to create and publish the reports to the ReportServer database. In addition to report properties (such as data sources) and report parameters, ReportServer also stores folder hierarchy and report execution log information.

ReportServerTempDB: This database houses cached copies of reports that you can use to increase performance for many simultaneous users. By caching reports using a nonvolatile storage mechanism, you make sure they remain available to users even if the report server is restarted.

The SSRS Report Server
          The SSRS report server plays the most important role in the SSRS model. Working in the middle, it’s responsible for every client request to render a report or to perform a management request, such as creating a subscription. You can break down the report server into several subcomponents by their function:
           Programming interface
           Authentication Layer (new to SSRS 2008)
           Report processing
           Data processing
           Report rendering
           Report scheduling and delivery




Reporting Framework Jargons

One of the most noteworthy changes which we have seen in this release of Microsoft Dynamics AX 2012 is that we’ve migrated the reporting framework from the X++ reporting framework to Microsoft SQL Server Reporting Services.
MS has introduced a robust reporting framework wrapping over the basic SSRS reporting functionality. There are many terms used in reporting framework in AX as discussed here:

Report Definition Language: RDL is an XML application primarily used with Microsoft SQL Server Reporting Services. RDL is usually written using Visual Studio. AX has Report Definition Language Contract classes that can generate and build the RDL for an AX SSRS report. This contract provides a weakly typed representation of parameters. It contains methods that can be used to get or set values. It also contains a map of parameter names and the SrsReportParameter class. The base class is SrsReportRdlDataContract.

Report Data Provider (RDP): A framework that helps in building, processing and rendering data to reports. Most of the reports require RDP classes that help in implementing business logic required to process data and provide data in readable, presentable and required formats design. The base class is SrsReportDataProvider. This class has two main sub classes, SrsReportDataProvderBase and SrsReportDataProviderPreProcess.

Report Data Contracts: The Report Data Contracts framework is used to provide and manage the parameters to an SSRS report. The report data contract contains all the other relevant instances like Report Data Provider contracts, print contracts, RDL contracts and query contracts that will be used by a report.

Printing Contracts: The framework that manages report printing (to different mediums). The base class is SrsPrintDestinationSettings. There are other supporting contracts that are used for printing, we will discuss about them in future posts.

Query Contracts: This framework manages the queries used to process report data. This framework is also responsible for providing dynamic filters (similar to our ‘Select” buttons on report dialogs that open the Query specification form to filter data on report queries).

Report Controllers: Report controllers control the report execution and dialog forms. Report controllers can be used to modify report dialogs, validate report parameters and other validations necessary before report execution. The base class is SrsReportRunController. Reports utilizing report controllers can only be used for printing data on client side. Reports controlled by controllers cannot be used in Enterprise Portals.

Report UI Builders: UI Builders are used to modify the report dialogs at run-time or to add additional parameters and write custom business logic to report dialogs. Ex: You want to perform some task based on data modified for one parameter, that affects other parameters or build a custom lookup etc (something that was provided by RunBaseReport framework class in previous versions. The base class is SrsReportDataContractUIBuilder.


http://bhushan.extreme-advice.com/chart-report-in-ssrs/ // Bar and Chart reports
http://www.mssqltips.com/sqlservertip/2483/ssrs-developer-interview-questions/
http://mfmujahidmim.wordpress.com/2012/12/18/simple-ui-builder-class/ - Builder class
==============================================================================
DP Class :
[
    SRSReportQueryAttribute(queryStr(ProjHourUtilisationQry)),
    SRSReportParameterAttribute(classStr(ProjHourUtilisationContract))
]
class ProjHourUtilisationDP extends SRSReportDataProviderbase
{
    QueryRun queryRun;
    ProjHourUtilisationTemp projHourUtilisationTemp;
    Query q;
    ProjId projid;
    ProjCategoryId categoryId;
    ProjWorkerRecId projWorkerRecId;
    FromDate fromDate;
    ToDate toDate;
    Bitmap                              companyLogo;
}
[
SRSReportDataSetAttribute(tableStr(ProjHourUtilisationTemp))
]
public ProjHourUtilisationTemp getProjHourUtilisationTemp()
{
    select * from projHourUtilisationTemp;
    return projHourUtilisationTemp;
}
private Query buildQuery(Query  _query, ProjId _projid,ProjCategoryId _CategoryId,ProjWorkerRecId _projWorkerRecId,FromDate _fromDate,ToDate _toDate)
    {
        if(_projid!="")
      _query.dataSourceTable(tablenum(ProjEmplTrans), 1).addRange(fieldnum(ProjEmplTrans,ProjId)).value(queryValue(_projid));
        if(_CategoryId!="")
        _query.dataSourceTable(tablenum(ProjEmplTrans), 1).addRange(fieldnum(ProjEmplTrans,CategoryId)).value(queryValue(_CategoryId));
        if(_projWorkerRecId !=0)
        {
        if(_projWorkerRecId)
        {
        _query.dataSourceTable(tablenum(ProjEmplTrans), 1).addRange(fieldnum(ProjEmplTrans,Worker)).value(queryValue(_projWorkerRecId));
        }
        }
        if(_fromDate && _toDate )
        {
             _query.dataSourceTable(tablenum(ProjEmplTrans), 1).addRange(fieldnum(ProjEmplTrans,TransDate)).value(queryRange(_fromDate,_toDate));
        }
        return _query;
    }
private void getReportParameters()
{
    ProjHourUtilisationContract ProjHourUtilisationContract = this.parmDataContract();
    if (ProjHourUtilisationContract)
    {
        projid=ProjHourUtilisationContract.parmProjectId();
        categoryId = ProjHourUtilisationContract.parmCategory();
        projWorkerRecId = ProjHourUtilisationContract.parmEmployeeId();
        fromDate = ProjHourUtilisationContract.parmFromDate();
        toDate    = ProjHourUtilisationContract.parmToDate();
    }
 }
[SysEntryPointAttribute(false)]
public void processReport()
{
        ProjEmplTrans projEmplTrans;
    ;
   this.getReportParameters();
    queryRun = newQueryRun(this.buildQuery(this.parmQuery(),projid,categoryId,projWorkerRecId,fromDate,toDate));
    while(queryRun.next())
    {
        projEmplTrans=queryrun.get(tableNum(ProjEmplTrans));
         this.InsertintoProjHourUtilTmp(projEmplTrans);
    }
}
public void InsertintoProjHourUtilTmp( ProjEmplTrans _projEmplTrans)
{
    HcmWorker hcmworkerlocal;
    smmActivities smmactivityloc;
    ;
    projHourUtilisationTemp.ProjId = _projEmplTrans.ProjId;
    projHourUtilisationTemp.CategoryId = _projEmplTrans.CategoryId;
    select hcmworkerlocal where hcmworkerlocal.RecId == _projEmplTrans.Worker;
    projHourUtilisationTemp.EmployeeName = hcmworkerlocal.name();
    select smmactivityloc where smmactivityloc.ActivityNumber == _projEmplTrans.ActivityNumber;
    projHourUtilisationTemp.Activity = smmactivityloc.Purpose;
    if(_projEmplTrans.LinePropertyId == "SpecialOT")
        projHourUtilisationTemp.SpecialOvertime = _projEmplTrans.Qty;
    else
        projHourUtilisationTemp.SpecialOvertime = 0.00;
    if(_projEmplTrans.LinePropertyId == "Breakdown")
        projHourUtilisationTemp.BreakDownTime = _projEmplTrans.Qty;
    else
        projHourUtilisationTemp.BreakDownTime = 0.00;
    if(_projEmplTrans.LinePropertyId == "Idle")
        projHourUtilisationTemp.IdleTime = _projEmplTrans.Qty;
    else
        projHourUtilisationTemp.IdleTime = 0.00;
    if(_projEmplTrans.LinePropertyId == "OverTime")
        projHourUtilisationTemp.Overtime = _projEmplTrans.Qty;
    else
        projHourUtilisationTemp.Overtime = 0.00;
    if(_projEmplTrans.LinePropertyId == "Normal")
        projHourUtilisationTemp.Normaltime = _projEmplTrans.Qty;
    else
        projHourUtilisationTemp.Normaltime = 0.00;
    projHourUtilisationTemp.CompanyLogo = CompanyImage::findByRecord(CompanyInfo::find()).Image;
    projHourUtilisationTemp.insert();
}
Contract  Class :
[
    DataContractAttribute,
    SysOperationContractProcessingAttribute(classStr(ProjHourUtilisationUIBuilder))
    // SysOperationContractProcessingAttribute(classstr(ProjHourUtilisationUIBuilder), SysOperationDataContractProcessingMode::CreateSeparateUIBuilderForEachContract)
    //SysOperationGroupAttribute('PrintOut', "@SYS12608", '2')
]
class ProjHourUtilisationContract implements SysOperationValidatable
{
    ProjWorkerRecId projWorkerRecId;
    ProjId projId;
    ProjCategoryId category;
    FromDate fromDate;
    ToDate toDate;
}
[
    DataMemberAttribute('Category'),
 SysOperationDisplayOrderAttribute('2')
]
public ProjCategoryId parmCategory(ProjCategoryId _ProjCategoryId = category)
{
    category = _ProjCategoryId;
    return category;
}
public boolean validate()
{
    boolean             isValid = true;
    if(!projWorkerRecId)
        throw error("Select Employee ID");*/
    return isValid;
}
UI Builder  Class :
class ProjHourUtilisationUIBuilder extends SysOperationAutomaticUIBuilder
{
    ProjHourUtilisationContract projHourUtilisationContract;
    DialogField dialogCategory;
    DialogField dialogProject;
    DialogField dialogEmployee;
    DialogField fromDate;
    DialogField toDate;
}
public void build()
{
    Dialog      dialogLocal = this.dialog();
     projHourUtilisationContract = this.dataContractObject();
    this.addDialogField(methodStr(ProjHourUtilisationContract,parmProjectId), projHourUtilisationContract);
    this.addDialogField(methodStr(ProjHourUtilisationContract,parmCategory), projHourUtilisationContract);
    this.addDialogField(methodStr(ProjHourUtilisationContract,parmEmployeeId), projHourUtilisationContract);
    this.addDialogField(methodStr(projHourUtilisationContract,parmFromDate),projHourUtilisationContract);
    this.addDialogField(methodStr(projHourUtilisationContract,parmToDate),projHourUtilisationContract);
}
public void getFromDialog()
{
    projHourUtilisationContract = this.dataContractObject();
    super();
}
public void initializeFields()
{
    projHourUtilisationContract = this.dataContractObject();
}
public void lookupCategory(FormStringControl _control)
{
    Query query = new Query();
    SysTableLookup sysTablelookup;
    sysTablelookup =SysTableLookup::newParameters(tableNum(ProjCategory),_control);
    sysTablelookup.addLookupfield(fieldNum(ProjCategory,CategoryId));
    sysTablelookup.addLookupfield(fieldnum(ProjCategory,Name));
    sysTablelookup.addLookupfield(fieldnum(ProjCategory,CategoryType));
    query.addDataSource(tableNum(ProjCategory));
    query.dataSourceTable(tableNum(ProjCategory)).addRange(fieldNum(ProjCategory, CategoryType)).value(queryValue(ProjCategoryType::Hour));
    sysTablelookup.parmQuery(query);
    sysTablelookup.performFormLookup();
}
/// <summary>
/// Override this method in order to register the dialog field methods to capture events.
/// </summary>
public void postRun()
{
    Dialog dialogLocal = this.dialog();
    super();
    // This method should be called in order to handle events on dialogs.
   dialogLocal.dialogForm().formRun().controlMethodOverload(false);
}
public void postBuild()
{
    ;
    super();
    dialogCategory = this.bindInfo().getDialogField(
                         this.dataContractObject(),
                         methodStr(ProjHourUtilisationContract,parmCategory));
    // register override method for lookup customer
    dialogCategory.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(ProjHourUtilisationUIBuilder,lookupCategory),this);
    dialogProject = this.bindInfo().getDialogField(
                         this.dataContractObject(),
                         methodStr(ProjHourUtilisationContract,parmProjectId));
    dialogEmployee = this.bindInfo().getDialogField(
                         this.dataContractObject(),
                         methodStr(ProjHourUtilisationContract,parmEmployeeId));
    fromDate = this.bindInfo().getDialogField(
                         this.dataContractObject(),
                         methodStr(ProjHourUtilisationContract,parmFromDate));
    toDate =this.bindInfo().getDialogField(
                         this.dataContractObject(),
                         methodStr(ProjHourUtilisationContract,parmToDate));
}
Controller Class :
If  you create Controller class, then you need to create output menu item, set  property Object type – class, Object – Controller class created,  Linked permission type – SSRS report, Linked Permission object – SSRS report Created,  Linked permission object type – Design name.
class ProjHourUtilisationController extends SrsReportRunController
{
  #define.ReportName('ProjHourUtilisation.PrecisionDesign1')
    ProjHourUtilisationContract projHourUtilisationContract;
    ProjTable projTable ;
}

protected void prePromptModifyContract()
{
    if (this.parmArgs()             &&
        this.parmArgs().record()    &&
        this.parmArgs().dataset() == tableNum(ProjTable))
    {
        projTable = this.parmArgs().record();
    }
    if (!projHourUtilisationContract)
    {
        projHourUtilisationContract = this.parmReportContract().parmRdpContract();
    }
    projHourUtilisationContract.parmProjectId(projTable.ProjId);
    super();
}

public void setRange(Args _args, Query _query)
{
    QueryBuildDataSource qbds;
    QueryBuildRange qbr;
    if (_args && _args.dataset())
    {
        switch(_args.dataset())
        {
            case tableNum(ProjTable) :
                projTable = _args.record();
                break;
        }
    }

    qbds = _query.dataSourceTable(tableNum(ProjTable));

    qbds.clearRanges();

    //qbr = qbds.findRange(fieldName2id(tableNum(ProjTable),fieldStr(ProjTable, ProjId)));


    if (!qbr)
    {
        qbr = qbds.addRange(fieldNum(ProjTable, ProjId));
    }
    if(ProjTable)
    {
        qbr.value(projTable.ProjId);
    }
}
public boolean showQueryValues(str parameterName)
{
    return true;
}

public static ProjHourUtilisationController construct(Args _args)
{
    ProjHourUtilisationController controller=new ProjHourUtilisationController();
    controller.parmArgs(_args);
    return controller;
}

public static void main(Args _args)
{
    ProjHourUtilisationController controller = new ProjHourUtilisationController();
    controller.parmReportName(#ReportName);
    controller.parmArgs(_args);
    controller.setRange(_args, controller.parmReportContract().parmQueryContracts().lookup(controller.getFirstQueryContractKey()));
    controller.parmShowDialog(true);
    controller.startOperation();
}

=====================================================================
To Make Child lookup - null when you change parent lookup :
 dimensionAttributeName - Parent Lookup
dimensionAttributeSubName - Child Lookup
Suppose you want the child lookup value to set null when you change the parent lookup , we need to override or add below code. 

Postbuild method :
dimensionAttributeName.registerOverrideMethod(methodstr(FormstringControl, Modified),methodstr(MMSBranchAgingUIBuilder,register),this);

 protected void register(FormStringControl dimensionAttributeNameLookUp)
{
     dimensionAttributeName.value(dimensionAttributeNameLookUp.text());
     dimensionAttributeSubName.value("");
   
}
===================================================================
If  suppose  you want to make query ranges to be disabled,  Just  create range in query and set it to hide. 

=================================================================================
Based on Condition deciding visibility of column/row :

1. To make  any row visibility , based on condition. Just  selct tht row and  right click - as to go for properties -  Click - Row Visibility, in Show or hide expression type below :

=iif(Parameters!ProjHourUtilisation_Category.Value = "",true,false)
======================================================================
To make  The value in text box to appear vertical instead of horizontal :
If  you  want  the  Text box Text, to appear in vertical ,
Go to textbox Properties , Alignment - Horizontal - Centre,Vertical - middle
======================================================================

http://msdn.microsoft.com/en-us/library/dd239338.aspx --- > Tutorials
http://technet.microsoft.com/en-us/library/bb630404.aspx ---> Types of reports
http://technet.microsoft.com/en-us/library/cc624720.aspx  --->   To have  a look on sample Precision design
Procedure  to  Develop  Objects :
<!--[if !supportLists]-->1.      <!--[endif]-->Create  a Query – CustBalQuery  with  CustTable and  CustTrans  as Data Sources  having CustTrans with Inner join under  Data Source of CustTable.

<!--[if !supportLists]-->2.      <!--[endif]-->Create  a Temporary Table – CustBalTmp
Fields – AccountNum, CustGroup, Voucher,Txt, TransType,AmountMst, Debit BalanceMST,CreditBalanceMST, Balance

<!--[if !supportLists]-->3.      <!--[endif]-->Create a Class – CustBalRDP
It contains  6  methods
[SRSReportQueryAttribute(querystr(CustBalQuery))]
class CustBalRDP extends SRSReportDataProviderBase
{
    CustBalTmp custBalTmp;
}
[SRSReportDataSetAttribute("CustBalTmp")]
public custBalTmp getCustBalTmp ()
{
    select * from custBalTmp;
    return custBalTmp;
}
private void insertCustBalTmp(CustTrans _custTrans,CustTable _custTable)
{
    custBalTmp.AccountNum = _custTable.AccountNum;
    custBalTmp.CustGroup = _custTable.CustGroup;
    custBalTmp.Voucher = _custTrans.Voucher;
    custBalTmp.Txt = _custTrans.Txt;
    custBalTmp.TransType = _custTrans.TransType;
    custBalTmp.AmountMST = _custTrans.AmountMST;
    custBalTmp.DebitBalanceMST = this.debitBalanceMST(_custTrans);
    custBalTmp.CreditBalanceMST = this.creditBalanceMST(_custTrans);
    custBalTmp.insert();
}
private AmountMST debitBalanceMST(CustTrans _custTrans)
{
    AmountMST debitBalanceMST;

    debitBalanceMST =-(_custTrans.AmountMST);

     return min(debitBalanceMST, 0);

}

private AmountMST creditBalanceMST(CustTrans _custTrans)
{
    AmountMST creditBalanceMST;

    creditBalanceMST = (_custTrans.AmountMST)-(0);

    return min(creditBalanceMST, 0);
}

[SysEntryPointAttribute(false)]
public void processReport()
{
    QueryRun queryRun;
    Query query;
    CustTable custTable;
    CustTrans custTrans;
    QueryBuildDataSource queryBuildDataSource1;
    QueryBuildDataSource queryBuildDataSource2;
    QueryBuildRange queryBuildRange;
    query = this.parmQuery();

    queryBuildDataSource1 = query.dataSourceTable(tablenum(CustTable));
    queryBuildDataSource2   = queryBuildDataSource1.addDataSource(tablenum(CustTrans));
    queryBuildDataSource2.relations(true);
    queryBuildDataSource2.joinMode(joinmode::InnerJoin);
           queryBuildDataSource2.addLink(fieldnum(CustTable,AccountNum),fieldnum(CustTrans,AccountNum));

    queryRun = new QueryRun(query);

    while(queryRun.next())
    {
    custTable = queryRun.get(tableNum(CustTable));
    custTrans = queryRun.get(tableNum(CustTrans));
    this. insertCustBalTmp(custTrans,custTable);
    }
}


<!--[if !supportLists]-->4.      <!--[endif]-->Go to VS  Create  a Report  Project  and Add Report  to it.
Name – CustBalReport 
Under  Data Set node of Report ( Set Property  DataSoureType – Report Data Provider, Query – Click Browse and Select  the RDP class you have Created.
Under  Design  node of Report  Create AutoDesign , RC Table  . Drag Fields  Voucher,Txt,  TransType, ,  Debit BalanceMST,CreditBalanceMST to Data Node . Under  Grouping Node drag -  AccountNum,  Under  Header Node drag CustGroup, Balance
Under Header  node  select  the Balance node Set  the property  Expression - =Sum(Fields!AmountMST.Value)
Deploy and  build the Report .

Controller Class :  


http://krishhdax.blogspot.in/2012/07/ax2012-create-ssrs-report-using-data.html

http://dynamicsaxgyan.wordpress.com/2012/05/11/save-ssrs-report-to-pdf-that-uses-controller-classes-dynamics-ax-2012/
 ==================================================================



Using AX Enum Provider in a Column Chart Report [AX 2012]
http://msdn.microsoft.com/en-us/library/cc554854.aspx

To define a query

1.      Open the Microsoft Dynamics AX Development Workspace.
2.      In the AOT, right-click the Queries node, and then click New Query.
3.      Right-click the node for the new query, click Rename, and then type CustTransactionData. Expand the node for the CustTransactionData query.
4.      In the AOT, right-click the Data Dictionary node, and then click Open New Window.
5.      In the new window, expand the Tables node.
6.      Locate the CustTable table and drag it onto the Data Sources node for the query.
7.      In the CustTable_1 data source node, select the Fields node, in the Properties window, set the Dynamic property to No. You will select the specific fields that will be used on the report instead of sending all data in the table. This will produce faster running reports.
8.      Locate the CustTrans table and drag it onto the Data Sources node located below the CustTable data source.
9.      In the CustTrans_1 data source node, select the Fields node, in the Properties window, set the Dynamic property to No.
10.  In the separate window, expand the node for the CustTrans table > Fields, drag the AmountMST field to the Fields node of the CustTrans_1 data source.
11.  Right-click the Relations node for the CustTrans_1 data source, and then click New Relation.
12.  Select the node for the relation and verify the following default values in the Properties window.
Property
Value
JoinDataSource CustTable_1
Field AccountNum
Related Field AccountNum
13.  In the AOT, right-click the Ranges node for the CustTrans_1 data source, and then click New Range.
14.  Select the node for the range, and in the Properties window, select the TransType field from the drop-down menu for Field.
NoteNote
A report parameter is automatically generated for the range when the query is used in a report dataset and the Dynamic Filters property for the report dataset is set to False.
15.  The TransType field is an enum type. When you define the report, you must know the value of the EnumType property when you define the AX Enum Provider data source. To find the property value, in the AOT, click Data Dictionary > Tables > CustTrans > Fields > TransType. In the Properties window, notice that the EnumType property is set to LedgerTransType.
16.  Locate the CustGroup table and drag it onto the Data Sources node located below the CustTrans_1 data source.
17.  In the CustGroup_1 data source node, select the Fields node, in the Properties window, set the Dynamic property to No.
18.  In the separate window, expand the CustGroup table > Fields node. Drag the Name field to the Fields node of the CustGroup_1 data source.
19.  Right-click the Relations node for the CustGroup_1 data source, and then click New Relation.
20.  Select the node for the relation and specify the following values in the Properties window.
Property
Value
JoinDataSource CustTable_1
Field CustGroup
Related Field CustGroup
21.  Save the query.

Next, you will create a reporting project in Microsoft Visual Studio. In this walkthrough, you will use the Report Model template.

To create a reporting project

1.      Open Microsoft Visual Studio.
2.      On the File menu, point to New, and then click Project. The New Project dialog box is displayed.
3.      In the Installed Templates pane, click Microsoft Dynamics AX node, and in the Templates pane, click Report Model.
4.      In the Name box, type SampleChartReport, and in the Location box, type a location.
5.      Click OK.

Before you create a chart, you must decide what type of chart to create. There are two types of charts: XY charts and pie or doughnut charts. An XY chart is a column, line, or bar chart. During design, you can switch between related chart types. For example, you can create a column chart and then later change it to a bar or line chart. In this walkthrough, you will begin by creating a column chart. Later in the walkthrough, you will change the design so that the data displays in a bar chart and then in a line chart. You will use the predefined layout and style templates provided by the Visual Studio tools for Microsoft Dynamics AX. You will use the template ColumnChartStyleTemplate to provide the layout for the column chart report. For the following example, you will create two datasets. The first will be bound to the CustTransactionsData query and the second will be used to display the transaction type that is an Enum type.

To create a report that has a column chart

1.      In Solution Explorer, right-click the SampleChartReport project, point to Add, and then click Report.
2.      In Model Editor, right-click the Report1 node, and then click Rename.
3.      Type ColumnChartReport as the name.
4.      Expand the ColumnChartReport node if it is not already expanded.
5.      Right-click the Datasets node, and then click Add Dataset.
6.      Select the node for the dataset.
7.      In the Properties window, specify the following values.
Property
Value
Data Source Dynamics AX
Data Source Type Query
Default Layout ColumnChart
Dynamic Filters False
Name CustomerTransactions
Query
1.      Click the ellipsis button (…). A dialog box displays where you can select a query that is defined in the AOT and identify the fields that you want to use.
2.      Select the CustTransactionData query and then click Next.
3.      Expand the CustTrans_1 node and select the All Fields check box. This will select the AmountMST field.
4.      Expand the CustGroup_1 node and select the All Fields check box. This will select the Name field.
5.      Click OK.
8.      In Model Editor, expand the node for CustomerTransactions > Fields.
9.      Select the AmountMST field, and in the Properties window, set the Aggregate Function property to Sum and the Format String property to Currency.
10.  Right-click the Datasets node, and then click Add Dataset. You will create a dataset with an AX Enum Provider data source for the TransType enum field. This will let you filter the report to show specific transaction types.
11.  Select the node for the dataset.
12.  In the Properties window, specify the following values.
Property
Value
Data Source Dynamics AX
Data Source Type AX Enum Provider
Name LedgerTransTypeEnum
Query LedgerTransType
13.  Drag the CustomerTransactions node onto the Designs node for the report. An auto design called AutoDesign1 is created for the report.
14.  Expand the AutoDesign1 node, expand the node for the chart data region, and then expand the Data node.
15.  Drag the Name field to the Categories node.
NoteNote
The AmountMST field should be the only field that remains below the Data node.

Next, you will configure a parameter for the report. The report contains a parameter for the TransType field because a range based on this field was added to the query and you set the Dynamic Filters property for the dataset to False.
The TransType field is an Enum type. You will update the Values property on the CustomerTransactions_TransType report parameter to reference the AX Enum Provider dataset that you created. By using the AX Enum Provider, the enum parameter can be accessed from Enterprise Portal and also the Microsoft Dynamics AX client.
The following procedure explains how to configure a report parameter.

To configure a report parameter

1.      In Model Editor, expand the Parameters node for the report, and then select the CustomerTransactions_TransType parameter.
2.      In the Properties window, set the following property values:
Property
Value
Allow Blank False
Data Type Integer
Values Click the ellipsis button (...) to open the Select Values dialog box. Set the following values:
o    Dataset: LedgerTransTypeEnum
o    Value field: Value
o    Label field: Label
Make sure that From dataset is marked, and then click OK.

Next, you will specify layout and style templates for the report. A layout template defines the general layout and style settings for a report. A style template contains the layout and style settings for a data region that displays in the body of a report. You will apply the predefined templates that are provided by the Microsoft Dynamics AX framework. These templates are the standard templates for Microsoft Dynamics AX reports. The following procedure explains how to apply layout and style templates to the report.

To apply layout and style templates

1.      In Model Editor, select the AutoDesign1 node.
2.      In the Properties window, set the LayoutTemplate property to ReportLayoutStyleTemplate. Also, type Customer transactions for the Title property.
3.      In Model Editor, expand the AutoDesign1 node, and then select the node for the chart data region.
4.      In the Properties window, set the Style Template property to ColumnChartStyleTemplate.
5.      Delete the default text for the Title property so that it does not display a title for the data region.
6.      Set the Value Axis Data Scale Minimum property to 5. This will set the starting value on the axis of your report to 5 instead of 0. This is one of many properties that will define the look of your report.
7.      In Model Editor, right-click the AutoDesign1 node, and then click Preview to view the report. Specify a transaction type for the parameter, like Customer, and then click the Report tab to view the report.
8.      Close the Preview window.

During design, you can switch between several related chart types. First, you will switch from a column chart to a bar chart. After that, you will switch it to a line chart. The following procedures explain how to switch between chart types.

To switch the format to a bar chart

1.      In Model Editor, select the node for the CustomerTransactionsXYChart chart data region.
2.      In the Properties window, set the Chart Type property to Bar.
3.      In Model Editor, right-click the AutoDesign1 node, and then click Preview to view the report. Specify a transaction type for the parameter, like Customer, and then click the Report tab to view the report.

To switch the format to a line chart

1.      In Model Editor, select the node for the CustomerTransactionsXYChart chart data region.
2.      In the Properties window, set the Chart Type property to Line.
3.      In Model Editor, right-click the AutoDesign1 node, and then click Preview to view the report. Specify a transaction type for the parameter, like Customer, and then click the Report tab to view the report.