Wednesday, January 18, 2012

Run-time add/remove datasource to filter results

Sometimes I add a Combobox above a Grid to give the user several 'canned' filters.
In some cases I would like to filter on a table other than the one displayed in the grid.  For example, I might want to filter a grid of CustTable records based on related Address table records.

If you want the filter to be active all the time, you can just add the filtering datasource to your form.  But if you only want the filter to be active some of the time, you need to be able to dynamically (run-time) add and remove the datasource that does the filtering.

The code below shows how to dynamically add and remove (actually disable) a child datasource for filtering purposes.

public void executeQuery() //on form datasource "formDatasourceName"
{
    QueryBuildDataSource    qbds;
    ;
 
    if(this.query().dataSourceName("formDatasourceName").childDataSourceCount() == 1)
    {
        //if the filter datasource has been added in the past (prior run of executeQuery), disable it
        this.query().dataSourceName("formDatasourceName").childDataSourceNo(1).enabled(false);
    }

    if (booleanFilterResults)
    {
        //this creates a "hidden" exists join to act as a filter
        if (this.query().dataSourceName("formDatasourceName").childDataSourceCount() == 1)
        {
            //if the filter datasource
            qbds = this.query().dataSourceName("formDatasourceName").childDataSourceNo(1);
            qbds.enabled(true);
        }
        else
        {
            qbds = this.query().dataSourceName("formDatasourceName").addDataSource(tablenum(filterTableName));
        }

        qbds.clearRanges();

        qbds.relations(true);  //or use .addLink...
        qbds.joinMode(JoinMode::ExistsJoin);
        qbds.fetchMode(queryfetchmode::One2One);
        
        //filter on some value, in this case a comboBox selection.  
        //Of course you'll call formDatasourceName.executeQuery() in comboBoxFilter modified method
        qbds.addRange(fieldnum(filterTableName, ItemId)).value(queryValue(comboBoxFilter.valueStr()));
    }

    super();
}

7 comments:

  1. Hi! Thank you for this. I have been trying to figure this out for many days.

    ReplyDelete
  2. Hi ,

    How to do that for multiple data sources . Means i have parent data sources in the form , but a combo box filter are form 3rd child table . Please explain how to extend above code for on parent and two child data sources.

    Thank you
    Himanshu Kotnala

    ReplyDelete
    Replies
    1. Hi Himanshu,

      You should be able to change code that says:
      "childDataSourceCount() == 1" to "childDataSourceCount() == 2"
      and
      "childDataSourceNo(1)" to "childDataSourceNo(2)".

      There are 4 total places where the code needs to change.

      Hope that helps,
      Nate

      Delete
  3. In DAX 2012 if you want to filter grid, you just need to add combobox and chose or write your own filter function in SysQueryRangeUtill class and after that you'll be able to use it.

    ReplyDelete
  4. Thanks for your helpful post.I'm facing same issue of your topic. I would like to add and remove range & join in datasource.
    I tried my best with your guide, but it didn't work. I post my code into this blog, please show me where i am wrong? Many thanks for your support.
    IF(!chkViewAll.value())
    {
    qsp = qss.addDataSource(tableNum(SKVNPermissionSKVN));
    qsp.relations(false);
    qsp.joinMode(JoinMode::InnerJoin);

    qsp.addRange(fieldNum(SKVNSampleTableSKVN, CREATEDBY)).value(
    strFmt('((%1.CREATEDBY == %3.UserID) && ((%3.USERID == "%2") || (%3.CHECKEDBY == "%2") || (%3.ApprovedBy == "%2")))',
    qss.name(),
    queryValue(CurUserID()),
    qsp.name()
    ));

    //info(qss.toString());
    //info(qsp.toString());
    //}
    }
    else
    {
    qss.clearRanges();
    qss.clearDynalinks();
    qss.clearLinks();

    SKVNSampleTableSKVN_ds.init();
    SKVNSampleTableSKVN_ds.refresh();
    SKVNSampleTableSKVN_ds.reread();

    info(qss.toString());
    }

    ReplyDelete
  5. Thanks for your help, very helpful!

    ReplyDelete