web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Suggested Answer

Call Controller Class from other code

(0) ShareShare
ReportReport
Posted on by 313
Hello everyone,
 
I have a controller class that I call when I'm printing a report.  Right now it creates a brand new packing slip number and I write that number to a table so it can be referenced, and records won't be printed again on another packing slip.
 
I would like the ability to reprint a packing slip so I was thinking that I could prompt for a Packing Slip number, take that number and somehow give it to the controller class and run it.  Would that work?  The only piece of the controller I would not call is the .getPackingSlipId();
 
Here is my controller
class TCI_OutsideServicePackingSlipController extends SrsReportRunController{    TCI_OutsideServicePackingSlipHeader     packingSlipHeader;    TCI_OutsideServicePackingSlipId         packingSlipId;    TCI_OutsideServicePackingSlipJournal    packingSlipJournal;    public static void main(Args _args)    {            TCI_OutsideServicePackingSlipController     controller = new TCI_OutsideServicePackingSlipController();        controller.parmReportName(ssrsReportStr(TCI_OutsideServicePackingSlip, Report));            controller.parmArgs(_args);        //controller.createReportData();        controller.getPackingSlipId();        controller.startOperation();        //controller.createReportData();    }    private void getPackingSlipId()    {        packingSlipId = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT()).num();    }    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.TCI_OutsideServicePackingSlipId   = packingSlipId;        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.TCI_ScanRefNumber                = outsideServiceImport.TCI_ScanRefNumber;            packingSlipDetails.LineNumber                       = outsideServiceImport.ResultLineNum;            packingSlipDetails.insert();            //Inserting record into journal table            packingSlipJournal.TCI_OutsideServicePackingSlipId  = packingSlipHeader.TCI_OutsideServicePackingSlipId;            packingSlipJournal.TCI_ScanNumber                   = outsideServiceImport.TCI_ScanNumber;            packingSlipJournal.insert();                        sequence++;            outsideServiceImport = helper.getNext();        }        ttsCommit;    }    protected void prePromptModifyContract()    {        super();        TCI_OutsideServicePackingSlipContract   contract = this.parmReportContract().parmRdpContract();        contract.parmPackingSlipId(packingSlipId);        contract.parmDriver('');        contract.parmNotes('');    }    public void run()    {        this.createReportData();        super();    }}
Now I have a new button called Reprint Packing Slip where I prompt what Packing Slip they want to reprint.  That works, but I'm not sure how to take their input and send it to the controller and run it.....
This is my code but it's not working and it's not even debugging correctly.....
[Control(/Button/)]class FormButtonControl1    {        /// <summary>        ///        /// </summary>        public void clicked()        {            Dialog                          dialog;            DialogGroup                     dialogGroup;            DialogField                     dialogField;            MenuFunction                    menuFunction;            Args                            args;            TCI_OutsideServiceImportLog     tempTable;            dialog = new Dialog(/What Packing Slip would you like to reprint?/);            dialogField = dialog.addField(extendedTypeStr(TCI_OutsideServicePackingSlipId));            if (dialog.run())            {                select tempTable                    where tempTable.TCI_ScanNumber == dialogField.value();                if (tempTable)                {                    args = new Args();                    menuFunction = new MenuFunction(menuItemActionStr(/TCI_OutsideServicePackingSlip/), MenuItemType::Action);                    args.record(tci_OutsideServiceImportLog);                    args.menuItemName(//);                    menuFunction.run(args);                }            }            super();        }}
Can someone please point me in the right direction?
I have the same question (0)
  • Andrew Huisman Profile Picture
    313 on at
    And if someone could please tell me how to post code correctly, that would be appreciated.  I can't seem to get it to look correct
  • André Arnaud de Calavon Profile Picture
    300,911 Super User 2025 Season 2 on at
    Hi Andrew,
     
    The pasting of the coding didn't work here. I tried to fix it, but it still appears not in a readable state. Usually when I use the Insert code snippet it is formatted correctly. It could be a specific code page mismach, but not sure.
     
    Maybe you can replace the code snippets with screenshots?
  • Martin Dráb Profile Picture
    237,795 Most Valuable Professional on at
    Unfortunately, I can't give you a solution for "it's not working and it's not even debugging correctly", because it tells nothing about your problem. Please describe what exactly happens. First of all, find out whether your code in clicked() calls the menu item or it fails even before that.
     
    I'm assuming that TCI_OutsideServiceImportLog isn't a temporary table and you just used a misleading variable name (tempTable).
     
    Formatting doesn't work correctly in the first message; it works in replies.
  • Martin Dráb Profile Picture
    237,795 Most Valuable Professional on at
    For reference, this is code of Andrew's clicked() method (that I simplified a bit):
    public void clicked()
    {
        Dialog dialog = new Dialog("What Packing Slip would you like to reprint?");
        DialogField dialogField = dialog.addField(extendedTypeStr(TCI_OutsideServicePackingSlipId));
        
        if (dialog.run())
        {
            TCI_OutsideServiceImportLog tempTable;
            
            select tempTable
                where tempTable.TCI_ScanNumber == dialogField.value();
    
            if (tempTable)
            {
                Args args = new Args();
    
                MenuFunction menuFunction = new MenuFunction(menuItemActionStr(TCI_OutsideServicePackingSlip), MenuItemType::Action);
                args.record(tci_OutsideServiceImportLog);
    
                menuFunction.run(args);
            }
        }
        
        super();
    }
  • Andrew Huisman Profile Picture
    313 on at
    Hi Martin,
     
    I knew you would call me out on not enough detail :)
     
    And thank you for letting me know about the original post code compared to the reply code.
     
    After looking at the code a little more, I noticed I made a few small mistakes.  I have corrected those and this code works to the point where it gets to the dialog prompt before the report, but the Packing Slip number is filled out with a new Packing Slip number.  I'm hoping to reprint the records they chose.  But I can see with my code, that it's just calling the same MenuFunction that I use when creating a new Packing Slip so of course it calls it.
     
    I'm wondering if there is a way to just call the controller from this code instead of calling the menuitem.  I was thinking either I do that, or I just create another controller class without the creation of the new packing slip number.
     
    Here is my code in the clicked that I would like to change to call the controller class but skip the getPackingSlipId method
    public void clicked()
            {
                Dialog              dialog = new Dialog("What Packing Slip would you like to reprint?");
                DialogField         dialogField = dialog.addField(extendedTypeStr(TCI_OutsideServicePackingSlipId));
    
                if (dialog.run())
                {
                    TCI_OutsideServiceImportLog             outsideServiceImport;
                    TCI_OutsideServicePackingSlipJournal    packingSlipJournal;
    
                    select outsideServiceImport
                        join packingSlipJournal
                        where packingSlipJournal.TCI_ScanNumber == outsideServiceImport.TCI_ScanNumber
                        && packingSlipJournal.TCI_OutsideServicePackingSlipId  == dialogField.value();
    
                    if (outsideServiceImport)
                    {
                        Args args = new Args();
                        MenuFunction menuFunction = new MenuFunction(menuItemActionStr("TCI_OutsideServicePackingSlip"), MenuItemType::Action);
                        args.record(outsideServiceImport);
                        args.menuItemName("");
                        menuFunction.run(args);
                    }                
                }
    
                super();
            }
    Here is the controller I call when creating a brand new report.  I hoping I can reuse it to reprint an old packing slip
    class TCI_OutsideServicePackingSlipController extends SrsReportRunController
    {
        TCI_OutsideServicePackingSlipHeader     packingSlipHeader;
        TCI_OutsideServicePackingSlipId         packingSlipId;
        TCI_OutsideServicePackingSlipJournal    packingSlipJournal;
        public static void main(Args _args)
        {
            TCI_OutsideServicePackingSlipController     controller = new TCI_OutsideServicePackingSlipController();
            
            controller.parmReportName(ssrsReportStr(TCI_OutsideServicePackingSlip, Report));
            controller.parmArgs(_args);
            //controller.createReportData();
            controller.getPackingSlipId();
            controller.startOperation();
            //controller.createReportData();
        }
    
        private void getPackingSlipId()
        {
            packingSlipId = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT()).num();
        }
    
        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.TCI_OutsideServicePackingSlipId   = packingSlipId;
            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.TCI_ScanRefNumber                = outsideServiceImport.TCI_ScanRefNumber;
                packingSlipDetails.LineNumber                       = outsideServiceImport.ResultLineNum;
                packingSlipDetails.insert();
    
                //Inserting record into journal table
                packingSlipJournal.TCI_OutsideServicePackingSlipId  = packingSlipHeader.TCI_OutsideServicePackingSlipId;
                packingSlipJournal.TCI_ScanNumber                   = outsideServiceImport.TCI_ScanNumber;
                packingSlipJournal.insert();
      
                sequence++;
      
                outsideServiceImport = helper.getNext();
            }
     
            ttsCommit;
        }
    
        protected void prePromptModifyContract()
        {
            super();
    
            TCI_OutsideServicePackingSlipContract   contract = this.parmReportContract().parmRdpContract();
            
            contract.parmPackingSlipId(packingSlipId);
            contract.parmDriver('');
            contract.parmNotes('');
        }
    
        public void run()
        {
            this.createReportData();
    
            super();
        }
    
    }
     
     
  • Martin Dráb Profile Picture
    237,795 Most Valuable Professional on at
    If you're successfully passing the record to TCI_OutsideServicePackingSlipController::main(), the next step is using it. One option is getting it from _args in main() and the other from args variable in an instance method.
     
    For example:
    protected void prePromptModifyContract()
    {
        super();
    
        TCI_OutsideServiceImportLog importLog = args.record() as TCI_OutsideServiceImportLog;
        
        str packingSlipId;
        
        if (... importLog contains packing slip ID ...)
        {
            packingSlipId = ... assign from import log ...
        }
        else
        {
            packingSlipId = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT()).num();
        }
    
        TCI_OutsideServicePackingSlipContract contract = this.parmReportContract().parmRdpContract();
        
        contract.parmPackingSlipId(packingSlipId);
        ...
    }
    Note that the logic you have in createReportData() doesn't belong to a report controller. Report data should be prepared by a Report Data Provided (RDP) class when the report executes (which may be a completely different time and place, if the user decides to run it in batch).
  • Andrew Huisman Profile Picture
    313 on at
    So it's working up to the point where it fills in the correct packing slip number on the prompt before the report, but then I get an error saying "This report is implemented in such a way that it must be called from a form".
     
    I also saw your comment about not having my controller setup correctly so perhaps we need to back up for a minute to get this done right.  Either that, or we just get my new request working since the original controller is working correctly.
     
    Let's start from the beginning.
    There is a form called TCI_OutsideServiceImportLog that users want to be able to choose some lines from and create a packing slip report to print.
    We use Docentric to create reports which still uses Contract, Controller and DP classes but they also use a DSP class that holds all the information.  I'm still somewhat new to it so I can create reports in it, but when it comes to selected multiple records on a form and looping through them was new to me.  I got it working by looping through in the Controller Class.
     
    After the report was working the way they wanted, they came to me and asked if they could find a way to reprint packing slips.
     
    I wasn't saving the packing slip numbers anywhere because before there was no request for it.  So the main table on that form (TCI_OutsideServiceImportLog) does not have a Packing Slip field.  I created a new table called TCI_OutsideServicePakcingSlipJournal and tied it with the Scan Number.
     
    Anyway, now that I'm writing this, I'm thinking to myself, why did I create a new table?  I should have just added a new field to the existing table, so that's what I'm going to do.
     
    Then after that, I think I'll use the same button "Print Packing Slip" and first it will check if all lines have a packing slip ID and it matches.  If so, then assume they are reprinting the packing slip.  If all lines are blank, assume they are printing a new packing slip.  If one line has a packing slip and one line does not, tell them they need to choose differently.
     
    Hopefully that makes sense and works.  I appreciate your help and I may come back here to post an update after I implement my changes......
  • Suggested answer
    Andrew Huisman Profile Picture
    313 on at
    So I got this working the way I would like, and how the user would like.
     
    First, on the click of the menuitembutton, I check to see if any of the lines have a packing slip ID.  If they all match, which also means all blank, it will continue.  If two packing slips are different, than it errors
    public void clicked()
            {
                MultiSelectionHelper            helper = MultiSelectionHelper::construct();
                TCI_OutsideServicePackingSlipId packingSlipId;
                boolean                         cannotPrint = false;
                boolean                         first = true;
                
                helper.parmDatasource(TCI_OutsideServiceImportLog_ds);
     
                TCI_OutsideServiceImportLog outsideServiceImport = helper.getFirst();
    
                while (outsideServiceImport.RecId != 0)
                {
                    //Check if it's the first record
                    if (first)
                    {
                        //Write packing slip to variable to check if second line has the same one
                        packingSlipId = outsideServiceImport.TCI_OutsideServicePackingSlipId;
                        first = false;
                    }
                    else
                    {
                        //Check to see if the second and following lines do not match the first packing slip
                        if (outsideServiceImport.TCI_OutsideServicePackingSlipId != packingSlipId)
                        {
                            cannotPrint = true;
                        }
                    }
      
                    outsideServiceImport = helper.getNext();
                }
    
                if (cannotPrint)
                {
                    throw error("At least one of the lines you have choses already belongs to a packing slip");
                }
                else
                {
                    super();
                }
                
            }
     
    Second, in the controller, with the help or Martin's code, I first check if there is a packing slip already there.
    If there is, I grab that number
    If not, I create one and fill in some tables with all the information needed for the form.
    class TCI_OutsideServicePackingSlipController extends SrsReportRunController
    {
        TCI_OutsideServicePackingSlipHeader     packingSlipHeader;
        TCI_OutsideServicePackingSlipId         packingSlipId;
        boolean                                 newPackingSlip = false;
        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();
            //controller.createReportData();
        }
    
        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();
    
            if (newPackingSlip)
            {
                ttsBegin;
     
                //packingSlipHeader.TCI_OutsideServicePackingSlipId   = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT()).num();
                packingSlipHeader.TCI_OutsideServicePackingSlipId   = packingSlipId;
                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.TCI_ScanRefNumber                = outsideServiceImport.TCI_ScanRefNumber;
                    packingSlipDetails.LineNumber                       = outsideServiceImport.ResultLineNum;
                    packingSlipDetails.insert();
    
                    outsideServiceImport.TCI_OutsideServicePackingSlipId = packingSlipId;
                    outsideServiceImport.update();
      
                    sequence++;
      
                    outsideServiceImport = helper.getNext();
                }
     
                ttsCommit;
            }
            
        }
    
        protected void prePromptModifyContract()
        {
            super();
    
            TCI_OutsideServiceImportLog importLog = args.record() as TCI_OutsideServiceImportLog;
    
            if (importLog.TCI_OutsideServicePackingSlipId)
            {
                packingSlipId = importLog.TCI_OutsideServicePackingSlipId;
            }
            else
            {
                packingSlipId = NumberSeq::newGetNum(ProdParameters::numRefTCI_OutsideServicePackingSlipEDT()).num();
                newPackingSlip = true;
            }
    
            TCI_OutsideServicePackingSlipContract   contract = this.parmReportContract().parmRdpContract();
            
            contract.parmPackingSlipId(packingSlipId);
            contract.parmDriver('');
            contract.parmNotes('');
        }
    
        public void run()
        {
            this.createReportData();
    
            super();
        }
    
    }
    If there already is a packing slip, that means all the information is already in the Header and Details table, so the DSP class will do the rest and print the report.
     
    Thanks again for all your help Martin

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

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Martin Dráb Profile Picture

Martin Dráb 660 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 549 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 307 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans