Skip to main content

Notifications

Announcements

No record found.

Finance | Project Operations, Human Resources, ...
Answered

Pass parameter from form to report

(0) ShareShare
ReportReport
Posted on by 284

Hello everyone,

I have created a SSRS report that uses Contract,Contoller and DP classes and I want to pass a paremeter that I'm creating on the button click, to the report.

I have create a parameter in the contract class

class TCI_OutsideServicePackingSlipContract
{
    TCI_OutsideServicePackingSlipId     packingSlipId;

    [
    DataMemberAttribute('TCI_OutsideServicePackingSlipId'),
    SysOperationLabelAttribute(literalStr('PackingSlipId')),
    SysOperationControlVisibilityAttribute(false)
    ]
    public TCI_OutsideServicePackingSlipId parmPackingSlipId(TCI_OutsideServicePackingSlipId _packingSlipId = packingSlipId)
    {
        packingSlipId = _packingSlipId;
        return packingSlipId;
    }

}

I have tried to pass the field into the parameter during the button click

 public void clicked()
        {
            TCI_OutsideServiceImportLog             outsideServiceImport;
            MultiSelectionHelper                    helper = MultiSelectionHelper::construct();
            TCI_OutsideServicePackingSlipHeader     packingSlipHeader;
            TCI_OutsideServicePackingSlipDetails    packingSlipDetails;
            int                                     sequence = 0;
            TCI_OutsideServicePackingSlipContract   contract = new TCI_OutsideServicePackingSlipContract();

            helper.parmDatasource(TCI_OutsideServiceImportLog_DS);

            outsideServiceImport  = helper.getFirst();

            packingSlipHeader.TCI_OutsideServicePackingSlipId   = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT(),true).num();
            packingSlipHeader.PurchId                           = outsideServiceImport.ResultNumber;
            packingSlipHeader.VendAccount                       = outsideServiceImport.VendAccount;
            packingSlipHeader.insert();

            contract.parmPackingSlipId(packingSlipHeader.TCI_OutsideServicePackingSlipId);

            while(outsideServiceImport.RecId != 0)
            {
                packingSlipDetails.TCI_OutsideServicePackingSlipId  = packingSlipHeader.TCI_OutsideServicePackingSlipId;
                packingSlipDetails.Seq                              = sequence;
                sequence = sequence   1;
                packingSlipDetails.ItemId                           = outsideServiceImport.ItemId;
                packingSlipDetails.QtyOrdered                       = outsideServiceImport.Qty;
                packingSlipDetails.insert();
                outsideServiceImport = helper.getNext();
            }

            super();
        }

But when I get to my controller class, that parameter is empty......

class TCI_OutsideServicePackingSlipController extends SrsReportRunController
{
    public static void main(Args _args)
    {
        SrsReportRunController controller = new TCI_OutsideServicePackingSlipController();
        controller.parmReportName(ssrsReportStr(TCI_OutsideServicePackingSlip, Report));
        controller.parmArgs(_args);
        controller.startOperation();
    }

    protected void prePromptModifyContract()
    {
        TCI_OutsideServicePackingSlipContract   contract = this.parmReportContract().parmRdpContract();
        TCI_OutsideServicePackingSlipId         packingSlipId;
        
        packingSlipId = contract.parmPackingSlipId();        

        this.parmReportContract().parmReportName(ssrsReportStr(TCI_OutsideServicePackingSlip, Report));
        boolean isPreview = false;

        //Set the target print destination to screen
        if (isPreview)
        {
            this.parmReportContract().parmPrintSettings().printMediumType(SRSPrintMediumType::Screen);
        }

        this.parmshowDialog(!isPreview);
        this.parmLoadFromSysLastValue(!isPreview);
    }

}

Normally, I wouldn't put that line packingSlipId = contract...... but I wanted to put a break point there to see if it gets anything, which is doesn't.

What am I missing?  I thought I would be able to just pass it in the contract and then grab it again if needed.....

  • Suggested answer
    Andrew Huisman Profile Picture
    Andrew Huisman 284 on at
    RE: Pass parameter from form to report

    Thank you Martin for all your help!  I got this working, but I agree with an earlier statement of yours saying if someone cancels printing, then the records will have been created but nothing got printed.

    So in a perfect world, I would like to get the next PS number and save it, but only create the records in the tables if the person prints.......

    Here is my code that currently creates the record before printing

    class TCI_OutsideServicePackingSlipController extends SrsReportRunController
    {
        TCI_OutsideServicePackingSlipHeader packingSlipHeader;
        public static void main(Args _args)
        {
            TCI_OutsideServicePackingSlipController                  controller = new TCI_OutsideServicePackingSlipController();
            
            controller.parmReportName(ssrsReportStr(TCI_OutsideServicePackingSlip, Report));
            controller.parmArgs(_args);
            controller.createReportData();
            controller.startOperation();
        }
    
        private void createReportData()
        {
            if (!args.caller())
            {
                throw error("This report is implemented in such a way that it must be called from a form.");
            }
     
            MultiSelectionHelper helper = MultiSelectionHelper::createFromCaller(args.caller());
     
            TCI_OutsideServiceImportLog outsideServiceImport = helper.getFirst();
    
            ttsBegin;
     
            packingSlipHeader.TCI_OutsideServicePackingSlipId   = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT()).num();
            packingSlipHeader.PurchId                           = outsideServiceImport.ResultNumber;
            packingSlipHeader.VendAccount                       = outsideServiceImport.VendAccount;
            packingSlipHeader.insert();
     
            int sequence;
    
            while (outsideServiceImport.RecId != 0)
            {
                TCI_OutsideServicePackingSlipDetails packingSlipDetails;
     
                packingSlipDetails.TCI_OutsideServicePackingSlipId  = packingSlipHeader.TCI_OutsideServicePackingSlipId;
                packingSlipDetails.Seq                              = sequence;
                packingSlipDetails.ItemId                           = outsideServiceImport.ItemId;
                packingSlipDetails.QtyOrdered                       = outsideServiceImport.Qty;
                packingSlipDetails.insert();
      
                sequence  ;
      
                outsideServiceImport = helper.getNext();
            }
     
            ttsCommit;
        }
    
        protected void prePromptModifyContract()
        {
            super();
    
            TCI_OutsideServicePackingSlipContract   contract = this.parmReportContract().parmRdpContract();
            
            contract.parmPackingSlipId(packingSlipHeader.TCI_OutsideServicePackingSlipId);
    
        }
    
    }

  • Verified answer
    Martin Dráb Profile Picture
    Martin Dráb 230,962 Most Valuable Professional on at
    RE: Pass parameter from form to report

    OK, let move this thread to the right forum.

    The fix is simple - declare the controller variable as TCI_OutsideServicePackingSlipController instead of SrsReportRunController. You can see that the method does exist; it's declared at line 14.

  • Andrew Huisman Profile Picture
    Andrew Huisman 284 on at
    RE: Pass parameter from form to report

    Hi Martin,

    Sorry I forgot to mention I'm using F&O

    I put in your code but I'm getting an error because this controller extends SrsReportRunController which doesn't have a method createReportData.  Is there another method I could use?

    class TCI_OutsideServicePackingSlipController extends SrsReportRunController
    {
        TCI_OutsideServicePackingSlipHeader packingSlipHeader;
        public static void main(Args _args)
        {
            SrsReportRunController                  controller = new TCI_OutsideServicePackingSlipController();
            
            controller.parmReportName(ssrsReportStr(TCI_OutsideServicePackingSlip, Report));
            controller.parmArgs(_args);
            controller.createReportData();
            controller.startOperation();
        }
    
        private void createReportData()
        {
            if (!args.caller())
            {
                throw error("This report is implemented in such a way that it must be called from a form.");
            }
     
            MultiSelectionHelper helper = MultiSelectionHelper::createFromCaller(args.caller());
     
            TCI_OutsideServiceImportLog outsideServiceImport = helper.getFirst();
    
            ttsBegin;
     
            packingSlipHeader.TCI_OutsideServicePackingSlipId   = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT()).num();
            packingSlipHeader.PurchId                           = outsideServiceImport.ResultNumber;
            packingSlipHeader.VendAccount                       = outsideServiceImport.VendAccount;
            packingSlipHeader.insert();
     
            int sequence;
    
            while (outsideServiceImport.RecId != 0)
            {
                TCI_OutsideServicePackingSlipDetails packingSlipDetails;
     
                packingSlipDetails.TCI_OutsideServicePackingSlipId  = packingSlipHeader.TCI_OutsideServicePackingSlipId;
                packingSlipDetails.Seq                              = sequence;
                packingSlipDetails.ItemId                           = outsideServiceImport.ItemId;
                packingSlipDetails.QtyOrdered                       = outsideServiceImport.Qty;
                packingSlipDetails.insert();
      
                sequence  ;
      
                outsideServiceImport = helper.getNext();
            }
     
            ttsCommit;
        }
    
        protected void prePromptModifyContract()
        {
            TCI_OutsideServicePackingSlipContract   contract = this.parmReportContract().parmRdpContract();
            
            contract.parmPackingSlipId(packingSlipHeader.TCI_OutsideServicePackingSlipId);
    
            //this.parmReportContract().parmReportName(ssrsReportStr(TCI_OutsideServicePackingSlip, Report));
            boolean isPreview = false;
    
            //Set the target print destination to screen
            if (isPreview)
            {
                this.parmReportContract().parmPrintSettings().printMediumType(SRSPrintMediumType::Screen);
            }
    
            this.parmshowDialog(!isPreview);
            this.parmLoadFromSysLastValue(!isPreview);
        }
    
    }

  • Verified answer
    Martin Dráb Profile Picture
    Martin Dráb 230,962 Most Valuable Professional on at
    RE: Pass parameter from form to report

    You'll make everyone's life (starting with yours) much easier if you get used to splitting logic to methods give those methods descriptive names. Don't just throw all code to clicked(), main() or so. You see that it's difficult to even comment our your logic. And of course, throw away things that aren't used, such as outsideServiceImport_ds variable.

    You still didn't tell us whether you're using AX 2012 or F&O, so let me guess and give you an example for F&O:

    TCI_OutsideServicePackingSlipHeader packingSlipHeader;
    
    public static void main(Args _args)
    {
    	SrsReportRunController controller = new TCI_OutsideServicePackingSlipController();
    
    	controller.parmReportName(ssrsReportStr(TCI_OutsideServicePackingSlip, Report));
    	controller.parmArgs(_args);
    	controller.createReportData();
    	controller.startOperation();
    }
    
    private void createReportData()
    {
    	if (!args.caller())
    	{
    		throw error("This report is implemented in such a way that it must be called from a form.");
    	}
    	
    	MultiSelectionHelper helper = MultiSelectionHelper::createFromCaller(_args.caller());
    	
    	TCI_OutsideServiceImportLog outsideServiceImport = helper.getFirst();
    
    	ttsBegin;
    	
    	packingSlipHeader.TCI_OutsideServicePackingSlipId   = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT()).num();
    	packingSlipHeader.PurchId                           = outsideServiceImport.ResultNumber;
    	packingSlipHeader.VendAccount                       = outsideServiceImport.VendAccount;
    	packingSlipHeader.insert();
    	
    	int sequence;
    
    	while (outsideServiceImport.RecId != 0)
    	{
    		TCI_OutsideServicePackingSlipDetails packingSlipDetails;
    	
    		packingSlipDetails.TCI_OutsideServicePackingSlipId  = packingSlipHeader.TCI_OutsideServicePackingSlipId;
    		packingSlipDetails.Seq                              = sequence;
    		packingSlipDetails.ItemId                           = outsideServiceImport.ItemId;
    		packingSlipDetails.QtyOrdered                       = outsideServiceImport.Qty;
    		packingSlipDetails.insert();
    		
    		sequence  ;
    		
    		outsideServiceImport = helper.getNext();
    	}
    	
    	ttsCommit;
    }
    
    protected void prePromptModifyContract()
    {
    	super();
    	
    	TCI_OutsideServicePackingSlipContract contract = controller.parmReportContract().parmRdpContract();
    	contract.parmPackingSlipId(packingSlipHeader.TCI_OutsideServicePackingSlipId);
    }

    Call createReportData() before startOperation() if you must have data generated even before showing the printing dialog to a user. Note that the user may cancel printing, while your data is already saved in database. This implementation looks strange to me, but I know nothing about related business requirements.

    Do you still observe the same behavior ("Report name is not set" when using createReportData() and a successful run if you comment out createReportData())?

  • Andrew Huisman Profile Picture
    Andrew Huisman 284 on at
    RE: Pass parameter from form to report

    Hi Martin,

    I know how to put a value into the parameter in the controller class.  That was never my issue.

    I would like to do the following in the controller class

    1. Grab the selected records from the calling form

    2. Create a new record in the table TCI_OutsideServicePackingSlipHeader

    3. Loop through the selected records from the form in which I will also create new records in the table TCI_OutsideServicePackingSlipDetails.

    So basically I'm trying to do something like this in the controller class somewhere......

            TCI_OutsideServiceImportLog             outsideServiceImport;
            FormDataSource                          outsideServiceImport_ds;
            MultiSelectionHelper                    helper = MultiSelectionHelper::construct();
            TCI_OutsideServicePackingSlipHeader     packingSlipHeader;
            TCI_OutsideServicePackingSlipDetails    packingSlipDetails;
            int                                     sequence = 0;
            TCI_OutsideServicePackingSlipContract   contract = controller.parmReportContract().parmRdpContract();
    
            helper = MultiSelectionHelper::createFromCaller(_args.caller());
    
            outsideServiceImport  = helper.getFirst();
    
            packingSlipHeader.TCI_OutsideServicePackingSlipId   = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT(),true).num();
            packingSlipHeader.PurchId                           = outsideServiceImport.ResultNumber;
            packingSlipHeader.VendAccount                       = outsideServiceImport.VendAccount;
            packingSlipHeader.insert();
    
            while(outsideServiceImport.RecId != 0)
            {
                packingSlipDetails.TCI_OutsideServicePackingSlipId  = packingSlipHeader.TCI_OutsideServicePackingSlipId;
                packingSlipDetails.Seq                              = sequence;
                sequence = sequence   1;
                packingSlipDetails.ItemId                           = outsideServiceImport.ItemId;
                packingSlipDetails.QtyOrdered                       = outsideServiceImport.Qty;
                packingSlipDetails.insert();
                outsideServiceImport = helper.getNext();
            }
    
            contract.parmPackingSlipId(packingSlipHeader.TCI_OutsideServicePackingSlipId);

    I put that in the main of the controller, and it gives me an error saying "Report name is not set.  Please set report name using parmReportName method"

     public static void main(Args _args)
        {
            SrsReportRunController                  controller = new TCI_OutsideServicePackingSlipController();
            TCI_OutsideServiceImportLog             outsideServiceImport;
            FormDataSource                          outsideServiceImport_ds;
            MultiSelectionHelper                    helper = MultiSelectionHelper::construct();
            TCI_OutsideServicePackingSlipHeader     packingSlipHeader;
            TCI_OutsideServicePackingSlipDetails    packingSlipDetails;
            int                                     sequence = 0;
            TCI_OutsideServicePackingSlipContract   contract = controller.parmReportContract().parmRdpContract();
    
            helper = MultiSelectionHelper::createFromCaller(_args.caller());
    
            outsideServiceImport  = helper.getFirst();
    
            packingSlipHeader.TCI_OutsideServicePackingSlipId   = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT(),true).num();
            packingSlipHeader.PurchId                           = outsideServiceImport.ResultNumber;
            packingSlipHeader.VendAccount                       = outsideServiceImport.VendAccount;
            packingSlipHeader.insert();
    
            while(outsideServiceImport.RecId != 0)
            {
                packingSlipDetails.TCI_OutsideServicePackingSlipId  = packingSlipHeader.TCI_OutsideServicePackingSlipId;
                packingSlipDetails.Seq                              = sequence;
                sequence = sequence   1;
                packingSlipDetails.ItemId                           = outsideServiceImport.ItemId;
                packingSlipDetails.QtyOrdered                       = outsideServiceImport.Qty;
                packingSlipDetails.insert();
                outsideServiceImport = helper.getNext();
            }
    
            contract.parmPackingSlipId(packingSlipHeader.TCI_OutsideServicePackingSlipId);
            
            controller.parmReportName(ssrsReportStr(TCI_OutsideServicePackingSlip, Report));
            controller.parmArgs(_args);
            controller.startOperation();
        }

    If I comment out the first chunk of code, then it works great

    public static void main(Args _args)
        {
            SrsReportRunController                  controller = new TCI_OutsideServicePackingSlipController();
            //TCI_OutsideServiceImportLog             outsideServiceImport;
            //FormDataSource                          outsideServiceImport_ds;
            //MultiSelectionHelper                    helper = MultiSelectionHelper::construct();
            //TCI_OutsideServicePackingSlipHeader     packingSlipHeader;
            //TCI_OutsideServicePackingSlipDetails    packingSlipDetails;
            //int                                     sequence = 0;
            //TCI_OutsideServicePackingSlipContract   contract = controller.parmReportContract().parmRdpContract();
    
            //helper = MultiSelectionHelper::createFromCaller(_args.caller());
    
            //outsideServiceImport  = helper.getFirst();
    
            //packingSlipHeader.TCI_OutsideServicePackingSlipId   = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT(),true).num();
            //packingSlipHeader.PurchId                           = outsideServiceImport.ResultNumber;
            //packingSlipHeader.VendAccount                       = outsideServiceImport.VendAccount;
            //packingSlipHeader.insert();
    
            //while(outsideServiceImport.RecId != 0)
            //{
            //    packingSlipDetails.TCI_OutsideServicePackingSlipId  = packingSlipHeader.TCI_OutsideServicePackingSlipId;
            //    packingSlipDetails.Seq                              = sequence;
            //    sequence = sequence   1;
            //    packingSlipDetails.ItemId                           = outsideServiceImport.ItemId;
            //    packingSlipDetails.QtyOrdered                       = outsideServiceImport.Qty;
            //    packingSlipDetails.insert();
            //    outsideServiceImport = helper.getNext();
            //}
    
            //contract.parmPackingSlipId(packingSlipHeader.TCI_OutsideServicePackingSlipId);
            
            controller.parmReportName(ssrsReportStr(TCI_OutsideServicePackingSlip, Report));
            controller.parmArgs(_args);
            controller.startOperation();
        }

  • Martin Dráb Profile Picture
    Martin Dráb 230,962 Most Valuable Professional on at
    RE: Pass parameter from form to report

    Sure, AX / F&O (you didn't tell us what you're using) is full of report controllers. But what do you want to demonstrate?

    If you want to see, say, examples of prePromptModifyContract() method, simply use "Find references" on this method. For instance, this is what you can see AssetExploitationController.prePromptModifyContract():

    // Get the contract
    contract   = this.parmReportContract().parmRdpContract() as AssetExploitationContract;
    // Set a value to the contract
    contract.parmDocumentNumber(assetTrans.DocumentNum_W);
    

    I can't tell how your code caused a problem with the report name, because I don't know your current code and your previous code didn't do anything like that.

  • Andrew Huisman Profile Picture
    Andrew Huisman 284 on at
    RE: Pass parameter from form to report

    Hi Martin,

    Do you know of an existing controller that I could look at as an example for best practices?  I keep searching the net and can't find anything.  I put some code in the controller that I thought would work but then got an error that the ReportName was not specified, so I took all that code out again to get it working.

    To give some clarification I'm coming from a form called TCI_OutsideServiceLogForm

    When someone clicks the Create Packing Slip, it's going to create a new packing slip ID and the print the packing slip

    I got the report side of things working perfectly.

    What I want now, is to create the new PS ID into a table called TCI_OutsideServicePackingSlipHeader

    I had all the code working exactly how I wanted up above, except I couldn't pass the new PS ID to the report, so now I would like to do what you suggest and create that PS ID in the controller.

    How do I begin.....

  • Martin Dráb Profile Picture
    Martin Dráb 230,962 Most Valuable Professional on at
    RE: Pass parameter from form to report

    In the controller, you can call this.parmReportContract().parmRdpContract() to get the contract object. Then you'll put the value there.

    The usual places for contract initialization are prePromptModifyContract() and preRunModifyContract().

  • Andrew Huisman Profile Picture
    Andrew Huisman 284 on at
    RE: Pass parameter from form to report

    Yes that logic is specific to that report.  It's the first time I've created a table with an ID where I created a number sequence for and I wasn't sure where to put that logic.  I will move it to the controller since you are saying it's best practice and hopefully from there it's easy to pass it into the contract.

  • Martin Dráb Profile Picture
    Martin Dráb 230,962 Most Valuable Professional on at
    RE: Pass parameter from form to report

    You create a new instance of your contract and put the value there, but then you don't use the contract anywhere, therefore it doesn't have any effect.

    You should populate the contract object used by the controller. The controller doesn't exist before line 5 of main() method, therefore you can do it only in main or in methods called from main (such as parmArgs()).

    I see that you have a lot of business logic in clicked() method (which isn't a good place) and this logic creates the value you want. Is this logic specific to the report? If so, put it into the controller class. If not, why do you have it in clicked() method of the button to print the report? Anyway, if you want that, I suggest you pass the value to main() through Args. There you'll extract it and put it into the contract.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Announcing Our 2025 Season 1 Super Users!

A new season of Super Users has arrived, and we are so grateful for the daily…

Vahid Ghafarpour – Community Spotlight

We are excited to recognize Vahid Ghafarpour as our February 2025 Community…

Congratulations to the January Top 10 leaders!

Check out the January community rock stars...

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 292,162 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 230,962 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans