Search This Blog

Tuesday, July 3, 2012

AX2012 Create SSRS Report using Data Provides Classes

Create the SSRS Report in AX2012 using Report Data Provider (RDP) functionality.

RDP implments the standard MVC(Model View Controller) design pattern.
In this post I am building one report which is used in the production packing list report for production module.

What is MVC?

  • Model-view-controller (MVC) is a pattern used to isolate business logic from the user interface.
  • Model: Responsible for retrieving data and for business logic, this can included queries, data methods, or other classes that are designed to retrieve data.
  • View: Responsible for the User Interface, this can also be thought of as the design for the report.
  • Controller: Orchestrates the flow between Model and View



For this Report I am creating the Query,Contract,Controller,DataProvider classes in below.
In this I used lot of my custom fields that we created and used in the functionality

I am extending this functionality with adding builder class to the contract and adding the logic to lookup the data for the contract parmmethods.

for this I am writing the class which extending the SysOperationAutomaticUIBuilder.


TmpTable- ProdPackingSlipDetailsTmp
Query Name-ProdPackList
Contract class-ProdPacklistContract
Controller class-ProdPackListController Extends SRSReportRunController
Data ProvideClass-ProdPacklistDP Extends SRSReportDataProvidePreProcess
SSRS Report-ProdPackList

Starting with Query-Build the Query as the following data sources with the fields and relations.



Create the TMP table as below fields and properties of the table




define Properties of the table mainly createTransactionID=Yes
















Create the Contract  Class first,
This class is used to create parm methods for the reports, So if you have any parameters that you want to pass to report then create parm methods for those as datamembers.

for ex.-

[    DataMemberAttribute('UseQuantity')]
public ProdBOMJournalQty parmUseQuantity(ProdBOMJournalQty _useQuantity = useQuantity)
{
    useQuantity = _useQuantity;
    return useQuantity;
}


In my report I am using Query and adding two parm fields.
I am adding the contract processing through my builder with the following attribute of my contract class.

[DataContractAttribute,
SysOperationContractProcessingAttribute(classstr(ProdPackListUIBuilder)) ]
public class ProdPacklistContract
{
SalesId salesId;
LineNum lineNum
}

[    DataMemberAttribute('SalesId')]
public SalesId parmSalesId(SalesId _salesId=salesId)
{
salesId=_salesId;
return salesId;
}

[ DataMemberAttribute('LineNum')]
public LineNum parmLineNum(LineNum _lineNum=LineNum)
{
 lineNum=_lineNum;
return lineNum;
}

Create Controller class which extends SrsReportRunController

/// <summary>
///    The <c>ProdPackListController</c> class is the controller class for <c>ProdPackList</c> SSRS report.
/// </summary>
public class ProdPackListController extends SrsReportRunController
{
}
Create the Main method where you have to define the reportname and design and this was the method which will calls the report to exectue...starting point of the report.

public static void main(Args _args)
{
    SrsReportRunController    controller = new  ProdPackListController  ();
    controller.parmReportName("ProdPackList.Report");
    controller.parmArgs(_args);
    controller.startOperation();
}



Override the method preRunModifyContract method


protected void preRunModifyContract()
{
    GNProdPacklistContract    contract;
    contract = this.parmReportContract().parmRdpContract() as GNProdPacklistContract;
}


if you want to handle the record count and no records then you can over ride this method and you can handle the no records warnings.
protected container preRunValidate()

{
    // This report is only containing dynamic filters and via testing it's been determined
    // that on warm box it performs under 10 seconds with a 500 records and under 10 minutes
    // with 50000 records. The rest of the contract parameters just define layout and UI, so
    // no additional filtering on those needs to be done in this method.
    // The granularity of the query is determined by the join of ProdJournalBOM and ProdBOM tables.
    #define.ErrorLimit(50000)
    #define.WarningLimit(500)

    container               validateResult;
    Query                   firstQuery = this.getFirstQuery();
    int                     rowCount = QueryRun::getQueryRowCount(firstQuery, #ErrorLimit + 1);

    if (rowCount > #ErrorLimit)
    {
        validateResult = [SrsReportPreRunState::Error];
    }
    else if (rowCount > #WarningLimit)
    {
        validateResult = [SrsReportPreRunState::Warning];
    }
    else if(rowCount <=0)
    {
       // validateResult = [SrsReportPreRunState::Error];
         throw error("No records available for the Selected criteria");
    }
    else
    {
        validateResult = super();
    }

    return validateResult;
}


if you want to pass the values for the report before promting to user for input you can override this method
prePromptModifyContract

In my case I am overriding to pass the value and ranges for my query before showing the dialog to user.


/// <summary>
///    Sets query ranges based on the caller.
/// </summary>
/// <exception cref="M:Exception::Error">
///    The method is called from a invalid path.
/// </exception>
protected void prePromptModifyContract()
{
    QueryBuildRange         queryBuildRangeSerial;
    QueryBuildRange         queryBuildRangeProd,qbrTransStatus;

    QueryBuildDataSource    queryBuildDataSource,queryBuildDataSource1,queryBuildDataSource2;
    ProdTable               localProdTable;
    Query                   query;
    // get the report query
    query                   = this.parmReportContract().parmQueryContracts().lookup(this.getFirstQueryContractKey());

    queryBuildDataSource    = SysQuery::findOrCreateDataSource(query, tableNum(ProdTable));
    queryBuildDataSource1   = SysQuery::findOrCreateDataSource(query, tableNum(InventDim));
    queryBuildDataSource2   = SysQuery::findOrCreateDataSource(query, tableNum(InventTrans));

    queryBuildRangeProd     = SysQuery::findOrCreateRange(queryBuildDataSource, fieldNum(ProdTable,ProdId));
    queryBuildRangeSerial   = SysQuery::findOrCreateRange(queryBuildDataSource1, fieldNum(InventDim,inventSerialId));
    qbrTransStatus          = SysQuery::findOrCreateRange(queryBuildDataSource2, fieldNum(InventTrans,StatusReceipt));
    qbrTransStatus.value(queryValue(StatusReceipt::Received));

    if (this.parmArgs().dataset() ==  tableNum(ProdTable))
    {
        localProdTable = this.parmArgs().record();
        queryBuildRangeProd.value(queryValue(localProdTable.ProdId));
        this.parmShowDialog(true);
    }
    else if ((this.parmArgs().menuItemName() == menuitemOutputStr(ProdPacklist)) && (this.parmArgs().dataset() ==0))
    {
        this.parmShowDialog(true);
    }
    else
    {
        throw error(strFmt("Packing list can only printed from Production",funcName()));
    }

}


Create DataProvider class which extends SrsReportDataProviderPreProcess
In My report I am using the Barcode setup functionality for printing the serial numbers aswell.


[
    SRSReportQueryAttribute(queryStr(ProdPackList)),
    SRSReportParameterAttribute(classStr(ProdPacklistContract))
]
class ProdPacklistDP extends SrsReportDataProviderPreProcess
{

    boolean                     showQuery;

    boolean                     firstPage;
    ProdTable                   prodTable;
    ProdId                      prodId;

    CompanyInfo                 companyInfo;

    ProdBOM                     prodBOM;
    InventDim                   inventDim;

   ProdPackingSlipDetailsTmp prodPackingSlipDetailsTmp;
    BarcodeSetup                barCodeSetup;
    BarcodeSetupId  barcodeSetupId;
    Barcode         barcode;
}


Create the method which return the tmp table object

[
    SRSReportDataSetAttribute(tableStr('ProdPackingSlipDetailsTmp'))
]
public ProdPackingSlipDetailsTmp getProdPacklistDetailsTmp()
{
    select prodPackingSlipDetailsTmp;
    return prodPackingSlipDetailsTmp;
}

override the method ProcessReport where you will write the business logic to fill into thetmp table

/// <summary>
///    Processes the report business logic.
/// </summary>
/// <remarks>
///    Calls the sub methods to insert data into the temporary table.
/// </remarks>
[SysEntryPointAttribute(false)]
public void processReport()
{
    QueryRun                queryRun;
     ProdPacklistContract contract       = this.parmDataContract() as  ProdPacklistContract ;
    // Set the userconnection to use on table.
    // This is required to ensure that createdTransactionId of inserted record is different than default
           transaction.
    prodPackingSlipDetailsTmp.setConnection(this.parmUserConnection());
    this.init();
    this.setupBarcode();
    queryRun                        = new QueryRun(this.parmQuery());
    while (queryRun.next())
    {
        prodTable       = queryRun.get(tableNum(ProdTable));
        inventDim       = queryRun.get(tableNum(InventDim));
        prodId          = prodTable.ProdId;
        if(prodTable.InventRefType==InventRefType::Sales)
        {
           this.insertHeader();
           this.insertDetails(prodId,inventDim.inventSerialId);
        }
    }
}


private void init()
{
    companyInfo = CompanyInfo::find();
    firstPage   = true;
}





//BP Deviation documented
protected BarCodeString barcode(str _SerialNumber)
{
    str jobId = strupr(_SerialNumber);

    if (barcodeSetup.validateBarcode(jobId))
    {
        barcode.string(true, jobId);
        barcode.encode();
    }
    else
    {
        throw(error(strfmt("@SYS41409", barcode.barcodeType(), jobId)));
    }
    return barcode.barcodeStr();
}


/// <summary>
/// Initialize barcode settings.
/// </summary>
protected void setupBarcode()
{
    barcodeSetupId = JmgParameters::find().getBarcodeSetupId();
    barcodeSetup = BarcodeSetup::find(barcodeSetupId);
    barcode = barcodeSetup.barcode();
}

// assigns the data into header information first

private void insertHeader()
{
    prodPackingSlipDetailsTmp.clear();
    prodPackingSlipDetailsTmp.initValue();
    prodPackingSlipDetailsTmp.SalesId=prodTable.InventRefId;
    prodPackingSlipDetailsTmp.SerialNumber=inventDim.inventSerialId;


    prodPackingSlipDetailsTmp.ProdItemId                = prodTable.ItemId;
    prodPackingSlipDetailsTmp.Description               = prodTable.Name;
    prodPackingSlipDetailsTmp.Customer                  = SalesTable::find(prodPackingSlipDetailsTmp.SalesId).CustAccount;


    prodPackingSlipDetailsTmp.initValue();
    prodPackingSlipDetailsTmp.barcodeSetupId=barCodeSetup.barcodeSetupId;
    prodPackingSlipDetailsTmp.barcodeType=barCodeSetup.barcodeType;
    prodPackingSlipDetailsTmp.fontName=barCodeSetup.fontName;
    prodPackingSlipDetailsTmp.fontSize=barCodeSetup.fontSize;
    prodPackingSlipDetailsTmp.maximumLength=barCodeSetup.maximumLength;
    prodPackingSlipDetailsTmp.minimumLength=barCodeSetup.minimumLength;
    prodPackingSlipDetailsTmp.SerialNumberBarCode=this.barcode(inventDim.inventSerialId);
}


private void insertDetails(ProdId _prodId,InventSerialId _inventSerialId)
{
    SMAServiceObjectTable smaServiceObjectTable;
    SMAServiceBOMTable    smaServiceBOMTable;
    ProdBOM               prodBOMTable;

    while select prodBOMTable order by InventTransId asc
        where prodBOMTable.ProdId==_prodId
    {
        if(InventTable::Find(prodBOMTable.ItemId).PrintItemProduction)
        {
            prodPackingSlipDetailsTmp.ItemId=prodBOMTable.ItemId;
            prodPackingSlipDetailsTmp.Qty=prodBOMTable.BOMQty;
            prodPackingSlipDetailsTmp.Name=prodBOMTable.itemName();
            if(prodBOMTable.SerialnoControlled())
            {
                select TemplateBOMId,ServiceObjectId from smaServiceObjectTable
                    where smaServiceObjectTable.InventSerialId==_inventSerialId
                    && smaServiceObjectTable.ReferenceId==_prodId
                    && smaServiceObjectTable.ReferenceCategory==InventTransType::Production
                join InventSerialId from smaServiceBOMTable where
                    smaServiceBOMTable.ItemId==prodBOMTable.ItemId
                    && smaServiceBOMTable.ObjectId==smaServiceObjectTable.ServiceObjectId
                    && smaServiceBOMTable.ServiceBOMId==smaServiceObjectTable.TemplateBOMId;

                prodPackingSlipDetailsTmp.SerialNo=smaServiceBOMTable.InventSerialId;
            }
            prodPackingSlipDetailsTmp.SalesFormNotes=FormLetterRemarks::find(companyInfo.LanguageId,FormTextType::ProductionPackingList).Txt;
            prodPackingSlipDetailsTmp.insert();
            prodPackingSlipDetailsTmp.SerialNo="";
        }
    }
}

Builder class

public class ProdPackListUIBuilder extends SysOperationAutomaticUIBuilder
        {
            DialogField dialogSalesId;
            DialogField dialogSalesLine;
            SalesId  salesId;
            LineNum  lineNum;
            ProdPacklistContract prodPacklistContract;
            ProdPackListController packListcontroller;
            QueryRun queryRun;
            Query baseQuery;
            ProdTable prodTable;
        }
       public void build()
        {
            FormBuildGroupControl grp;
       
            Dialog      dialogLocal = this.dialog();
            ;
            prodPacklistContract = this.dataContractObject();
            if(this.validateCaller())
            {
                dialogLocal.addGroup("Sales");
                this.addDialogField(methodStr(ProdPacklistContract,parmSalesId), prodPacklistContract);
                this.addDialogField(methodStr(ProdPacklistContract,parmSalesLine), prodPacklistContract);
            }
       }

        public SysOperationController controller()
        {
            SysOperationController ret;
            ret = super();
            packListcontroller=ret;
            return ret;
        }

        private str getFirstQuery()
        {
              // this will just return the first contract key in the Map
            Map queryContracts =packListcontroller.parmReportContract().parmQueryContracts();
            MapEnumerator mapEnum;
            str firstQueryKey;
            if(queryContracts)
            {
                mapEnum = queryContracts.getEnumerator();
                if(mapEnum.moveNext())
                {
                    firstQueryKey = mapEnum.currentKey();
                }
            }
            return firstQueryKey;
        }
        public void getFromDialog()
        {
            prodPacklistContract = this.dataContractObject();
            if(this.validateCaller())
            {
                salesId=dialogSalesId.value();
                LineNum=dialogSalesLine.value();
                this.validateData(salesId,LineNum);
            }
            super();
        }

        public void initializeFields()
        {
            prodPacklistContract = this.dataContractObject();
        }

        private void initquery()
        {
baseQuery=packListcontroller.parmReportContract().parmQueryContracts().lookup(this.getFirstQuery());
            QueryRun=new QueryRun(baseQuery);
            while (queryRun.next())
            {
                prodTable=queryRun.get(tableNum(ProdTable));
                if(prodTable)
                    break;
            }
        }
        public void lookupSalesId(FormStringControl _control)
        {
            Query query = new Query();
            SysTableLookup sysTablelookup;
            sysTablelookup =SysTableLookup::newParameters(tableNum(SalesTable),_control);
            sysTablelookup.addLookupfield(fieldNum(SalesTable,SalesId));
            sysTablelookup.addLookupfield(fieldnum(SalesTable,CustAccount));
            sysTablelookup.addLookupMethod(tableMethodStr(SalesTable,customerName));
       
            query.addDataSource(tableNum(SalesTable));
            if(ProdTable.InventRefType==InventRefType::Sales)
            {
                query.dataSourceTable(tableNum(SalesTable)).addRange(fieldNum(SalesTable, SalesId)).value(queryValue(ProdTable.InventRefId));
            }
            sysTablelookup.parmQuery(query);
            sysTablelookup.performFormLookup();
        }
        public void lookupSalesLine(FormStringControl _control)
        {
            Query query = new Query();
            SysTableLookup sysTablelookup;
            sysTablelookup =SysTableLookup::newParameters(tableNum(SalesLine),_control);
            sysTablelookup.addLookupfield(fieldnum(SalesLine,LineNum));
            sysTablelookup.addLookupfield(fieldnum(SalesLine,Itemid));
            sysTablelookup.addLookupfield(fieldNum(SalesLine,SalesId));
            query.addDataSource(tableNum(SalesLine));
            query.dataSourceTable(tableNum(SalesLine)).addRange(fieldNum(SalesLine, SalesId)).value(dialogSalesId.value());
            query.dataSourceTable(tableNum(SalesLine)).addRange(fieldNum(SalesLine, ItemId)).value(queryValue(prodTable.ItemId));
            if(prodTable.InventRefType==InventRefType::Sales)
            {
                query.dataSourceTable(tableNum(SalesLine)).addRange(fieldNum(SalesLine, InventtransId)).value(queryValue(prodTable.InventRefTransId));
            }
       
            sysTablelookup.parmQuery(query);
            sysTablelookup.performFormLookup();
        }

//Override the postbuild function to bind the lookups for the fields.
        public void postBuild()
        {
            super();
            if(this.validateCaller())
            {
                prodPacklistContract=this.dataContractObject();
                this.initquery();
                // From binding info, get the dialog field for racecode attribute and add button
                dialogSalesId = this.bindInfo().getDialogField(
                                     this.dataContractObject(),
                                     methodStr(ProdPacklistContract,parmSalesId));
                if (dialogSalesId)
                {
                    dialogSalesId.lookupButton(2);
                }
                dialogSalesId.value(" ");
       
                // register override method for lookup cust Group
                dialogSalesId.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(ProdPackListUIBuilder, lookupSalesId), this);
                // register override method for modified
                dialogSalesId.registerOverrideMethod(methodStr(FormStringControl, modified), methodStr(ProdPackListUIBuilder, SalesIdModified), this);
       
                //binding info for customer drop down
                dialogSalesLine = this.bindInfo().getDialogField(this.dataContractObject(),
                                     methodStr(ProdPacklistContract,parmSalesLine));
                dialogSalesLine.value(" ");
                // register override method for lookup customer
                dialogSalesLine.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(ProdPackListUIBuilder, lookupSalesLine), this);
       
                if (dialogSalesLine)
                {
                    dialogSalesLine.lookupButton(2);
                }
                if(ProdTable.InventRefType==InventRefType::Sales)
                {
                    dialogSalesId.value(prodTable.InventRefId);
                    dialogSalesLine.value(SalesLine::findInventTransId(prodTable.InventRefTransId).LineNum);
                    prodPacklistContract.parmSalesId(prodTable.InventRefId);
                    prodPacklistContract.parmSalesLine(SalesLine::findInventTransId(prodTable.InventRefTransId).LineNum);
                    dialogSalesId.enabled(false);
                    dialogSalesLine.enabled(false);
                }
                if(prodTable.RecId==0)
                {
                    throw error(strFmt("please select valid production order"));
                }
            }
            else
            {
                    prodPacklistContract.parmSalesId("");
           }
        }
// if the salesId is modified we have to load the sales lines 
        public boolean SalesIdModified(FormStringControl _control)
        {
            dialogSalesId.value(_control.valueStr());
            dialogSalesLine.value('');
            return true;
        }
        private boolean validateCaller()
        {
            if((packListcontroller.parmArgs().menuItemName() == menuitemOutputStr(ProdPacklist)) && (packListcontroller.parmArgs().dataset() ==0))
                return false;
            else
                return true;
        }

        private void validateData(SalesId _salesId,LineNum _lineNum)
        {
            boolean ret=true;
            SalesLine salesLine;
            if(this.validateCaller())
            {
                    if(_salesId=="")
                        throw error(strFmt("this production is not linked to sales %1",prodTable.ProdId));
       
                    if(_lineNum==0)
                        throw error(strFmt("this production is not linked to sales %1 ",_salesId,prodTable.ProdId));
                    if(ret)
                    {
                        salesLine= SalesLine::find(_salesId,_lineNum);
                        if(salesLine && salesline.ItemId != prodTable.ItemId)
                        {
                            throw error(strFmt("this production is not linked to sales %1 ,%2",salesLine.ItemId,prodTable.ItemId));
                        }
                    }
            }
        }
     
 This was the new functionality for the adding the lookups for the fields using builder class.



After creation of all the classes above mentioned then we have to create the report,
Open .netDevelopment enviorment and create project and select Microsoft Dynamics AX from the Left pane and select the ReportModel Project from the list of project and give your project name and click ok.

















select the project and right click and click add and select report.














It will create the new report as follow.Right click on report and select properties and give the name as ProdPackList.













Select DataSets and right click and click AddDataset and provide the DatasetName and select the dataset that you created and right click and properties.








click on Query it will opens the dialog with the DataProvider classes,in that select the DataProvider class that we built and click next. It will opens the fields selection window where we will select the list of fields that required to show in the report
















based on your requirements you can select or deselect the fields and click on. Now the dataset with the fields are ready for the report.
Now you can drag and drop that dataset on to the designs node, It will generate auomatic design for those fields.
If you want to design your own format then create new precision Design by right click on the designnode and  add precisionDesign and change that design name as we mentioned in the controller class main method(Report).

I Created the Precision design as follows.









This is how my report looks like above.






68 comments:

  1. Hi,
    I have designed a report.Before printing the report, i need to select the values using a query.
    i followed the way you created prePromptModifyContract().
    But i am not able to find those query range values on dialog.
    Am i missing something?
    Can you please tell me if i need to do anything more?

    ReplyDelete
    Replies
    1. Hi Jhansi,
      Did you define the Member attribute of query on the class declaration of dp class. and your dpclass should be extend from srsreportdataprovidepreprocess class then only you can debug into the dp class...

      and please keep the debugger in the contoller Main method of staroperation call...go into those methods...and it will call..prepromptmodifycontract...and check whether its hitting your method or not.

      Regards,
      krishna.

      Delete
    2. Hey all,

      I am sending out a note to those of you that have taken advantage of my Blog(http://krishhdax.blogspot.com),through skype,Chat..etc, that I have been making over the past couple of years, asking for a favor.

      It is that time of year 2013, and we are now announcing the nomination process for The Most Influential People in Microsoft Dynamics for 2013. I would really like to make the list this year, and I hope that I have influenced you all in my own little way.

      If you feel inclined, you can nominate me by sending an email with a persuasive explanation for the nomination to top100@dynamicsworld.co.uk or through Twitter using the #dwtop100 tag.

      You can find more on the nomination process can be found here: http://www.dynamicsworld.co.uk/top100nominationprocess/

      Thanks in advance.

      Krishna Reddy Modugula | CGI |AX Technical Manager | Microsoft Solutions
      Lautrupvang 10, DK-2750 Ballerup | Denmark
      Phone: +45 44 78 40 00 | Mobile: +45 41 88 23 35
      www.cgi.com | www.cgi.dk
      http://krishhdax.blogspot.com
      http://www.linkedin.com/in/krishhprofile

      Delete
  2. Hi Krishna,
    I did the same steps as you mention for my custom packing slip. However, when I run the report, it shows only fixed layout but not the data querried in AX db. I had debugged already, it went to "process report" method and completed inserted data into details table, but after that, the data weren't shown in the report.
    Do you have any suggestion for this issue?
    Thank you very much.
    Jane

    ReplyDelete
    Replies
    1. Hi Hong,
      in your Report design you have build the dataset with this DP class, then in your report design table you have define the datasource for this Dataset and added the fields from this dataset right?-

      Then you override the method preRunValidate and keep the debugger and see how many records its returning... from the query.

      and your main method of the controller should have your reportName.Design

      Still if not working please send me the whole project...I will check it.

      Regards,
      krishna
      krishna.dynamics@gmail.com

      Delete
    2. Hi Krishna,
      Problem sold. Just a silly mistake.
      Thank for your help. I've learn a lot from your reply. I'll visit your blog frequently. Look forward to read new post.

      Regards,
      Trinh

      Delete
    3. Hey all,

      I am sending out a note to those of you that have taken advantage of my Blog(http://krishhdax.blogspot.com),through skype,Chat..etc, that I have been making over the past couple of years, asking for a favor.

      It is that time of year 2013, and we are now announcing the nomination process for The Most Influential People in Microsoft Dynamics for 2013. I would really like to make the list this year, and I hope that I have influenced you all in my own little way.

      If you feel inclined, you can nominate me by sending an email with a persuasive explanation for the nomination to top100@dynamicsworld.co.uk or through Twitter using the #dwtop100 tag.

      You can find more on the nomination process can be found here: http://www.dynamicsworld.co.uk/top100nominationprocess/

      Thanks in advance.

      Krishna Reddy Modugula | CGI |AX Technical Manager | Microsoft Solutions
      Lautrupvang 10, DK-2750 Ballerup | Denmark
      Phone: +45 44 78 40 00 | Mobile: +45 41 88 23 35
      www.cgi.com | www.cgi.dk
      http://krishhdax.blogspot.com
      http://www.linkedin.com/in/krishhprofile

      Delete
  3. Hi Krishna,

    I have designed a report using RDP.
    In fact, the report is a label printing with specific page size.
    However, everytime when I change the page width bigger than page height, the orientation is set to Landscape.
    This cause the label being printed side ways.
    I have look through and still no solution yet.
    Have you encounter this issue? Is there a ways to set the orientation using RDP class?

    Thanks so much.
    Vincent
    crazysee@gmail.com

    ReplyDelete
    Replies
    1. Hi Vincent,
      You can set anything related to page width and heights for the report,normally when you design the report you can go to the report properties and select the page type-A4,letter,tabloid etc based on your page type selection it will have its own sizes bye protrait and landscape, may be in your case your report is expanding more width than required portrait width, you can reduce the report deisgn to 19cm then you will get in the porttrait format.

      I hope you understand now,if not please let me know.

      Regards,
      krishna.
      krishna.dynamics@gmail.com

      Delete
    2. Hi Krishna,

      Thanks for the prompt reply.
      The width is small than 19cm actually.
      I'm trying to get it as 4in width and 2.4in height.
      When I key in that value, the orientation is automatically set to landscape.

      Thanks.

      Vincent
      crazysee@gmail.com

      Delete
    3. Sorry. To clarify, i need to print out the label in 4in width and 2.4in height in portrait mode.

      Delete
    4. Hi vincent,
      then decrease you design width to 5in and height to 2.3in
      open your design and reduce your table or textbox to 4in and height to 2.4in and change your text properties as not to increase the height.

      then it will works.

      Regards,
      krishna.

      Delete
    5. Hi Krishna,

      I tried but it doesn't work.
      As long as I set the width value higher than height, system auto set to landscape and the print out will always be side ways.

      Vincent

      Delete
    6. Hi Vincent,
      Yes sorry, always the height of the report should be more than the width, I don't think you required to change the height of the design, only you have to set the width of the potrait to 5in and your text box size you can define to 4in and height 2.4in and uncheck the text box to increace the height, then i think it will works.

      Regards,
      krishna.

      Delete
    7. Hi Krishna,

      Thanks so much for all the replies.
      I tried you method but it didn't work. The printer recognize the and shrink it to fit into the label paper.
      Anyway, I'm using a RDP class. Is there any way to set the orientation programatically?
      Thank you so much.

      Vincent

      Delete
    8. Hi Vincent,
      I got an idea, in you design create a new design as a ListStyleTemplate, select your design and define the template as ListStyleTemplate and provide the datasource as your dataset and provide your height as 2.4in. I hope then it will works.

      Regards,
      krishna.

      Delete
    9. Hi Krishna,

      Can you tell me how to change / set report orientation from AX 2012's Class? like AX 2009

      Thx & Regards,
      Darwanto

      Delete
    10. Hi Darwanto,
      We can set it through controller, for ex take salesConfirm Report
      SalesConfirmController have the method RunPrintMgmt,this method will be there only the document was managed by print management.
      Delcare the following class objects
      SRSPrintDestinationSettings srsPrintDestinationCopySettings,srsPrintDestinationOriginalSettings;

      get the class object printdestination settings for the report
      srsPrintDestinationCopySettings=formLetterReport.parmDefaultCopyPrintJobSettings();
      srsPrintDestinationOriginalSettings=formLetterReport.parmDefaultOriginalPrintJobSettings();

      Assign lanscape method as true
      srsPrintDestinationCopySettings.landscape(true);
      srsPrintDestinationOriginalSettings.landscape(true);


      Then assign the printer settings again to formletterReport
      formLetterReport.parmDefaultCopyPrintJobSettings(srsPrintDestinationCopySettings);
      formLetterReport.parmDefaultOriginalPrintJobSettings(srsPrintDestinationOriginalSettings);


      I hope you got how to do it.

      regards,
      krishna.


      Delete
    11. Hi Krishna,

      Thx for your reply.
      I've tried your method (using RunPrintManagement) and i'm extend the RDP class with SRSReportDataProviderPreProcess.
      Using SalesConfirm as an example, but now i got an error "Parameter 'paramName' does not exist on this report". The error shown after i press "OK" on the report dialog.
      Although i've use controller.parmShowDialog(false) in the main controller class, but the error still exist.

      Can you help me solve this problem?

      Thx in advanced.

      Regards,
      Darwanto

      Delete
  4. Hi , Krishna , basically i want to know that you are using temp table and you mentioned the image below consisting of fields , i made the same query prodtable-inventtransorigin-inventtrans, maked al relations b/w them as you did. but i didn't find the fields when i am inserting in temp table by dragging them from the table????

    ReplyDelete
  5. Sapna Sharma9/30/2012 2:37 PM

    Hi,
    You blog was really help full i was able to create my SSRS report. However I had a question on formatting.

    I have to create a report that has a detachable part in it i.e. once the report is printed the user can cut off a particular section manually.

    I am facing two scenarios:

    1)Report has 3 pages (both side printing) in this case the data will be printed on first two pages and the detachable section will start from third fresh page.

    2) Report has 4 pages out of which 3 has data in it. in this case the first 3 pages will be printed back to back and the 4th page will be left blank. The detachable section should start from 5th page.

    how can i achieve this

    ReplyDelete
  6. Sapna Sharma10/02/2012 5:41 AM

    Hi,

    I forgot to mention i am working in AX 2012.
    To simplify this if the body section of a report takes even number of pages i need to add a page break: detachable section will go to a fresh page.

    If the body section of the report takes odd number of page then i need two page breaks so that detachable section goes to a fresh page.

    ReplyDelete
    Replies
    1. Sapna,
      I'm also in a similar situation. Did you get a solution? Kindly assist.
      Regards,

      Delete
    2. Sapna,
      I got something that maybe sort your out. If you are using tables,you can insert the detachable section in a tablix then from the tablix property dialog, under page break options, check the Add a page break before options.

      Delete
    3. Hey all,

      I am sending out a note to those of you that have taken advantage of my Blog(http://krishhdax.blogspot.com),through skype,Chat..etc, that I have been making over the past couple of years, asking for a favor.

      It is that time of year 2013, and we are now announcing the nomination process for The Most Influential People in Microsoft Dynamics for 2013. I would really like to make the list this year, and I hope that I have influenced you all in my own little way.

      If you feel inclined, you can nominate me by sending an email with a persuasive explanation for the nomination to top100@dynamicsworld.co.uk or through Twitter using the #dwtop100 tag.

      You can find more on the nomination process can be found here: http://www.dynamicsworld.co.uk/top100nominationprocess/

      Thanks in advance.

      Krishna Reddy Modugula | CGI |AX Technical Manager | Microsoft Solutions
      Lautrupvang 10, DK-2750 Ballerup | Denmark
      Phone: +45 44 78 40 00 | Mobile: +45 41 88 23 35
      www.cgi.com | www.cgi.dk
      http://krishhdax.blogspot.com
      http://www.linkedin.com/in/krishhprofile

      Delete
  7. Hi Krishna!

    I have a problem. I am new in SSRS riports and not to experienced in AX. I've tried to create a Report and I am pretty sure that I making an obvious mistake but I cannot realize.
    So creted a query in AX2012. Created a project and a report in VS2010 but when I would like to choose my new query in the dataset query property, I just cannot because I cannot see any newly created query(what my collagues created earlier). But in the Application explorer there is my ( and all of the new objects) queries. So just don't know which property or configures doesn't set. Thanks

    ReplyDelete
  8. Hi Krishna

    I have a problem in sales quotation report. The report run based on selected Quotation journal.I want to run the report for a sales quotation as well as to send a mail to the customer. i tried in Controller class it is not working.

    ReplyDelete
  9. Hi Krishna,

    I am trying to add another design on the WMSPickingList_OrderPick report. (AX2012). It uses the WmsPickingList_OrderPickController class. So there will be two designs and I want to call the different designs from two different menu items.

    controller.parmReportName((ssrsReportStr(WMSPickingList_OrderPick, Report)

    The above line lets me specify the design. but i dont know how to do this depending on the menu item called from.
    Any ideas?

    Thanks
    Thasha

    ReplyDelete
    Replies
    1. Hi Thasha,
      When you have multiple designs for the report, and you have two menuitems, then in your controller main method while passing parmReportName you have to validate from which caller is this from args and you have to pass different deisgns for each menuitem caller for parmreportname(reprtName.designname);

      hope you understand otheriwise ping me on
      krishna.dynamics@gmail.com

      Delete
    2. Hey all,

      I am sending out a note to those of you that have taken advantage of my Blog(http://krishhdax.blogspot.com),through skype,Chat..etc, that I have been making over the past couple of years, asking for a favor.

      It is that time of year 2013, and we are now announcing the nomination process for The Most Influential People in Microsoft Dynamics for 2013. I would really like to make the list this year, and I hope that I have influenced you all in my own little way.

      If you feel inclined, you can nominate me by sending an email with a persuasive explanation for the nomination to top100@dynamicsworld.co.uk or through Twitter using the #dwtop100 tag.

      You can find more on the nomination process can be found here: http://www.dynamicsworld.co.uk/top100nominationprocess/

      Thanks in advance.

      Krishna Reddy Modugula | CGI |AX Technical Manager | Microsoft Solutions
      Lautrupvang 10, DK-2750 Ballerup | Denmark
      Phone: +45 44 78 40 00 | Mobile: +45 41 88 23 35
      www.cgi.com | www.cgi.dk
      http://krishhdax.blogspot.com
      http://www.linkedin.com/in/krishhprofile

      Delete
  10. Hi Krishna.

    I did the same steps, and when I run the report it shows only fixed layout but not the data. I'm trying use the debugger in the Controller Class, but the code don't pass in the controller class methods. How can I associate the DP with the Controller class?

    Thank's!
    I'm learning a lot from your blog

    ReplyDelete
  11. Hi Krishna,
    this is chandru, i am facing problem in SSRS report,please help me on this.
    i added new fields in existing Axapta standard SSRS reports. in UIbuilder and contract class, i added new parameter. in temp table also some fields added. in SSRS reports design those fileds added, while open Ax thick client enter values in parameters and click ok, i am getting this below error
    parameter 'tmptableDS_newParameter' does not exist in the report.
    i deployed the report,restarted AOS & SSRS services.
    i am trying to add this in to existing group but it is giveing some compilation errors. how to resolved this. Please help me. my mail id chandru.mbs@gmail.com

    ReplyDelete
  12. Hi Krishna,

    I understand more about SSRS Report form your blog.I have problem need your advice.

    I am using DP class to generate data in temp table as follow:
    Voucher Amount
    V1 150
    V2 200
    V3 300

    Could we use controller class to print each record in separate report viewer?

    Hope you understand what i mean.

    Thanks in advance

    ReplyDelete
    Replies
    1. Hi Nguyen,
      you have to write the class to filter the data and for each record you have to call the controller,so in your Dp class you will fill only that record.
      classmain.

      Filter the data according in the main and for each record you call start operation.

      I hope you got it, if not ping me on krishna.dynamics@gmail.com

      Delete
    2. Hey all,

      I am sending out a note to those of you that have taken advantage of my Blog(http://krishhdax.blogspot.com),through skype,Chat..etc, that I have been making over the past couple of years, asking for a favor.

      It is that time of year 2013, and we are now announcing the nomination process for The Most Influential People in Microsoft Dynamics for 2013. I would really like to make the list this year, and I hope that I have influenced you all in my own little way.

      If you feel inclined, you can nominate me by sending an email with a persuasive explanation for the nomination to top100@dynamicsworld.co.uk or through Twitter using the #dwtop100 tag.

      You can find more on the nomination process can be found here: http://www.dynamicsworld.co.uk/top100nominationprocess/

      Thanks in advance.

      Krishna Reddy Modugula | CGI |AX Technical Manager | Microsoft Solutions
      Lautrupvang 10, DK-2750 Ballerup | Denmark
      Phone: +45 44 78 40 00 | Mobile: +45 41 88 23 35
      www.cgi.com | www.cgi.dk
      http://krishhdax.blogspot.com
      http://www.linkedin.com/in/krishhprofile

      Delete
  13. Hi Krishna,
    iwould like to show the position heirarchy tree in dialog lookup for SSRS reports generation Axapta think client. Please give me the solution how to show Position hierarchy in dailog lookp.

    Thanks & Regards
    Chandru

    ReplyDelete
    Replies
    1. Hi Chandru,
      if you want to do any lookups for parameters you have to create the builder class and there you have to write the lookup method and register for that contract parm method.

      regards,
      krishna.

      Delete
    2. Hi chandru,
      I updated the post with the builder class to build the lookups for the parameters of report.

      regards,
      krishna.

      Delete
    3. hi Krishna,
      Thanks for your solution. if we are design SSRS report, using precision design, in that design, how we can group the items and shown in header level. for example, in the data set i have 1 customer, for this customer mulitple lines are available. group by customer, i want to show the data in details section, customer id needs to be showned in header level.in Auto design, we have the groupings option is there, but in precision design how we achieve this. Please give the solution how we can do in precision design.

      Regards
      Chandru

      Delete
    4. Hey all,

      I am sending out a note to those of you that have taken advantage of my Blog(http://krishhdax.blogspot.com),through skype,Chat..etc, that I have been making over the past couple of years, asking for a favor.

      It is that time of year 2013, and we are now announcing the nomination process for The Most Influential People in Microsoft Dynamics for 2013. I would really like to make the list this year, and I hope that I have influenced you all in my own little way.

      If you feel inclined, you can nominate me by sending an email with a persuasive explanation for the nomination to top100@dynamicsworld.co.uk or through Twitter using the #dwtop100 tag.

      You can find more on the nomination process can be found here: http://www.dynamicsworld.co.uk/top100nominationprocess/

      Thanks in advance.

      Krishna Reddy Modugula | CGI |AX Technical Manager | Microsoft Solutions
      Lautrupvang 10, DK-2750 Ballerup | Denmark
      Phone: +45 44 78 40 00 | Mobile: +45 41 88 23 35
      www.cgi.com | www.cgi.dk
      http://krishhdax.blogspot.com
      http://www.linkedin.com/in/krishhprofile

      Delete
  14. Hi Krishna,

    after i run the main method on the controller, when it executes the method this.prePromptModifyContract();

    when gos there, i have this line 'this.setRange(this.parmReportContract().parmQueryContracts().lookup(this.getFirstQueryContractKey()));' and here i'm getting the following exception

    Map Object not initialized, can you help why i'm getting this kind of exception?

    ReplyDelete
  15. Hi Krishna,
    I am doing employee profit loss report customizations, in report model, prameters sections added the parameter group in that group i dragged the parameters. after that i try to deploy, it is showing below error
    Error 2 The property 'Report parameter' on model element ':
    CGS_EmplProfitableReport.ProjProfitLossDS(DataSets).TimeMaterial(Parameters)'
    refers to target element 'Parameters.ProjProfitLossDS_TimeMaterial' which cannot be resolved.
    Make sure that the property value is correct and that the target model element is within scope,
    either in the project or in referenced projects or assemblies. \SSRS Reports\Reports\CGS_EmplProfitableReport 0 0 CGS_EMPProfitReport

    without adding in to the parameter group, deployement done successfully.Please give me the solution.

    Thanks & Regards
    Sarat Chandra R

    ReplyDelete
  16. Hi Krishna.
    In AX 2009 reports we were able to write element.JobId() and get jobId. How can I find JobId in AX 2012 if I create SSRS Report using Data Provides Classes?

    Regards,
    Oksana

    ReplyDelete
  17. Hi Krishna,
    Thanks for the solution. I make two SSRS report, but, do you know how run two reports in one view? Because my client need print both reports in a printer with two sides paper wihtout removing paper.
    Thanks and regards,
    Yered

    ReplyDelete
    Replies
    1. Hey all,

      I am sending out a note to those of you that have taken advantage of my Blog(http://krishhdax.blogspot.com),through skype,Chat..etc, that I have been making over the past couple of years, asking for a favor.

      It is that time of year 2013, and we are now announcing the nomination process for The Most Influential People in Microsoft Dynamics for 2013. I would really like to make the list this year, and I hope that I have influenced you all in my own little way.

      If you feel inclined, you can nominate me by sending an email with a persuasive explanation for the nomination to top100@dynamicsworld.co.uk or through Twitter using the #dwtop100 tag.

      You can find more on the nomination process can be found here: http://www.dynamicsworld.co.uk/top100nominationprocess/

      Thanks in advance.

      Krishna Reddy Modugula | CGI |AX Technical Manager | Microsoft Solutions
      Lautrupvang 10, DK-2750 Ballerup | Denmark
      Phone: +45 44 78 40 00 | Mobile: +45 41 88 23 35
      www.cgi.com | www.cgi.dk
      http://krishhdax.blogspot.com
      http://www.linkedin.com/in/krishhprofile

      Delete
  18. Hello Krishna,

    thanks for your comprehensive tutorial.

    I tried to follow it, but I don't see the newly created data provider class in the dialog of Report / Datasets / Query. I see other DP classes, but not mine. I tried incremental CIL but without any change.

    this is the class declaration

    [
    SRSReportParameterAttribute(classStr(LedgerTransOpenContract)),
    SRSReportQueryAttribute(queryStr(LedgerTransOpen))
    ]
    public class LedgerTransOpenDP extends SRSReportDataProviderPreProcess
    {
    LedgerTransOpenTmp ledgerTransOpenTmp;
    }

    do you have any idea, what is wrong?

    ReplyDelete
  19. Hi Krishna

    I desinged a SSRS report in Ax2012 using contract and DP classes.
    I have a small label update issue in contract class.
    I imported all the report related objects and deployed the report.Report is working fine.
    But i changed the label id in the SysOperationLabelAttribute, SysOperationHelpTextAttribute properties for my parameter fields. After changing this, the labels for the parameter fields didnt get updated to the new label.The label for the parameter fields is still pointing to the old label id which was there when i imported. But the help text label got updated.
    I have tried deploying the report again in Visual studio, restarting reporting services, restarting Ax service, clearing usage data, even full cil was done.
    But the label for the parameter field didnot get updated.
    I see the old label when the parameters screen gets opened before printing the report.
    Is there any way that i can update the label for the parameter fields ?

    Thanks in advance

    ReplyDelete
    Replies
    1. Hi Gandadhar,
      Normally it should work if not try to open the design and change in the parameter label value with that label id and deploy it and see...if not some cache problem. restart SSRS,AOS,Clear the AUC files and try..

      Delete
    2. Thanks Krishna

      I have tried giving the labelId in the PromptString property for the parameter in visual studio. There i can see the previously entered labels in the drop down but i am not able to select any of them.
      Eventhough i just simply tried to select it and deploy it. After this i can see the labels updated. Not sure because of what change it got updated
      Thanks again for your information

      Delete
  20. Hi Krishna,

    I need an help in an Existing Report ProdJobCard Report i need to display the transactions for each Job Card respectively.Kindly tell me how can i do that .How can i link the ProdBom with OprNUm and sispaly transations

    ReplyDelete
  21. Hi Krishna,

    Thanks for the whole uttorial!
    I made an SSRS report, works well in Visual Studio. Only problem is, when I want to set it to a Output Menu Item, I got the following: "xxx attribute class has not been declared". I got the DP and the Controller classes. Could you give me tips where to find the root of the issue?

    Thanks in advance!

    ReplyDelete
  22. Hi Krishna Reddy,

    I create an SSRS report Ax 2012. I create function:
    [
    DataMemberAttribute('LedgerConsolidateAccountGroupId'),
    SysOperationHelpTextAttribute(literalstr("@GLS222083")),
    SysOperationGroupMemberAttribute('ConsolidateGroupId'),
    SysOperationDisplayOrderAttribute('4')
    ]
    public LedgerConsolidateAccountGroupId parmConsolidateGroupId(LedgerConsolidateAccountGroupId _consolidateAccountGroupId = consolidateAccountGroupId)
    {
    consolidateAccountGroupId = _consolidateAccountGroupId;
    return consolidateAccountGroupId;
    }
    on Contract class,
    but it seems doesn't pass data to Data Provider class.
    Could you please help.
    Many thanks.

    ReplyDelete
  23. Hi

    I have a requirement like we need to print each record information in each page in Ax 2012 ssrs report
    How can i acheive this.
    can you please help me on this

    ReplyDelete
    Replies
    1. Hi Gangadhar,
      Create group by and define page break after for that group.

      Delete
  24. hi krishna
    i created a lookup but i am not able to fetch data in my lookup from temporary table. please help me krishna.

    ReplyDelete
  25. i want to select multiple fields in my report from the same look up . please help me .

    ReplyDelete
    Replies
    1. Hi Deepak,
      In my above post, I created the lookup for salesId and SalesLineNum in the builder class.
      I dint get the point that you mentioned select multiple fields in report from same lookup. could you please brief it.
      if you want to talk to me on gmail or skype you can send me the contact request.
      gmail:krishna.dynamics@gmail.com

      Delete
  26. Hi Krishna
    My Contract Class code is as follows:-
    1.class declration

    [DataContractAttribute,
    SysOperationContractProcessingAttribute(classstr(tri_uibuilder)) ]
    class tri_contract
    {
    List studentid;
    }
    2.parmstudentid

    [
    DataMemberAttribute('StudentId'),
    AifCollectionTypeAttribute('StudentId', Types::String),
    SysOperationLabelAttribute(literalstr("studentid"))
    ]
    public List parmstudentid(List _studentid = studentid)
    {
    studentid = _studentid;
    return studentid;
    }


    My Dp Class is as following

    [

    SRSReportQueryAttribute(queryStr(tri_lookup)),
    SRSReportParameterAttribute(classStr(tri_contract))
    ]
    public class tri_rdbclass extends SRSReportDataProviderBase
    {
    tempstudent tmptable;
    }


    2.[SRSReportDataSetAttribute('tempstudent')]
    public tempstudent gettempstudent()
    {
    select * from tmptable;
    return tmptable;
    }

    3.Process Report

    public void processReport()
    {
    List studentid=new List(Types::String);
    Query query=new query();
    QueryRun qr;
    QueryBuildDataSource queryBuildDataSource;
    QueryBuildRange queryBuildRange;
    tri_student querytri_student;
    tri_course querytri_course;
    ListEnumerator stuindex;
    tri_contract dataContract;
    str test;
    // Get the query from the runtime using a dynamic query.
    query = this.parmQuery();

    // Get the parameters passed from runtime.
    dataContract = this.parmDataContract() as tri_contract;
    studentid = dataContract.parmstudentid();
    // queryBuildDataSource = query.dataSourceTable(tablenum(tri_student));
    if(studentid.empty())
    {
    queryBuildRange = queryBuildDataSource.addRange(fieldnum(tri_student, studentid));
    // if (!queryBuildRange)
    //{
    // queryBuildRange = queryBuildDataSource.addRange(fieldnum(tri_student, studentid));
    //}
    // If the student id has not been set, then use the parameter value to set it.
    //if(!queryBuildRange.value())
    stuindex= studentid.getEnumerator();
    //test=stuindex.current();
    //while(stuindex.moveNext()){
    //test+="||";
    //test+=stuindex.current();
    }
    queryBuildRange.value(test);


    qr = new QueryRun(query);
    //ttsbegin;
    while(qr.next())
    {
    tmptable.clear();
    querytri_student = qr.get(tablenum(tri_student));
    //this.insertTmpTable(querytri_student,querytri_course);
    querytri_course=qr.get(tableNum(tri_course));
    // this.insertTmpTable(tri_course);
    tmptable.studentid = querytri_student.studentid;
    tmptable.CourseName=querytri_course.coursename;
    tmptable.CourseType=querytri_course.coursetype;
    tmptable.Courseid=querytri_course.Courseid;
    tmptable.StudentName = querytri_student.studentname;

    //select * from querytri_student where querytri_student.Courseid==querytri_course.Courseid;

    tmptable.insert();
    //Tmpco.insert();


    //ttscommit;
    }
    }

    ReplyDelete
  27. my UI bUilder is as follows:-

    class tri_uibuilder extends SrsReportDataContractUIBuilder
    {
    DialogField dialogstudentid;

    boolean enable;
    tri_contract contract;

    }

    2.public void build()
    {
    contract = this.dataContractObject();
    dialogstudentid = this.addDialogField(methodStr(tri_contract, parmstudentid),contract);
    //super();
    }


    3.public void getFromDialog()
    {
    contract = this.dataContractObject();
    super();
    }


    4.public void initializeFields()
    {
    contract = this.dataContractObject();
    }

    5.private void studentidLookup(FormStringControl studentidlookup)
    {
    Query query = new Query();
    QueryBuildDataSource qbds_studentid;
    SysTableLookup systablelookup;
    QueryBuildRange qbr;
    if(studentidlookup!=null)
    {

    // Create an instance of SysTableLookup with the current calling form control.
    sysTableLookup = SysTableLookup::newParameters(tableNum(tri_student), studentidlookup);
    //sysTableLookup = SysTableLookup::newParameters(tableNum(tri_course), studentidlookup);
    // Add fields to be shown in the lookup form.
    qbds_studentid = query.addDataSource(tableNum(tri_student));
    sysTableLookup.addLookupfield(fieldNum(tri_student,StudentId),true);
    // sysTableLookup.addLookupfield(fieldNum(tri_student,StudentName));
    //sysTableLookup.addLookupfield(fieldNum(tri_course,CourseName));
    // sysTableLookup.addLookupfield(fieldNum(tri_course,CourseType));
    // sysTableLookup.addLookupfield(fieldNum(tri_course,CourseId));
    //sysTableLookup.addLookupfield(fieldNum(FilterDemo,Name));

    qbr = qbds_studentid.addRange(fieldNum(tri_student,studentid));
    // qbr.value('20');
    sysTableLookup.parmUseLookupValue(false);

    sysTableLookup.parmQuery(query);
    // Perform the lookup
    sysTableLookup.performFormLookup();
    }
    }

    i have to select multiple records from look up but my look up is empty i.e has no record when calling report.
    and gettintg error list objects not initialised.

    why data is not showing in lookup?
    & why error is there.?
    help me out

    ReplyDelete
  28. I have made a ui builder class which has the dialog field of sales id and sales name in which I used a query build field list for multiselect but when in dialog field I multiselect salesname or salesid it shows only the record of first one selected lookup the others records are not displayed
    please help me out regarding this problem.

    ReplyDelete
  29. I have made a ui builder class which has the dialog field of sales id and sales name in which I used a query build field list for multiselect but when in dialog field I multiselect salesname or salesid it shows only the record of first one selected lookup the others records are not displayed
    please help me out regarding this problem.

    ReplyDelete
  30. hi krishna
    how to change the report designs at run time.
    when we are using multiple designs.

    thanks & regards
    rameshkumar

    ReplyDelete
    Replies
    1. Hi Ramesh,
      You can do in the controller main method. see in the above code main method, in this method do validation and pass whatever the design that you want to use it.
      controller.parmReportName("ProdPackList.Report");

      Delete
  31. Hi Krishna, Good article.
    I was searching for the method processPreRunValidate.
    However in your article you say to throw an error instead of sending the error Type enum back. Instead you should use
    validateResult = [SrsReportPreRunState::Error, "No records available for the Selected criteria"];
    The second element in the container being the message instead (If its empty then the default message of exceeding records for timeout will be shown) :)

    ReplyDelete
    Replies
    1. Hi
      I'm facing problem with ssrs reports, Here is my requirement

      I have created a new custom report (with new DP, Contract,Controller) and when ever customer(client)selects copy from Print management-- (where my customer report is attached to drop down list of report format field) my custom report should open from CustinvoiceJourmal--Copy preview --Custom report
      AR_printmanagement-- customerinvoice-- copy

      Where should i write the code for my report should open

      can you please help me with code...

      Thanks in advance
      Vivek Goud
      vivekvalandas@gmail.com

      Delete
    2. Hi Vivek,
      I already posted one post regarding the configuring the printmanagement for the report, could you please see that post
      for your reference I am adding the url below.

      http://krishhdax.blogspot.dk/2012/02/ax2012-configure-print-management-for.html

      Delete

Thanks for visiting my blog,
I will reply for your comment within 48 hours.

Thanks,
krishna.