Quick Search - Replace Base Search

I need to replace the base search with a quick search in Quote Entry.

The problem is, when I replace the base search for QuoteHed.QuoteNum, it also replaces the quick search for all of the Quote Line Searchs throughout the Quote Entry form. For example, when you copy lines in from a different quote or duplicate the quote.

Is there a way to set these independently? Alternatively, is there an easy enough way to call a quick search from a custom button and just ditch the native button?

1 Like

Check out my post at our blog
http://trigemco.com/call-a-custom-quick-search-2/

1 Like

Thanks Jose. That seems like just what I need but I can’t seem to get the code to work. I added a button and in the event wizard for the click put the code from your post. I get the following errors below. “QuoteSearch” is my Quick Search ID. Any help would be appreciated!

Error: CS0103 - line 58 (640) - The name ‘ˮQuickSearchAdapterˮ’ does not exist in the current context
Error: CS0103 - line 58 (640) - The name ‘ˮShowQuickSearchFormˮ’ does not exist in the current context
Error: CS0103 - line 58 (640) - The name ‘ˮQuoteSearchˮ’ does not exist in the current context

You’ll have to add references to all those, QuickSearchAdapter and thoise are defined in the QuickSearch UI Dll

I added the references and the code compiled fine. When testing, the button launches the appropriate QuickSearch but then for some reason the value the quicksearch returns is not flowing through. It looks like it is trying to return all quotes I have rather than the one selected in the quicksearch. Any idea what would cause this?


Application Error

Exception caught in: System.Data

Error Detail

Message: There is no row at position -1.
Program: System.Data.dll
Method: GetNodeByIndex

Client Stack Trace

at System.Data.RBTree`1.GetNodeByIndex(Int32 userIndex)
at Erp.UI.App.QuoteEntry.Transaction.get_QuoteNum()
at Erp.UI.App.QuoteEntry.Transaction.checkHedItems()
at Erp.UI.App.QuoteEntry.Transaction.resetActionMenus()
at Erp.UI.App.QuoteEntry.Transaction.Transaction_EpiViewChanged(EpiViewChangedArgs args)
at Ice.Lib.Framework.EpiViewChanged.Invoke(EpiViewChangedArgs args)
at Ice.Lib.Framework.EpiTransaction.onViewChanged(EpiDataView CurrentView, EpiDataView LastView)
at Ice.Lib.Framework.EpiTransaction.set_LastView(EpiDataView value)
at Ice.Lib.Framework.EpiTextBox.this_gotFocus(Object sender, EventArgs ea)

What does your code look like?

private void epiButtonC1_Click(object sender, System.EventArgs args)
{
// ** Place Event Handling Code Here **
object ret = ProcessCaller.InvokeAdapterMethod(oTrans.EpiBaseForm, “QuickSearchAdapter”, “ShowQuickSearchForm”, new object {oTrans.EpiBaseForm, “QuoteSearch”, false /* multi-select */, new DataTable() });

// user cancelled
if (ret == null) return;

// If multi-select, ret is an ArrayList whose elements are the selected values

// If single-select, ret is the selected value string

// Perform a native lookup with the returned result
SearchOptions opts = new SearchOptions(SearchMode.AutoSearch);
opts.NamedSearch.WhereClauses.Add(“QuoteNum”, string.Format(“SysRowID=‘{0}’”,ret.ToString()));
opts.DataSetMode = DataSetMode.RowsDataSet;
QuoteAdapter _adapter = (QuoteAdapter)csm.TransAdaptersHT[“oTrans_adapter”];
_adapter.InvokeSearch(opts);
oTrans.NotifyAll();

And where is the error being thrown? Which line is generating the error?

It doesn’t error out when I do the test code in the customization. But when I go to test the customized form, the button now launches the correct quick search. I search for what I want, but it brings back every quote. I did some more clicking around, it seems the error gets prompted when trying to click on the quote form without one of the many returned quotes selected.

I couldn’t get this to work but did find a way that may be easier for some, like me, who aren’t to comfortable messing around with the code and just piece together random lines from posts on here.

Create a new button to use instead of the native button.

On a button click event, set a BPM data field to some number. Then, mimic a click on the native button. Code is below.

Create a Post Processing BPM on QuickSearch GetBaseDefault. Have a condition that checks that the BPM context field is set to the value your button sets it to. If yes, set the result parameter BaseMenuID to your QuickSearch ID.

Then, reset your BPM context field to 0.

private void epiButtonC1_Click(object sender, System.EventArgs args)
{
	// ** Place Event Handling Code Here **
	((EpiDataView)oTrans.EpiDataViews["CallContextBpmData"]).dataView.Table.Rows[0]["Number15"] = "157";
	EpiButton btnKeyField = (EpiButton)csm.GetNativeControlReference("14f4b126-b1cb-4045-8690-614eeda743ca"); 
	btnKeyField.PerformClick();
}

Very interesting. Would you be willing to share the BPM logic you used?

Thanks,
Tanner

Sure thing, do a post processing BPM on Ice.QuickSearch.GetBaseDefault. Then the screenshots of the BPM are below




1 Like

Hello Jose,

Do you have this information somewhere still? This link is sending me to 404.

I appreciate your help!

Way back machine is your friend

Origninal post from trigemco.com
To simply call a custom quick search on a button click you can make a call to the InvokeAdapterMethod of the ProcessCaller library. The Quick Search Adapter implements the ShowQuickSearchForm method which when called will show you and let you execute a given Quick Search. This is the simplest way to call a Quick Search Form on demand, the resulting object will be either the selected key (if single select) or an ArrayList of all the selected values

object ret = ProcessCaller.InvokeAdapterMethod(oTrans.EpiBaseForm, ˮQuickSearchAdapterˮ, ˮShowQuickSearchFormˮ, new object[] {oTrans.EpiBaseForm, ˮYOURQUICKSEARCHNAMEˮ, false /* multi-select */, new DataTable() });
  
// user cancelled
if (ret == null) return;
  
// If multi-select, ret is an ArrayList whose elements are the selected values
  
// If single-select, ret is the selected value string
  
// Perform a native lookup with the returned result
SearchOptions opts = new SearchOptions(SearchMode.AutoSearch);
opts.NamedSearch.WhereClauses.Add("ABCCode", string.Format("SysRowID='{0}'",ret.ToString()));
opts.DataSetMode = DataSetMode.RowsDataSet;
ABCCodeAdapter _adapter = (ABCCodeAdapter)csm.TransAdaptersHT["oTrans_adapter"];
_adapter.InvokeSearch(opts);
oTrans.NotifyAll();

There is a more advanced option which allows you to on the fly pre-filter the results that will be returned from the Quick Search. I do warn you though , this is not for the faint of heart. You will have to add references to your customization for the Adapter, Business Object and UI (User Interface) Dlls related to Quick Search Entry

sender = oTrans.EpiBaseForm;
QuickSearchAdapter _qdA = new QuickSearchAdapter(oTrans);
_qdA.BOConnect();
_qdA.GetByID("","ABCCodeNoA");
QuickSearchDataSet qsds = _qdA.QuickSearchData;
//I have a criteria item in my Quick Search that I  need to pass dynamically.
//so I look through all the criteria items until I find mine and I replace
//the CriteriaValue with the value I want to filter on.
foreach(QuickSearchDataSet.QuickSearchCriteriaRow r in qsds.QuickSearchCriteria)
{
    if(r.FieldName.Equals("ABCCode") && r.CriteriaType.Equals("Constant"))
    {
        r.CriteriaValue = txtFilter.Text;
        break;
    }
}
  
try
{
    using(QuickSearchPanel panel = _qdA.GetQuickSearchPanel(oTrans.EpiBaseForm))
    {
        if(panel !=null)
        {
            using(QuickSearchForm form = new QuickSearchForm(_qdA))
            {
                form.LastQS = "ABCCodeNoA";
                System.Reflection.MethodInfo mi = form.GetType().GetMethod("addQuickSearchPanel",System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                mi.Invoke(form, new object[]{panel});
  
                SearchOptions options = SearchOptions.CreateSearchForm(DataSetMode.ListDataSet);
                options.Sender = sender;
  
                options.SelectMode = SelectMode.SingleSelect;
                form.ShowDialog(new Ice.Lib.Searches.EpiSearchEngine((EpiBaseAdapter)_qdA),options);
                System.Reflection.FieldInfo fi = form.GetType().GetField("selectObject", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                object o= fi.GetValue(form);
                if(o!=null)
                {
  
                    //o is a String containing your returned key
                    //if multi select o is an ArrayList containing all selected keys.
                    if (o == null)
                           return;
                    SearchOptions opts = new SearchOptions(SearchMode.AutoSearch);
                    opts.NamedSearch.WhereClauses.Add("ABCCode", string.Format("SysRowID='{0}'",o.ToString()));
                    opts.DataSetMode = DataSetMode.RowsDataSet;
                    ABCCodeAdapter _adapter = (ABCCodeAdapter)csm.TransAdaptersHT["oTrans_adapter"];
                    _adapter.ClearData();
                    _adapter.InvokeSearch(opts);
                    oTrans.NotifyAll();
                    EpiDataView edvA = oTrans.Factory("ABCCode");
                    edvA.Row=0;
                    edvA.Notify(new EpiNotifyArgs(oTrans, 0, EpiTransaction.NotifyType.Initialize));
  
                }
            }
        }
    }
}
catch(Exception ex)
{
}

Note the above was posted in like 2016 most of it still applies but handle with care.

2 Likes

Wow, you’re old! :grin:

1 Like

Specially since I’ve been locked in home for 3 months… Body is starting to atrophy now everything hurts and I can barely walk
When this is all over they are going to have to wheel me out.

2 Likes

Using the advanced option, I found that the CriteriaValue can be updated successfully, but either the criteria at the form or the result set cannot filter the record using the CriteriaValue.