Creating a Part Search for BAQ

Ok, so where I’m at now is that originally clicking the button yelled at me that there was no quick search with that ID. I created a quick search which was basically a baq that listed all parts, and the quick search would search off those parts.

Reloaded Epicor, but now when I click the button, nothing happens at all.

// **************************************************
// Custom code for MainController
// Created: 1/13/2023 8:41:22 AM
// **************************************************
using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using System.Collections;
using Ice.BO;
using Ice.UI;
using Ice.Lib;
using Ice.Adapters;
using Ice.Lib.Customization;
using Ice.Lib.ExtendedProps;
using Ice.Lib.Framework;
using Ice.Lib.Searches;
using Ice.UI.FormFunctions;

public class Script
{
	// ** Wizard Insert Location - Do Not Remove 'Begin/End Wizard Added Module Level Variables' Comments! **
	// Begin Wizard Added Module Level Variables **

	// End Wizard Added Module Level Variables **

	// Add Custom Module Level Variables Here **

	public void InitializeCustomCode()
	{
		// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Variable Initialization' lines **
		// Begin Wizard Added Variable Initialization

		// End Wizard Added Variable Initialization

		// Begin Wizard Added Custom Method Calls

		this.PartSearch.Click += new System.EventHandler(this.PartSearch_Click);
		// End Wizard Added Custom Method Calls
	}

	public void DestroyCustomCode()
	{
		// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Object Disposal' lines **
		// Begin Wizard Added Object Disposal

		this.PartSearch.Click -= new System.EventHandler(this.PartSearch_Click);
		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal

		// End Custom Code Disposal
	}

	private void PartSearch_Click(object sender, System.EventArgs args)
	{
					object ret = ProcessCaller.InvokeAdapterMethod
							(oTrans.EpiBaseForm, "QuickSearchAdapter", "ShowQuickSearchForm", new object[] 
							{oTrans.EpiBaseForm, "PartSearch", true/* multi-select */, new DataTable() });
				  
				// user cancelled
				if (ret == null) return;			
				ArrayList list = (ArrayList)ret;
	}
}








I’m sure there’s things I’m missing here but I’m a total noob at customization

Did you test your quick search? You can test it in the window where you make it.

Ah yes thanks I tested it and figured out I wasn’t setting it up as a criteria prompt. I now have the button set to open the search and it allows me to filter out parts. Now, next steps are that I need it to return the selected part to the text box, and then use that text box as my BAQ “parameter”. I want to use this instead of using a parameter field, but I still need to keep some form of criteria within my BAQ right? Right now it is set to PartNum BEGINS WITH “parameter”. Not sure how I need to change that so it takes in the value in the textbox instead. I could possibly remove the parameter, in which case it would return all parts, and filter by tracker view, but that would be insanely slow.

Ignore the Key already exists This is a bug but your changes will work fine.

The ret is a variable which has been used else where in some code. It may not apply to your situation.

You must always remember when copying and pasting code from the threads it may not work first time. It’s to give you an understanding of how to build and develop your own solution.

I’m happy to assist you further over a teams call if you need any other support.

Aarong thanks for the continued help, and I may take you up on that teams call. I am still trying to get my head around epicor, and my programming knowledge isnt the greatest either. I will reply next week with any progress and if I need more help.

Since you are just on a dashboard, that’s exactly what you want to do, remove the parameter.
Use only the tracker. Trackers DO send a where clause in the query. The filtering is not
done locally. It will not be insanely slow, unless you are doing something very complex with
your parameter.

Reference:


So now let’s say you do that.
You now have a tracker field called “Part Number”.
Set it to “StartsWith”, and just use the first part of the parameter.
Or “Matches(or is it Contains?)” and you can use it like this:
“mypartnum” matches “SomeTextmypartnumSomeText”
“%mypartnum%” matches “SomeTextmypartnumSomeText”
“%mypartnum” matches “SomeTextmypartnum” (Ends With)
“mypartnum%” matches “mypartnumSomeText” (Starts With)

To get your value from the part search, you will need to get a reference
to your textbox from the tracker.

Add a TextBox variable inside the Script class like so:
Get a reference to the tracker textbox in the Initialize Custom Code Method
In the PartSearch Click Event, populate your textbox.

using System.Collections;

public class Script
{
    // Add Custom Module Level Variables Here **

    //TextBox Variable
    EpiTextBox myPartSearchTextBoxIsSoFancy = null;

    public void InitializeCustomCode()
    {
        this.PartSearch.Click += new System.EventHandler(this.PartSearch_Click);

        //Get Reference from PartNum TextBox on Tracker
        myPartSearchTextBoxIsSoFancy = (EpiTextBox)csm.GetNativeControlReference("theGUIDofYourTextBox"); //Get GUID from properties on form
    }

    public void DestroyCustomCode()
    {
        this.PartSearch.Click -= new System.EventHandler(this.PartSearch_Click);
    }

    private void PartSearch_Click(object sender, System.EventArgs args)
    {
        //Changed multiselect to false
        object ret = ProcessCaller.InvokeAdapterMethod
            (oTrans.EpiBaseForm, "QuickSearchAdapter", "ShowQuickSearchForm", new object[] 
            {oTrans.EpiBaseForm, "PartSearch", false/* multi-select */, new DataTable() });

        // user cancelled
        if (ret == null) return; //This is a short circuit. If no value was returned, exit method.			
        ArrayList list = (ArrayList)ret;

        //Not sure on syntax, don't use ArrayList often
        if(list.Count() > 0)
        {
            myPartSearchTextBoxIsSoFancy.Text = list[0];
        }
    }
}

Press refresh and you’re done.

This makes since for the most part. My BAQ is recursive, so hopefully that won’t mess it up too much.

I’m having a bit of issue getting the code working. I kind of know the gist of whats wrong I’m just not sure how to fix it. Originally I was getting a method error on the arraylist, which I fixed by removing the () after count.

This is the error I am getting now. I’m just not really sure how to set that up.

If you have multiselect set to false, it ret is a string, not an ArrayList

object ret = ProcessCaller.InvokeAdapterMethod
    (oTrans.EpiBaseForm, "QuickSearchAdapter", "ShowQuickSearchForm", new object[] 
    {oTrans.EpiBaseForm, "PartSearch", false/* multi-select */, new DataTable() });


// user cancelled
if (ret == null) return; //This is a short circuit. If no value was returned, exit method.			

myPartSearchTextBoxIsSoFancy.Text = string(ret)	;

Ok, so I was able to get that working. I just used (String)ret instead in case anyones wondering.

So I have my button working with the textbox now. I went in and removed my query parameter and the definition parameter to go with it. However, when I use my dashboard now, even with the part number in there, it freezes upon refresh. Is this because it is still searching through every part in the database? It actually times out the refresh after a while.

And it doesnt seem like there is an easy way to pass the tracker view as a BAQ parameter?

What textbox? The filter for partnum?

Did you redeploy your dashboard?

No need anymore.

We just need to figure out your dashboard first.

Run your dashboard without customization and make sure your filter on partnum works as expected.
After it does, the rest will flow through fine.

Yes, with a recursive query, you will actually need the parameter or it’s going to do what you are witnessing. A where clause only gets you so far.

The only way that they have it set up right now to pass a parameter into a dashboard without a popup is a publish and subscribe. Where you have a feeder grid publishing the value for the parameter, and then a “filter” (not tracker, filter in the properties) on the grid that needs the parameter.

I see that now, as no matter what I seem to do it still times out when I remove my parameter.

Would you be able to give me some information on how to set that up? I’m mostly a newb when it comes to stuff like this.

You hit the magic combo where you need it ! :cry:

Sounds about right with my luck. This whole project has been a fun experience lol :lying_face:

We should be able to use the same approach then, just one level up.
Have the filter populate a matching grid of parts, then publish that partnum for the lower grid to consume.

So on your feeder query, you make a list of what you will need for the parameters. Then use properties, and check on the field that you want to publish.

On the receiver query, go the the parameters tab, and select the parameter, and make it equal to the field that you published.

Here you can see that it changes and you change rows.
parameterrefresh

So this isn’t ideal, as the query probably takes a little bit in your case, and it will refresh everytime you click on a different row, but it gets rid of the popup. I’m not really sure which is better.

When you’re new, it’s all about a lack of knowledge. I still feel new.

It shouldn’t be too hard to combine @aarong’s & @Banderson’s approach together.
It won’t be too hard to adapt

Yea, I don’t think this will work, as it takes out all my functionality in searching for multiple parts, and the refresh would be highly annoying.

I think that’ll work nicely. He just needs to use the partsearch bit to filter a simple query of parts, and
then feed the lower query.