BAQ Dataview Example Video

Correct but hey reflection is still valid code :smiley:

2 Likes

This is a very timely post. Thanks for sharing!

Is there an easy button for enabling updates through a BAQDV? The BAQ is updatable but the grid is forcing it to be read only.

No easy button requires reflection

And I noticed the grid refresh was not being triggered when toggling between orders with and without lines. (version E10.1.6xx).

Ref screen shot

While I was playing around with the example in the video - thanks to Carson for that BTW

Good catch @bordway.
The publisher subscribe doesn’t like not having a row. I think embedded dashboards have a similar issue.
This cleans it up. I added an EpiViewNotification to look for a change of the order number and applying a second filter to the dataview. This also clears the view when clear is pressed.

	int currentOrder = 0;
	private void edvOrderHed_EpiViewNotification(EpiDataView view, EpiNotifyArgs args)
	{
		// ** Argument Properties and Uses **
		// view.dataView[args.Row]["FieldName"]
		// args.Row, args.Column, args.Sender, args.NotifyType
		// NotifyType.Initialize, NotifyType.AddRow, NotifyType.DeleteRow, NotifyType.InitLastView, NotifyType.InitAndResetTreeNodes
		if ((args.NotifyType == EpiTransaction.NotifyType.Initialize))
		{
			if ((args.Row > -1))
			{
				if (currentOrder != (int)view.dataView[args.Row]["OrderNum"])
				{
					currentOrder = (int)view.dataView[args.Row]["OrderNum"];
				}
			}
			else	
			{
				currentOrder = 0;
			}

			orderLineOnHandBAQDV.dataView.RowFilter = String.Format("OrderDtl_OrderNum = '{0}'", currentOrder);

		}
	} 

I must not be doing something correctly. If I have just one binding it works just fine. It’s when I try to add the second one in, it just seems to ignore one or the other. In this case, it’s returning the part with all of the customers listed. It doesn’t matter if I put CustID first or second.

	public void CreatetrkCustomerPricingBAQDV()
	{
		trkCustomerPricingBAQDV = new BAQDataView("trkCustomerPricing");
		oTrans.Add("trkCustomerPricingBAQDV",trkCustomerPricingBAQDV); 

		string pub1Binding = "MyCustomerData.CustID"; 
		IPublisher pub1 = oTrans.GetPublisher(pub1Binding);
		if(pub1==null) 
		{ 
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pub1Binding, pubName);
			pub1 = oTrans.GetPublisher(pub1Binding);
		} 
		if(pub1 !=null) 
			trkCustomerPricingBAQDV.SubscribeToPublisher(pub1.PublishName, "Customer_CustID");
		
		string pub2Binding = "Part.PartNum"; 
		IPublisher pub2 = oTrans.GetPublisher(pub2Binding);
		if(pub2==null) 
		{ 
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pub2Binding, pubName);
			pub2 = oTrans.GetPublisher(pub2Binding);
		} 
		if(pub2 !=null) 
			trkCustomerPricingBAQDV.SubscribeToPublisher(pub2.PublishName, "Part_PartNum");
	}

Yields this:
image

I don’t know if I’m just misunderstanding, or if something isn’t working.

Thanks!

What screen are you adding it to? Does the screen have EpiDataViews of MyCustomerData and Part?

I’m adding it to the part tracker. I have a custom EpiDataView that I store the customer data in, I have bound textboxes as well to make sure they are properly populated. The data refreshes when I put a new part in, but it doesn’t care about changing the CustID (or CustNum) field. I have a feeling I’m misunderstanding something which would explain it.

You could remove the customer ID publish/subscribe relations and do a post filter.

trkCustomerPricingBAQDV.dataView.RowFilter = String.Format("Customer_CustID= '{0}'", insert_customer_ID_here);

I did try that. The query is pretty intense, so I have changed it to a parameterized query where I just get one row back. It takes 1/10th the time. I was just hoping I could figure out something about this because this way is much easier.

I just had an interesting problem with a BAQ Dataview that was subscribed to two fields.
On a UD screen I am storing CustNum_c and ShipToNum_c and retrieving information about the shipto with a BAQ dataview. Everything worked great 90% of the time, but occasionally while moving through records the BAQ data view would not refresh correctly. It didn’t seem to be related to any specific records since sometimes I could leave a record and return to it and it would be ok. I have two other BAQ daviews with a single publish/subscribe relation that work 100% of the time. My work around was to change the my baq dataview to use the SysRowId of the UD table for the publish/subscribe relation.

Has anyone seen similar issues with subscribing to multiple fields?

My first guess as to the cause of your problem was that ShipToNum can be blank. In fact, I think when a Customer record is first created, a ShipTo record with a blank SipToNum will be created. If it’s not when the customer is first created, then it might be when the first ShipTo (which becomes the second ShipTo record for the customer) is created.

Does you BAQ handle that condition okay?

It works fine with the blank shipto records and correctly returns the data for the blank shipto record. The one that I dug completely the BAQ dataview appeared to have only filtered on the CustNum and not the ship to. While debugging I could see the publisher was correctly publishing the shipTo in oTrans, but the BAQ had returned all the records for that customer and did not filter the ship to even thought there was a matching shipto record in the dataview. Changing the shipto and changing it back would correctly refresh the BAQ Dataview. I only saw the issue when loading multiple records at once and using the record select arrows to move between records.

Hi. I am trying to replace the grid in Opportunity/Quote Entry > Line > Manufacturing > Details > Quote Details > Materials > List with a BAQ Data View. Reason being we want to see fields like QtyOnHand and several other fields from different tables for each part in the current quote. Following from the advice in this post I have created a BAQ and managed the below code.

Problem is the list view is now showing me a list of quotes just the one part is in. I need all the parts showing. This must have something to do with needing to filter by the QuoteHed.QuoteNum?

Any help much appreciated - I’m a beginner!
Thanks

using Ice.Lib.Broadcast;

public class Script
{

BAQDataView baqViewMatGrid;

public void InitializeCustomCode()
{
	
	CreateMatGridBAQView();
}

public void CreateMatGridBAQView()
{
	baqViewMatGrid = new BAQDataView ("JSL-QuoteMtlOnHandBAQView");
	oTrans.Add("MaterialsGridBAQ",baqViewMatGrid);

	string pubBinding = "JobMtl.PartNum";
	IPublisher pub = oTrans.GetPublisher(pubBinding);
	if(pub==null)
		{
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pubBinding, "MyCustomerPublishMatGrid");
			pub = oTrans.GetPublisher(pubBinding);
		}

	if(pub !=null)
		baqViewMatGrid.SubscribeToPublisher(pub.PublishName,"QuoteMtl_PartNum");
}

This is great! Thank you so much for sharing! I am trying to implement this solution on a custom dashboard. How do I know which values to enter for pub1Binding? You can see I am trying to link to text box values and combo box values.

public void CreateEcoRevOpsBAQDV()
	{

		ecoRevOpsBAQDV = new BAQDataView("getPartRevOpECO"); //baq name
		oTrans.Add("EcoRevOpsBAQDV",ecoRevOpsBAQDV); 
		string pub1Binding = "txtMyPart.Text"; //Native form linking field 1
		IPublisher pub1 = oTrans.GetPublisher(pub1Binding);
		if(pub1==null) 
		{ 
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pub1Binding, pubName);
			pub1 = oTrans.GetPublisher(pub1Binding);
		} 
		if(pub1 !=null) 
			ecoRevOpsBAQDV.SubscribeToPublisher(pub1.PublishName, "ECORev_PartNum"); //BAQ linking field 1

		string pub2Binding = "revCombo.Text"; //Native form linking field 2
		IPublisher pub2 = oTrans.GetPublisher(pub2Binding);
		if(pub2==null) 
		{ 
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pub2Binding, pubName);
			pub2 = oTrans.GetPublisher(pub2Binding);
		} 
		if(pub2 !=null) 
			ecoRevOpsBAQDV.SubscribeToPublisher(pub2.PublishName, "ECORev_RevisionNum");//BAQ linking field 2



	}

It is the name of the DataView/Field where the values come from. So lookk at your grid and see what EpiBinding and use that plus the field name.

1 Like

Perfect! I had to switch mine to “V_EditAnyOp_1View.PartRev_PartNum”. I also forgot to remove the parameters from my BAQ. I had removed the criteria but left the parameters. Once I removed them and fixed the syntax, this works great! Thanks for the help!

2 Likes

I am trying to use this bit of code to manually refresh my BAQDataView:

private void CheckForCheckedOut(BAQDataView myBAQDV)
	{
		if (myBAQDV.dataView.Count > 0)
		{
			//MessageBox.Show("Checked Out!");
			ecoUltraGrid.Visible=true;
			lblCheckedOutWarning.Visible = true;
			MethodInfo mi = myBAQDV.GetType().GetMethod("invokeExecute", BindingFlags.Instance | BindingFlags.NonPublic);
   		 mi.Invoke(myBAQDV , new object[]{ true });
		}
		else
		{
			ecoUltraGrid.Visible=false;
			lblCheckedOutWarning.Visible = false;
		}
	}

This bit of code is called anytime a relevant field is changed (ValueChanged). But I keep getting an error on the methodinfo bit that is supposed to refresh my BAQ View.

Application Error

Exception caught in: App.EditAnyOp.MainController.EP.VTAERO.Customization.Custom2.CustomCode.59

Error Detail 
============
Message: Object reference not set to an instance of an object.
Program: App.EditAnyOp.MainController.EP.VTAERO.Customization.Custom2.CustomCode.59.dll
Method: CheckForCheckedOut

Client Stack Trace 
==================
   at Script.CheckForCheckedOut(BAQDataView myBAQDV)
   at Script.V_EditAnyOp_1View_AfterRowChange(EpiRowChangedArgs args)
   at Ice.Lib.Framework.EpiRowChanged.Invoke(EpiRowChangedArgs args)
   at Ice.Lib.Framework.EpiDataView.RaiseRowChanged(Int32 currentRow, Int32 lastRow)
   at Ice.Lib.Framework.EpiDataView.onRowChanged(Int32 currentRow, Int32 lastRow)
   at Ice.Lib.Framework.EpiDataView.SetCurrentRow(Int32 newRow, Boolean currentRowOnly)
   at Ice.Lib.Framework.EpiUltraGrid.OnBeforeCellActivated(Object sender, CancelableCellEventArgs ea)

I am using reflection. Is there something else I am missing?
Thanks!
Nate

I had the case wrong. It should be “InvokeExecute”. Thanks to an old post from Jose!

I know you showed me how to use an EPIBinding here, but is there any way to link to a unbound text field? For example:

public void CreateEcoRevOpsBAQDV()
	{
		ecoRevOpsBAQDV = new BAQDataView("getPartRevOpECO"); //baq name
		oTrans.Add("EcoRevOpsBAQDV",ecoRevOpsBAQDV); 
		string pub1Binding = txtPartNum.Text; //Native form linking field 1
		IPublisher pub1 = oTrans.GetPublisher(pub1Binding);
		if(pub1==null) 
		{ 
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pub1Binding, pubName);
			pub1 = oTrans.GetPublisher(pub1Binding);
		} 
		if(pub1 !=null) 
			ecoRevOpsBAQDV.SubscribeToPublisher(pub1.PublishName, "ECORev_PartNum"); //BAQ linking field 1

		string pub2Binding = cmbRevNum.Text; //Native form linking field 2
		IPublisher pub2 = oTrans.GetPublisher(pub2Binding);
		if(pub2==null) 
		{ 
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pub2Binding, pubName);
			pub2 = oTrans.GetPublisher(pub2Binding);
		} 
		if(pub2 !=null) 
			ecoRevOpsBAQDV.SubscribeToPublisher(pub2.PublishName, "ECORev_RevisionNum");//BAQ linking field 2
	
	}

I want to link to my unbound text box, txtPartNum, and BAQ combo, cmbRevNum. Is this kind of thing possible? Thanks!
Nate

1 Like