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
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];
}
}
}
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.
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.
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.
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.
Here you can see that it changes and you change rows.
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.