Epicor: How to Call A BAQ From Code Within A Customization

BAQs are such a fantastic building block for so many things within Epicor. You have probably used them to build dashboards and quick searches, but in this article, I wanted to describe how you can run them via code within an embedded customization. I use this technique all of the time - most recently, I had a customer that wanted to have a selectable grid of shipment notification recipients listed at order entry formed by pulling together all of the customer contacts having a specific set of criteria. While I might have been able to get creative with foreign key views to pull that together, a simple BAQ gets the job done clean and fast.

As you might imagine, the process here is going to start by creating a BAQ. There are no special rules here - you can use any type of BAQ, including those that have parameters.

Here is a BAQ that has a parameter prompting for the CustNum.

Here is a BAQ that has a parameter prompting for the CustNum.

In order to use this BAQ within a customization we need to first add an assembly reference using Tools / Assembly Reference Manager:

Screenshot of the Epicor customization tools dialog - GingerHelp

From here click the ‘Custom Assemblies’ folder and then press the ‘Add Custom Reference’ button:

Screenshot of the “Custom Assembly Reference Manager” screen in a tutorial about how Epicor can call a BAQ from code - GingerHelp

Now change the type drop-down to all and select the DLL file Ice.Contracts.BO.DynamicQuery.DLL (be careful to pick the DLL and not the XML file with the same name):

Screenshot of selecting the DLL file - GingerHelp

Now we are ready to add our code. We start off with some boilerplate stuff:

Screenshot of adding code that will call an Epicor BAQ from a customization - GingerHelp

Breaking those down just a bit:

  • The first line we are creating an object called dynamicQueryAdapter of the type DynamicQueryAdapter at the script level - this means we will be able to use it anywhere within the customization.

  • The second two lines are nested within the InitializeCustomCode function and this is where we are actually wiring up dynamicQueryAdapter to actually work. Note that on the line that says:

dynamicQueryAdapter = new DynamicQueryAdapter(UD01Form);

The bit in the parenthesis needs to be the name of the form as obtained from the top of the tree view:

Screenshot of the Epicor Customization Tools Dialog - GingerHelp
  • The last line is just disposing the dynamicQueryAdapter object so we don’t end up with a memory leak.

Now that we have the basics in place we are ready to actually call out to our BAQ. Ultimately it is going to depend on your use case exactly where you wedge this next bit of code. For my customer that was wanting to pull in shipment notification recipients we attached this to the EpiViewNotification for OrderHed. For the purpose of this article I am just attaching the code to the form load event:

    private void UD01Form_Load(object sender, EventArgs args)
    {
        int myCustNum = 414;
        QueryExecutionDataSet queryExecutionDataSet = new QueryExecutionDataSet();
        queryExecutionDataSet.Tables["ExecutionParameter"].Rows
            .Add("CustNum", myCustNum, "int", false, null, "A");
        dynamicQueryAdapter.ExecuteByID("CustomerContacts", queryExecutionDataSet);
        epiUltraGridC1.DataSource = dynamicQueryAdapter.QueryResults.Tables["Results"];
    }

Breaking this down a bit:

  • We start with setting a variable for a static customer number we will later use to fill in the parameter on our BAQ:

    int myCustNum = 414;
  • Next we initialize a new QueryExecutionDataSet - an object that holds things like parameters for our BAQ:

    QueryExecutionDataSet queryExecutionDataSet = new QueryExecutionDataSet();
  • Now if you have any parameters you are going to use this next line paying special attention to those first three arguments after Add - they refer to the name of the parameter, the value you want to pass in, and the type of parameter. You will repeat this line for each parameter your BAQ calls for:

    queryExecutionDataSet.Tables["ExecutionParameter"].Rows.Add("CustNum", myCustNum,"int", false, null, "A");
  • Now we execute our BAQ using ExecuteByID. The first parameter is the name of our BAQ and the second is the queryExecutionDataSet we just created:

    dynamicQueryAdapter.ExecuteByID("CustomerContacts", queryExecutionDataSet);
  • At this point the results of the BAQ will be stored at dynamicQueryAdapter.QueryResults.Tables["Results"]. You can do whatever you want with them at this point including binding them to controls or even creating brand new EpiDataViews.

Hope this has been helpful!