Useuf_filter()(its code is provided below) instead of the DW's built-in functionsSetFilter()andFilter().
Create that function in the ancestor DW of your application.
That solution:
1. Decreases the number of code lines in the calling script - 1 instead of 2 (or one more if GroupCalc() required, or even one more if RowCount() is called just after filtering). So, the fragment
2. Alerts if the passed expression is NULL (that can happen when the expression is built dynamically and a variable with NULL is concatenated). If an EMPTY STRING is passed it's NOT interpreted as error (it's used to remove filtering).
3. If the search expression is incorrect, displays a programmer-friendly message which: A. Displays the incorrect expression. B. Displays the DW's DataObject and suggests to check if all the mentioned fields exist in it.
Here is the source of that function (it utilizes f_throw() to throw an exception of type n_ex - read here for details):
/********************************************************************************************************************** Dscr: Filters the DW using passed expression (see http://code.intfast.ca/viewtopic.php?f=2&t=75). *********************************************************************************************************************** Arg: as_new_filter *********************************************************************************************************************** Ret: long (number of rows in Primary! buffer after filtering) *********************************************************************************************************************** Developer: Michael Zuskin - http://linkedin.com/in/zuskin | http://code.intfast.ca/ **********************************************************************************************************************/ int li_rc
if IsNull(as_new_filter) then f_throw(PopulateError(1, "Filter exression is NULL.")) // f_throw(): http://code.intfast.ca/viewtopic.php?f=2&t=1
li_rc = this.SetFilter(as_new_filter) if li_rc <> 1 then f_throw(PopulateError(2, "this.SetFilter() failed.~r~n~r~nFilter Expression:~r~n" + as_new_filter + & "~r~n~r~nCheck if all fields, mentioned in expression, exist in DataObject '" + this.DataObject + "'.")) li_rc = this.Filter() if li_rc <> 1 then f_throw(PopulateError(3, "this.Filter() failed.~r~n~r~nFilter Expression:~r~n" + as_new_filter + & "~r~n~r~nCheck if all fields, mentioned in expression, exist in DataObject '" + this.DataObject + "'."))
this.GroupCalc()
return this.RowCount()
uf_append_filter()
If the task is to APPEND a filter (rather than to REPLACE the existing one) then create uf_append_filter() in your ancestor DW:
/********************************************************************************************************************** Dscr: Works as uf_filter() but new filter is added to existing instead replacing it. *********************************************************************************************************************** Arg: as_filter_to_append *********************************************************************************************************************** Ret: long (number of rows in Primary! buffer after filtering) *********************************************************************************************************************** Developer: Michael Zuskin - http://linkedin.com/in/zuskin | http://code.intfast.ca/ **********************************************************************************************************************/ string ls_existing_filter string ls_new_filter
ls_existing_filter = this.object.datawindow.table.filter choose case ls_existing_filter case "?", "!" ls_new_filter = as_filter_to_append case else ls_new_filter = "(" + ls_existing_filter + ") AND (" + as_filter_to_append + ")" end choose
return uf_filter(ls_new_filter)
Of course, both the given functions can also be added to the ancestor DataStore.