EpiDataView on FKV

My Goal: To get a field from the PO Header (Plant_c) and copy it to the AP Invoice Header.

What I have done is this:
On the AP Invoice Entry menu I have created an FKV for POHeader.
image

I have never used an FKV before, so I hope I did it correctly…The columns do show up under Custom Columns, including the field I am looking for, which is Plant_c.
image

I then set an AfterFieldChange event on APInvHed, to try and catch when the REFPONum field changes.
image

	private void APInvHed_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 "REFPONum":
				MessageBox.Show(string.Format("APInvHed_AfterFieldChange: {0}", args.Row["REFPONum"]));
				string POPlant_ID = edvPOHeader.dataView[edvPOHeader.Row]["Plant_c"].ToString();
				MessageBox.Show(string.Format("POPlant_ID is set to: {0}", POPlant_ID)); 
				break;
		}
	}

That event fires, and the first message box appears with the PO Num, then an error appears:
image

I am assuming that the edvPOHeader DataView has not been populated at this point.

With all of that being said, am I going about this the wrong way? I look into using a Method Directive, but I couldn’t find a method that fires when a new PO is loaded into the AP Invoice Header. The closest I found was on APInvoice.ChangeRefPONum, but that seems to hold the PONumber that was in the field (in this case, it was 0 from when I clicked the ‘NEW’ button.

I ran a trace to see what methods were called when I added the PO to the AP Invoice, and ChangeRefPONum is the only one that fired, so again, I am back to square one.

So my question is: Where did I go wrong here? What am I missing/overlooking to get a record from the PO Header on the AP Invoice Entry?

I think I ran into this issue before. Try replacing

string POPlant_ID = edvPOHeader.dataView[edvPOHeader.Row]["Plant_c"].ToString();

with

string POPlant_ID = edvPOHeader.CurrentDataRow["Plant_c"].ToString();

I have tried that, but since it appears the FKV isn’t populated with any data, it errors out with the “Index -1 is either negative or above rows count” message.

I’m not sure why it wouldn’t be populating, but I don’t have any experience with a Wizard created FKV. Is that string all you need?

Yes, just the Plant_c field from the PO Header.

You can get it another way. Your way is probably better, but I’m not sure how to troubleshoot it lol. If you add the following to your after-change method:

		var session = (Ice.Core.Session)APInvoiceForm.Session;

		string POPlant_ID = string.Empty; // Move this variable declaration outside of the method if you need to access it elsewhere.
		string APInvHed   = "APInvHed";
		string REFPONum   = "REFPONum";

		var edvAPInvHed = (EpiDataView)oTrans.EpiDataViews[APInvHed];

		int RefPONum = (int)edvAPInvHed.CurrentDataRow[REFPONum];


		using (var svc = WCFServiceSupport.CreateImpl<Erp.Proxy.BO.POImpl>(session, Erp.Proxy.BO.POImpl.UriPath))	
		{
			var dsPOHeader = svc.GetByID( RefPONum );

			if (dsPOHeader != null) 
			{
				POPlant_ID = (string)(dsPOHeader.Tables[0].Rows[0])["Plant_c"];
			}
		}

It should do the job. You also have to add the Erp.Contracts.BO.PO.dll in Assembly References Manager:
image

You could just check if the row is greater than zero…

While your solution looks like it would do exactly what I need, I was already in the process of going about it a different way when you posted it.

This is what I came up with:

				DynamicQueryAdapter dynamicQueryAdapter = new DynamicQueryAdapter(this.oTrans);
				dynamicQueryAdapter.BOConnect();
				QueryExecutionDataSet qeds = dynamicQueryAdapter.GetQueryExecutionParametersByID("EFG_GetPOPlant");
				qeds.ExecutionParameter.Clear();
				qeds.ExecutionParameter.AddExecutionParameterRow("PONumber", args.Row["REFPONum"].ToString() , "nvarchar", false, Guid.NewGuid(), "A");
				dynamicQueryAdapter.ExecuteByID("EFG_GetPOPlant", qeds);
				if(dynamicQueryAdapter.QueryResults.Tables["Results"].Rows.Count > 0)
				{
					string plantID = dynamicQueryAdapter.QueryResults.Tables["Results"].Rows[0]["POHeader_Plant_c"].ToString();
					edvAPInvHed.dataView[edvAPInvHed.Row]["Plant_c"] = plantID;
				} else {
					MessageBox.Show("S**t is still broke");
				}

Basically, grabbed it from a BAQ that I had, and then used that to set the value of a BAQCombo (which was the ultimate goal).

Thank you for that snippet thought. That is going to come in handy on a few other projects that are lined up on my plate.

@klincecum - Good point…I did do that on my BAQ Results though :slight_smile:

I had it there initially, but I took it out when I realized that something wasn’t working right. In this case, the FKV not having any data in it, and I was trying to figure out why. FKV’s are new to me, so I am sure I made a basic mistake somewhere along the line.

Even easier: ctrl+A + Backspace would get rid of that error pretty quick.

That works too. Only change I would make is to put the adapter in a using statement to make sure it gets disposed properly automatically:

		using ( DynamicQueryAdapter dynamicQueryAdapter = new DynamicQueryAdapter(this.oTrans) )
		{
			dynamicQueryAdapter.BOConnect();
			
			QueryExecutionDataSet qeds = dynamicQueryAdapter.GetQueryExecutionParametersByID("EFG_GetPOPlant");
			qeds.ExecutionParameter.Clear();
			
			qeds.ExecutionParameter.AddExecutionParameterRow("PONumber", args.Row["REFPONum"].ToString() , "nvarchar", false, Guid.NewGuid(), "A");
			
			dynamicQueryAdapter.ExecuteByID("EFG_GetPOPlant", qeds);
			
			if ( dynamicQueryAdapter.QueryResults.Tables["Results"].Rows.Count > 0 )
			{
				string plantID = dynamicQueryAdapter.QueryResults.Tables["Results"].Rows[0]["POHeader_Plant_c"].ToString();
				edvAPInvHed.dataView[edvAPInvHed.Row]["Plant_c"] = plantID;
			} 
			else 
			{
				MessageBox.Show("S**t is still broke");
			}
		}

EDIT: but you would have to declare the string outside of the method & using scope if you want to access it again.

1 Like