Script Editor - MES Customization Calculation


(Chai Chang) #1

In the “Start Production Activity” for MES, I would like to add additional fields for informational requirement from my users. I did a foreign key link to JobOper to get the ProductionQty and QtyCompleted. I had both of these displayed in the textbox. My user asked if I can take these 2 texbox and calculate the difference to tell them the remaining balance for each operation.

I thought since the 2 textboxes are strings, i convert them into double and then do the math. However, when I did that I get the following error.

Any ideas how I can take these 2 textboxes and do calculation?


(Chai Chang) #2

Never mind. I caught where I placed the variable. I moved it down to InitializeCustomcode and it’s fine now.


(Chai Chang) #3

I do have a question though. Does anyone know which Custom Object Explorer I would need to have it do it’s calculation after it pull in the Production Qty and Completed Qty to get my remaining balance?

I just want to take 2 texboxes that pulled information from database and calculate to get my remaining balance which i put into another textbox.


(Chris Conn) #4

Heres one way, you pass the job,asm, and opr

Add a reference to BOReader

	void GetQtyInfo(string jobNum, int asmNum, int opNum)
	{
		try
		{
			
	             Ice.Proxy.Lib.BOReaderImpl _bor = WCFServiceSupport.CreateImpl<Ice.Proxy.Lib.BOReaderImpl>((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase<Ice.Contracts.BOReaderSvcContract>.UriPath);
	                DataSet ds2 = _bor.GetList("Erp:BO:JobOperSearch", "JobNum = '"+jobNum+"' AND AssemblySeq = "+asmNum.ToString()+" AND OprSeq = "+opNum.ToString(), "");//,ProdQty,ReceivedQty,WIPQty");  //namespace,whereclause,columns
		               
				 if(ds2 != null)
				{
				//				epiUltraGridC1.DataSource = ds2.Tables[0];
					numCompletedQty.Value = ds2.Tables[0].Rows[0]["QtyCompleted"];
					numExpectedQty.Value = ds2.Tables[0].Rows[0]["RunQty"];
				}
		}
		catch(Exception e)
		{
			MessageBox.Show("Error: "+e.Message);
		}
	}

(Ken Nash) #5

Chris, what calls GetQtyInfo?


(Chai Chang) #6

Chris,

To add the BOReader reference, from customization tools dialog–>Tools–>Custom Assembly Reference Manager, which dll is it? I am on Epicor 10.2, and I don’t see anything related to BOReader or Ice.Prox.Lib.BOReaderImpl.dll?


(Jose C Gomez) #7

@cchang a recommendation not related to your question, for your own sake you should always rename the controls from their default value (epiLabelC1, epiLabelC3) to something that makes sense in the context of it’s use. IE rename epiLabelC1 to lblProdQty and epiLabelC3 to lblQtyComplete

Otherwise you’ll come back in 6 months and have no idea what in the world is epiLabelC1

Sorry for the unsolicited 2 cents, but my programmer brain twitches when it sees default control names

Carry on! :slight_smile:


(Chris Conn) #8

I guess it makes the most sense to detect the change on the last item, in this case operation. (Bcuz when job or asm changes, operation is reset)

In general (pseudo) terms, it would be kinda like

GetRef to the EpiDataView that has your job/asm/op
EpiDataView myEDV = oTrans.Factory(“Name of the correct EDV”);
Put a field change event on operation field

OnFieldChange(Operation) =>
{
get the job/asm/op from the epidataview (myEDV)
Call GetQtyInfo
}

Also the DLL is:
Ice.Contracts.Lib.BOReader.dll


(Chai Chang) #9

Thanks for the help Chris. So I went and tried to detect change, however, it seems to be pulling operation 10 whenever I open my program. Also I can’t seem to get calling “GetQtyInfo”. Is there something I am missing my my code?

Here’s the entire code:

// **************************************************
// Custom code for StartProdForm
// Created: 4/2/2018 11:16:08 AM
// **************************************************

extern alias Erp_Contracts_BO_JobEntry;
extern alias Erp_Contracts_BO_JobAsmSearch;
extern alias Erp_Contracts_BO_JobOperSearch;
extern alias Erp_Contracts_BO_Resource;
extern alias Erp_Contracts_BO_ResourceGroup;
extern alias Erp_Contracts_BO_EmpBasic;

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;

public class Script
{
// ** Wizard Insert Location - Do Not Remove ‘Begin/End Wizard Added Module Level Variables’ Comments! **
// Begin Wizard Added Module Level Variables **
private static string mJobOper;
private DataView Start_DataView;
// 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

	this.Start_DataView = this.Start_Row.dataView;
	this.Start_DataView.ListChanged += new ListChangedEventHandler(this.Start_DataView_ListChanged);
	mJobOper=string.Empty;

	this.baseToolbarsManager.ToolClick += new Infragistics.Win.UltraWinToolbars.ToolClickEventHandler(this.baseToolbarsManager_ToolClick);
	// End Wizard Added Variable Initialization

	// Begin Wizard Added Custom Method Calls
		
	// End Wizard Added Custom Method Calls
}

public void GetQtyInfo(string jobNum, int asmNum, int opNum)
{

	try
	{
             Ice.Proxy.Lib.BOReaderImpl _bor = WCFServiceSupport.CreateImpl<Ice.Proxy.Lib.BOReaderImpl>((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase<Ice.Contracts.BOReaderSvcContract>.UriPath);
                DataSet ds2 = _bor.GetList("Erp:BO:JobOperSearch", "JobNum = '"+jobNum+"' AND AssemblySeq = "+asmNum.ToString()+" AND OprSeq = "+opNum.ToString(), "");
	               
			 if(ds2 != null)
			{
				txtQtyCompleted.Value = ds2.Tables[0].Rows[0]["QtyCompleted"];
				txtProdQty.Value = ds2.Tables[0].Rows[0]["RunQty"];
			
			}
	MessageBox.Show(Convert.ToString(txtQtyCompleted));
	}
	catch(Exception e)
	{
		MessageBox.Show("Error: "+e.Message);
	}
}

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


	this.Start_DataView.ListChanged -= new ListChangedEventHandler(this.Start_DataView_ListChanged);
	this.Start_DataView = null;
	mJobOper=string.Empty;

	this.baseToolbarsManager.ToolClick -= new Infragistics.Win.UltraWinToolbars.ToolClickEventHandler(this.baseToolbarsManager_ToolClick);
	// End Wizard Added Object Disposal

	// Begin Custom Code Disposal

	// End Custom Code Disposal
}


public void JobOper()
{
//Get reference to job operation
EpiDataView edvJobOper=(EpiDataView)oTrans.EpiDataViews["Start"];
	if(((edvJobOper.dataView[0]["OprSeq"].ToString() !=null)&&(Convert.ToInt32(edvJobOper.dataView[0]["OprSeq"].ToString()) > 0)))
	{
		string strJobOper = edvJobOper.dataView[0]["OprSeq"].ToString();
		if ((mJobOper != strJobOper))
		{
			mJobOper = strJobOper;
			//GetQtyInfo();
			
			MessageBox.Show(mJobOper);
		}
		else
		{
			mJobOper=string.Empty;
		}
	}

}

private void Start_DataView_ListChanged(object sender, ListChangedEventArgs args)
{
	// ** Argument Properties and Uses **
	// Start_DataView[0]["FieldName"]
	// args.ListChangedType, args.NewIndex, args.OldIndex
	// ListChangedType.ItemAdded, ListChangedType.ItemChanged, ListChangedType.ItemDeleted, ListChangedType.ItemMoved, ListChangedType.Reset
	JobOper();
	// Add Event Handler Code
}

private void baseToolbarsManager_ToolClick(object sender, Infragistics.Win.UltraWinToolbars.ToolClickEventArgs args)
{
	switch(args.Tool.Key)
	{
	case "DeleteTool":
	case "ClearTool":
	mJobOper=string.Empty;
	break;
	}
}

}


(Chai Chang) #10

Hmmmm not sure how to get all those codes into the inside frame.


(Chris Conn) #11

Instead of using a ListChange event to trigger this, use a FieldChange event on the OprSeq field of the proper dataview.


(Chai Chang) #12

Chris,

You know why I can’t call “GetQtyInfo”? I get the error indicating “Only assignment, call, increment, await, and new object expressions can only be used as statement”.

So I am using afterfieldchange to call “GetQtyInfo”, but getting error.

private void LaborDtl_AfterFieldChange(object sender, DataColumnChangeEventArgs args)
{
	// ** Argument Properties and Uses **
	// args.Row["FieldName"]
	// args.Column, args.ProposedValue, args.Row
	// Add Event Handler Code
	switch (args.Column.ColumnName)
	{
		case "OprSeq":
		GetQtyInfo;
		break;
	}
}

(Jose C Gomez) #13

That is not valid syntax in C# You have to either call a function or do an assignment.


(Chris Conn) #14

Like Jose said, that’s not valid syntax. If you dont know basic C# you’re gonna have a tough time moving forward with your customization.

One final push:

	switch (args.Column.ColumnName)
	{
		case "OprSeq":
                var myDV = oTrans.Factory("THE PROPER DATAVIEW NAME HERE");
                var job =   myDV.dataView[myDV.Row]["JobNum"].ToString();
                var asm = (int)myDV.dataView[myDV.Row]["AssemblySeq"];
                var op = (int)myDV.dataView[myDV.Row]["OprSeq"];
		GetQtyInfo(job,asm,op);
		break;
	}

To figure out what dataview you need, use Help>Field Help then select the JobNum textbox. Look at the epibinding (Table.Field). That Table name will be the name of your dataview


(Chai Chang) #15

Thanks Chris. I got it to work now.


(Chris Conn) #16

Excellent - mark my response as a solution


(Chai Chang) #17

Thanks again. New to C# and Epicor, so this is extremely helpful.