Add Fields to Epicor Custom Grid

Hi smart people,
has any one done similar code in ERP10, this seems to work for Epicor previous versions, as i tried it, it is error out at BOReader, i have tried most of suggestion on this post, but no luck, could anyone help please, i am trying to add PORel.NeedByDate to the Demand Grid in Job Manager ?

Continuing the discussion from Adding a Field to A Grid:

1 Like

I haven’t looked at the grid and form you’re asking about, but in general if there’s a field not in a grid that you want to see, there are two main options and one probably over-complex one, depending on the particular case.

Is the field you want actually within the EpiDataView the grid is bound to? If so, option one is very simple, and you can make it visible in the grid column collection.

If the field is NOT in the EpiDataView, then it might be easiest to swap out the grid entirely for one based on a BAQView that DOES show what you want. That isn’t trivial, but there are good guides to it in posts here, and @josecgomez is the expert.

Last resort if you are comfortable with DataTables and getting deeper into the code is manually adding a column to the underlying DataTable, which looks like is the general approach in the code you’ve posted. That is possible but seems overkill in most circumstances.

the 1st option is obvious my friend, the filed i need is not within the EpiDataView, and i have done the 2nd option in other cases but on this one i can not replace the Custom BAQ because it is functional to many tracker buttons, this left me with 3rd option which is code my field to appear within the custom grid including call it’s value from the Database.

Sorry, I don’t mean to offend you! I know I get stuck looking for complicated solutions quite often when a simpler one would do.

Given that you’ve already ruled out the simpler options then yes, you need to get quite manual here. Having a data call for every row in the grid feels a bit extreme to me, though. If that is what you want to do then I think the E10 way is to use a dedicated adapter to do so. PORelSearch seems like it would do the job, and you would essentially swap out the code that uses boReader for it.

Personally I would prefer an approach that retrieved the relevant data once when the EpiDataView is updated, and added it to the DataTable then, I think. But you know your needs best!

no problem at all, i am just explaining my case, my Background is Manufacturing Engineering, the last coding language i worked on before Start customizing Epicor was Fortran and Pascal, C# is the first Object-Oriented Programming language i use, i found it very powerful dealing with database with loads of libraries or what we used to call ‘subroutines’, so long story short i have not got a wide knowledge of using such commands, could you please elaborate a bit more, it will be very useful if you give an example of what you mean here.
thanks in advance

1 Like

For me, Epicor is a whole other world in itself and not much experience of mine elsewhere has been much use to me! But I’m learning.

Here’s an adapter call that I’m using somewhere. I think you’ll see it’s similar to the BOReader parts of the code you’ve already posted and could be adjusted to work the same way. As I say, it feels a bit strange to me to be doing this for every row of a grid, but alternative solutions would need a whole lot more re-engineering.

Erp.Adapters.ProdCalAdapter prodCal = new Erp.Adapters.ProdCalAdapter(oTrans);
prodCal.BOConnect();
SearchOptions opts = new SearchOptions(SearchMode.AutoSearch);
opts.PreLoadSearchFilter = @"CalendarID = ""xxx""";
opts.NamedSearch.WhereClauses["ProdCalDay"] = "ModifiedDay = '" + shipdate.ToString("yyyy-MM-dd") + "'";
bool morePages;
Erp.BO.ProdCalDataSet dsProdCal = (Erp.BO.ProdCalDataSet)prodCal.GetRows(opts, out morePages);

may be @josecgomez ‘the great’ can help updating this code :):grin:

This should get you what you are looking for.

// **************************************************
// Custom code for JobManagerForm
// Created: 9/28/2018 7:09:07 AM
// **************************************************
using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Erp.Adapters;
using Erp.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;
using Ice.Contracts;
using Ice.Core;
using Ice.Proxy.Lib; // BOReader

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 **Epicor.Mfg.UI.FrameWork.EpiUltraGrid myGrid;
	EpiUltraGrid myGrid;
	private BOReaderImpl _boReader; 

	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

		// End Wizard Added Custom Method Calls
		myGrid = (EpiUltraGrid)csm.GetNativeControlReference("ba0809c1-ec83-4e27-8f32-38256184f797");
		myGrid.DisplayLayout.Bands[0].Columns.Add("VendorNumVendorID","Supplier ID");
		myGrid.InitializeRow += new Infragistics.Win.UltraWinGrid.InitializeRowEventHandler(grdMatLst_InitializeRow);
		BOReaderImpl _boReader = WCFServiceSupport.CreateImpl<BOReaderImpl>((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase<Ice.Contracts.BOReaderSvcContract>.UriPath);
	}

	private void grdMatLst_InitializeRow(object sender, Infragistics.Win.UltraWinGrid.InitializeRowEventArgs e)
	{
		if(!String.IsNullOrEmpty(e.Row.Cells["VendorNumVendorID"].Value.ToString()))
		{
		DataSet ds = _boReader.GetRows("PartTran","VendorNumVendorID='" +e.Row.Cells["VendorNumVendorID"].Value.ToString()+ "'","VendorNumVendorID");
		if(ds.Tables[0].Rows.Count > 0 )
		e.Row.Cells["VendorNumVendorID"].Value = ds.Tables[0].Rows[0]["VendorNumVendorID"];
		}
	}

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

		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal

		// End Custom Code Disposal
		myGrid.InitializeRow += new Infragistics.Win.UltraWinGrid.InitializeRowEventHandler(grdMatLst_InitializeRow);
		_boReader = null;
	}
}

Thanks Dan,
i have tried these libraries (highlighted) and without adding any other code lines it is error out:

Did you add this reference?

image

could not find it

Hit this drop-down to look for “All Files”
image

BOReader not POReader :slight_smile:

Many Thanks Dan, i found and added the BOReader :):sweat_smile:and The Core, code compiled fine, then start add my custom code and it is error out at
private BOReaderImpl _boReader;
i am testing my code line by line, do i need to add the whole modification and test ?

Are you sure you grabbed the DLL from the proper folder (version)?

these the two assembly DLL i added so far

You can remove Core and add this for 10.1.400 and the ResourceSchedForm. Remove using for Core as well.
image

compiled failed when removing Core, so i have added it back and added what you suggested as well ‘Epicor.ServiceModel’, i have added my custom lines, the whole code complied fine now, however :):tired_face: my added field does not show any value

and this my code, (i am testing this code on Scheduling Resource Tracker Screen as i have manged to add the field but failed to bind it to Epicor DataBase)
// **************************************************
// Custom code for ResourceSchedForm
// Created: 27/09/2018 13:43:48
// **************************************************
using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Erp.Adapters;
using Erp.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;
using Ice.Contracts;
using Ice.Core;
using Ice.Proxy.Lib;

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 **
Ice.Lib.Framework.EpiUltraGrid myGrid;
private BOReaderImpl _boReader;

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
// End Wizard Added Custom Method Calls

myGrid = (Ice.Lib.Framework.EpiUltraGrid)csm.GetNativeControlReference("87f88dc8-1b94-4324-ba83-583a2af5cbb9");
myGrid.DisplayLayout.Bands[0].Columns.Add("JobReleased", "Job Released");
myGrid.InitializeRow += new Infragistics.Win.UltraWinGrid.InitializeRowEventHandler(grdList_InitializeRow);
BOReaderImpl _boReader = WCFServiceSupport.CreateImpl<BOReaderImpl>((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase<Ice.Contracts.BOReaderSvcContract>.UriPath);
}

private void grdList_InitializeRow(object sender, Infragistics.Win.UltraWinGrid.InitializeRowEventArgs e)
{
	if (!String.IsNullOrEmpty(e.Row.Cells["JobNum"].Value.ToString()))
	{
	EpiDataView edv = oTrans.Factory("JobHead");
	DataSet ds = _boReader.GetRows("JobHead","JobNum='" +e.Row.Cells["JobNum"].Value.ToString()+ "'","JobNum");
	if(ds.Tables[0].Rows.Count > 0 )
	e.Row.Cells["JobNum"].Value = ds.Tables[0].Rows[0]["JobNum"];
	}
}

public void DestroyCustomCode()
{
// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Object Disposal' lines **
// Begin Wizard Added Object Disposal
// End Wizard Added Object Disposal
// Begin Custom Code Disposal
// End Custom Code Disposal
myGrid.InitializeRow -= new Infragistics.Win.UltraWinGrid.InitializeRowEventHandler(grdList_InitializeRow);
_boReader = null;
}

}

I assumed some of the code was good and just got it to compile. I can take another look to make sure it is functional