Excel Parameter To Filter Epicor BAQ

@Kpearson Yes, you got the feed pull there in your image. Looks like the Power Query Editor UI and that is what you will need.

  1. Add the p function I provided above in the Editor there. Optional: Add the t and dt functions as well.
  2. Create a named cell above your table or somewhere else on the sheet utilizing that query so it makes sense where the viewer provides it.
  3. Either COPY current query and edit to new table.
  4. Edit the Query feed to be like the code below

You need to have the BAQ copied to a new one with the parameter you would like if you want to simplify it OR you can use the power M query transform to use parameter and filter your data set with is like this:

Add the Table.SelectColumns method around your OData.Feed like this:

 = Table.SelectRows(OData.Feed(%Your SERVER URL REST CALL% or p("My REST Feed URL in a named CELL")), each ([JobHead_JobNum] = p("Named Cell Parameter Name for Job Head")))

I do the similar above in the advanced editor and I provided to correct code for that editor in my post above. The p function code I provided will dynamically use a named cell/range and provide the VALUE of that CELL/RANGE within a Power M query (or even other Excel functions which I do not show/explain here). Much easier than hopping back to this Editor interface when a parameter/filter value needs to change.

***Assumption: Your table column name is “JobHead_JobNum”
image

CAVEAT: This is not the best or most efficient way to do this! Better would be to duplicate your original BAQ to a new query with parameter to filter the result set during the OData.Feed refresh, or since you already have the data filter the table set using the dt function and a transform using something like mine 1st and possible yours 2nd/3rd:

/* Copied from MINE Advanced Editor with additional transform to tweak column data type so it comes out more excel friendly */
let
    Source = Table.SelectRows( Table.TransformColumnTypes(dt("TrailerCostingData"),{{"Site CostID", Int64.Type}, {"Product Group", type text}, {"Trailer", type text}, {"Trailer Description", type text}, {"Option Type", type text}, {"Option PartNum", type text}, {"Config Desc", type text}, {"Option Description", type text}, {"Is Default Option", type logical}, {"Inc Cost", type number}, {"Item Total Cost", type number}, {"Trailer Model", type text}}), each [Product Group]=p("SelectedCategory"))
in
    Source

/* Example of shorthand for yours */
=Table.SelectRows(dt("Named Table Range for your Material Query"), each ([JobHead_JobNum] = p("Named Cell Parameter Name for Job Head"))) 

/* Advanced Editor result of shorthand above */
let
    Source = Table.SelectRows(dt("Named Table Range for your Material Query"), each ([JobHead_JobNum] = p("Named Cell Parameter Name for Job Head"))) 
in
    Source

The dt function provides linking back to already available named tables in Excel workbook and using them in a new query or a subset of data like I have in mine.

Multiple Dynamic lists combo boxes provide filtering and trigger VBA macros to refresh the linked data set.

'VBA Code on worksheet used named ranges as triggers to update (Power M Query -> Table) Dynamic Lists on hidden tab used as data validation list for named cells providing data/trigger to build the Quote vs Costing worksheet info

Private Sub Worksheet_Change(ByVal Target As Range)
' Detect cell change and refresh relevant table(s) 
    Dim oldText As String
    Dim tbl As Variant
    Select Case Target.Address
        Case Range("SelectedModel").Address
            ' Model Changed
            oldText = Range("StatusDisplay").Text
            PricingTool.Unprotect
            Range("StatusDisplay").Value = "One moment updating Trailer Options . . ."
            Application.StatusBar = Range("StatusDisplay").Value
            ActiveWorkbook.Connections("Query - TrailerOptions").Refresh
            PricingTool.Unprotect
            Range("SelectedModel").Select
            Range("StatusDisplay").Value = oldText
            Range("ModelTrailerConfig").ClearContents
            Set tbl = PricingTool.ListObjects("TrailerOptions").TableObject.ListObject
            Application.EnableEvents = False
            If tbl.ListRows.Count > 0 Then
                tbl.DataBodyRange.Sort _
                      Header:=xlYes _
                    , Key1:=tbl.ListColumns("Option/Standard").DataBodyRange _
                    , Order1:=xlDescending _
                    , Key2:=tbl.ListColumns("Option Type").DataBodyRange _
                    , Order2:=xlAscending
                Application.EnableEvents = True
            End If
            PricingTool.Protect
        Case Range("SelectedCategory").Address
            ' Category Changed
            oldText = Range("StatusDisplay").Text
            PricingTool.Unprotect
            Range("StatusDisplay").Value = "One moment updating Trailer Model dropdown . . ."
            Application.StatusBar = Range("StatusDisplay").Value
            Range("ModelTrailerConfig").ClearContents
            Range("SelectedModel").ClearContents
            ActiveWorkbook.Connections("Query - dlSelectedProductGroupTrailers").Refresh ' This is to refresh a dynamic list attached to the cell validation
            Range("SelectedModel").Select
            PricingTool.Unprotect
            Range("StatusDisplay").Value = oldText
            PricingTool.Protect
    End Select
    Application.StatusBar = ""
    Application.EnableEvents = True
    Set tbl = Nothing
End Sub
' VBA module code to refresh ALL data tables
Public Sub EzTrailersDataRefreshAll()
    Dim oldText, statusText As String
    statusText = "One moment updating datasets using data below. . ."
    PricingTool.Select
    oldText = PricingTool.Range("StatusDisplay").Text
    PricingTool.Range("StatusDisplay").Value = statusText
    Application.StatusBar = statusText
    EzTrailers.RefreshAll
    Application.StatusBar = ""
    PricingTool.Range("StatusDisplay").Value = oldText
End Sub


'Callback for btnEzRefreshData onAction
Public Sub aRefreshData(control As IRibbonControl)
    PricingTool.Unprotect
    EzTrailersDataRefreshAll
    PricingTool.Protect
End Sub

There is a lot for me to unpack here, but I really appreciate the in-depth explanation! I will try to find some time to work through this either today or tomorrow and report back with any questions.

Can you upload the workbook you are using as an example?

I will try and put a sample one together for you as time permits (hopefully today).

Find relevant files & info here:

The sample workbook(s) will have dynamic queries setup to access an Epicor BAQ once the relevant details are filled in the workbook and you refresh the data.

Sample BAQ zzzEUH can be created with the provided screenshots and sample SQL from the BAQ it has a parameter to PRE filter result set if you want that route or you can use the second type and use the full dataset with an in-memory query against the table in the worksheet.

You should find everything you need to put together with what you already have. If not please let me know.

Check out the sample files I created.

Also, found out how to have Excel do Power M Query with Epicor OData v2 including API Key etc this past weekend. I try creating a sample file for that as well including an Epicor Login Form on open. I have not tried with Tokens, SSO or AD Auth just regular Base64 Basic Auth with API Key.

All,
Thanks for all of the help on this. I think I have arrived at a pretty eloquent way of doing this. I take little to no credit for this solution, but just re-explaining it in terms that made sense to me.

Step one was editing the BAQ in epicor to have a ‘filter’ for the field I wanted. I created the parameter ‘XLJOBNUM’ and tied it to the JobHead.JobNum column in the BAQ.

Next, I made the named range called “EPICOR_JOB” which contained the job number field I wanted filtered.

Next, I loaded the BAQ using the simple URL OData pull in excel. In my case, it was important to put a filter so that only the ‘active’ jobs got pulled in, otherwise it tried to pull ALL the materials in ALL jobs in our system.

Finally, I simply added the logic for the parameter I made in Epicor to the URL in powerquery OData feed:

= OData.Feed(" EPICORURLHERE ?XLJobNum=" & Excel.CurrentWorkbook(){[Name=“EPICOR_JOB”]}[Content]{0}[Column1] & “&$filter=null&$format=json&$top=100”, null, [Implementation=“2.0”])

The above goes into the ‘command line’ of power query editor. When you pull the query it should filter by your desired parameter!

Again, I am sure this was explained to me already, but doing it yourself is the best way of learning I suppose.

THANKS AGAIN FOR ALL THE HELP!

Yes, I gave you the Power M Query for grabbing your parameter from a named range cell in post 2 that you are using in your solution along with how to use in the Power M query OData.Feed. Then I also provided a sample workbook with detailed directions per your request.

Congrats on finding the solution provided to you for yourself. :slight_smile:

@CSmith - Who do you think you are fooling by blurring out your Bookmarks bar…We all see what you are doin’ over there :rofl:

@jhecker LOL Busted :smiley: Only one of the 8 profiles though :stuck_out_tongue:

OMG LOL I missed the ref there and not XXXHUB, but GoToMeeting lol :stuck_out_tongue: Guess you really only busted yourself @jhecker :smiling_imp:

Should have inspected your image edit much closer!