Linq Output to Grid?

Happy Friday fellow epiusers!

In my project to convert a screen customization to a BPM workflow, I’ve got another question?

I have this code to create a formatted string and assigns the string to callContextBpmData.Character01, which I’m displaying in a BPM form, which is sort of working, but I would rather have the data in an EpiUltraGrid. Is that possible?

Related questions is it possible to launch Mass Issue with the job/asm/opr prepopulated via code?

LINQ Stringbuilder code
foreach (var mtlPart in (
	from jm in Db.JobMtl.With(LockHint.NoLock)
		join pp in Db.PartPlant.With(LockHint.NoLock)
			on new {jm.Company, jm.PartNum} equals new {pp.Company, pp.PartNum}
		into jmj
	from pp in jmj.DefaultIfEmpty()
		where jm.Company == sCompany && jm.JobNum == sJobNum 
			&& jm.AssemblySeq == iAsmSeq && iOprSeq == jm.RelatedOperation
			&& jm.IssuedComplete == false && jm.BackFlush == false
	select new {jm.Company, jm.JobNum, jm.AssemblySeq, jm.PartNum, jm.Description
		, jm.IUM, jm.RequiredQty, jm.IssuedComplete, jm.RelatedOperation
		, jm.IssuedQty, jm.WarehouseCode, jm.MtlSeq
		, Shortage = (jm.RequiredQty - jm.IssuedQty) }))
	{
		myDetail = myDetail + Environment.NewLine + string.Format
		(layoutFormat, mtlPart.MtlSeq, mtlPart.PartNum, mtlPart.Shortage.ToString("0.00"));
		iRecordCount += 1;
	}
if (iRecordCount > 0)
{
	callContextBpmData.Character01 = myHeader + myDetail;
}

1 Like

So what you should do is move that LINQ code to a BAQ
Then whatever you are using for your filtering assign that to callContext and then in the BPM Form simply use a BAQDataView or BAQGrid to show the data and filter with the callContext.

1 Like

You know after getting this far along I actually start thinking that maybe there was a way to do this with a BAQ and somehow knew you were going to say that…

Guess I’ll see if I can figure that out.

I’m using the LINQ code as a condition as well, basically checking to see if there are any outstanding mtl, if not proceed normally, if there is display the BPM form showing the mtls and options.

So can you not do left joins in a BPM query condition? It’s grayed out…

You should be able to…

You CAN do left joins in a BAQ, but it is not possible in a BPM Query… this is a long-time missing feature.

Well that stinks… Thanks for verifying @timshuwy!

If your LINQ code returns a datatable, then you can use that directly as an UltraGrid datasource. It’s as simple as grid.DataSource = table.

1 Like

This might be useful for getting your linq to datatable

2 Likes

@josecgomez, I’ve made some process getting a BAQ to show up in the BPMform, but I’m running into an error that I can’t figure out.

Inner Exception Message: Length cannot be less than zero.

Application Error

Exception caught in: mscorlib

Error Detail

Message: Exception has been thrown by the target of an invocation.
Inner Exception Message: Length cannot be less than zero.
Parameter name: length
Program: CommonLanguageRuntimeLibrary
Method: InvokeMethod

Client Stack Trace

at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Ice.Lib.Customization.CustomScriptMethodInvoker.InvokeScriptMethod(MethodInfo scriptMethod, Object[] parameters)
at Ice.Lib.Customization.CustomScriptMethodInvoker.InvokeInitializeCustomCodeIfExists()
at Ice.Lib.Customization.CustomScriptManager.TryActionShowExceptionBoxOrLogVerificationErrorIfException(Action action, String exceptionBoxTitle)

Inner Exception

Length cannot be less than zero.
Parameter name: length

at System.String.Substring(Int32 startIndex, Int32 length)
at Ice.Lib.Broadcast.PublishAgent…ctor(Object sender, String Name, String EpiBinding)
at Ice.Lib.Broadcast.PublishAgent.RegisterTransactionEvent(Object sender, String Name, String EpiBinding)
at Ice.Lib.Framework.EpiTransaction.PublishColumnChange(String EpiBinding, String BroadcastName)
at Script.CreateMtlListBAQView()
at Script.InitializeCustomCode()

The Code I have is below. It seems to create the view correctly and bring in the BPMData values

public void CreateMtlListBAQView()
{
	baqViewMtlList = new BAQDataView("OutstandingJobOpMtls");
	oTrans.Add("OutstandingJobOpMtls_BAQ",baqViewMtlList);
	
	EpiDataView edvBPMdata = (EpiDataView)(oTrans.EpiDataViews["BPMData"]);
	
	string sJobNum = Convert.ToString(edvBPMdata.dataView[edvBPMdata.Row]["Character01"]);
	int iAsmSeq = Convert.ToInt32(edvBPMdata.dataView[edvBPMdata.Row]["Number01"]);
	int iOprSeq = Convert.ToInt32(edvBPMdata.dataView[edvBPMdata.Row]["Number02"]);
	
	txtJobNum.Value = sJobNum;
	txtAsmSeq.Value = iAsmSeq;
	txtOprSeq.Value = iOprSeq;
	
	IPublisher pub = oTrans.GetPublisher(sJobNum);
	
	if(pub==null)
	{
		oTrans.PublishColumnChange(sJobNum, "MyCustomPublish");
		pub = oTrans.GetPublisher(sJobNum);
	}
	if(pub !=null)
	{
		baqViewMtlList.SubscribeToPublisher(pub.PublishName, "JobMtl_JobNum");
	}
}

Any pointers, I’m sure I’m missing something.

You can’t use sJobNum since on your PublishColumn since that’s not a column.
sJobNum is the jobNumber…
What you want to pass there is the name of the column to subscribe to.

ahh, not the value, but the actual column name, which I now see that in the examples. Therefore, I would think it would be “BPMData.Character01”, which does makes the error go away but the grid still contains no data…

public void CreateMtlListBAQView()
{
	baqViewMtlList = new BAQDataView("OutstandingJobOpMtls");
	oTrans.Add("OutstandingJobOpMtls_BAQ",baqViewMtlList);

	EpiDataView edvBPMdata = (EpiDataView)(oTrans.EpiDataViews["BPMData"]);

	string sJobNum = Convert.ToString(edvBPMdata.dataView[edvBPMdata.Row]["Character01"]);
	int iAsmSeq = Convert.ToInt32(edvBPMdata.dataView[edvBPMdata.Row]["Number01"]);
	int iOprSeq = Convert.ToInt32(edvBPMdata.dataView[edvBPMdata.Row]["Number02"]);
		
	txtJobNum.Value = sJobNum;
	txtAsmSeq.Value = iAsmSeq;
	txtOprSeq.Value = iOprSeq;

	string pubBinding = "BPMData.Character01";

	IPublisher pub = oTrans.GetPublisher(pubBinding);

	if(pub==null)
	{
		oTrans.PublishColumnChange(pubBinding, "MyCustomPublish");
		pub = oTrans.GetPublisher(pubBinding);
	}

	if(pub !=null)
	{
		baqViewMtlList.SubscribeToPublisher(pub.PublishName, "JobMtl_JobNum");
	}
}

Silly question you do have data in that field? also when are you calling this function/

no silly questions

I’m calling it on InitializeCustomCode(), I’m 99% sure there is data because I’ve displayed the value of BPMData.Character01 in txtJobNum.

If I manually add the JobNum as criteria to the BAQ I get data when I test the it.

If I comment out the publish & subscribe lines of code, so I’m just creating the BAQview, the grid still has no data. Shouldn’t I get all of the data that I get when I test the BAQ?

Got it, so because this is a special IP form you may have to trigger it to change the value
What happens if you change that value on the textbox?

Yes, that did refresh the BAQ and it display the correct data. Is there a way to do that programmatically?

Yes

using System.Reflection;

private void RefreshBAQDataView(BAQDataView iBaqView)
    {
        MethodInfo mi = iBaqView.GetType().GetMethod("invokeExecute", BindingFlags.Instance | BindingFlags.NonPublic);
        mi.Invoke(iBaqView, new object[]{ true });
    }
1 Like

Getting closer, I think.

Error: CS1502 - line 73 (333) - The best overloaded method match for ‘Script.RefreshBAQDataView(Ice.Lib.Framework.BAQDataView)’ has some invalid arguments
Error: CS1503 - line 73 (333) - Argument 1: cannot convert from ‘Ice.Lib.Framework.EpiDataView’ to ‘Ice.Lib.Framework.BAQDataView’

It doesn’t seem to like
EpiDataView edvBPMdata = (EpiDataView)(oTrans.EpiDataViews["BPMData"]);

if I change it to
BAQDataView edvBPMdata = (BAQDataView)(oTrans.EpiDataViews["BPMData"]);
the syntax checks okay but get an error on launch

Unable to cast object of type ‘Ice.Lib.Framework.EpiDataView’ to type ‘Ice.Lib.Framework.BAQDataView’.