Dynamic Query write updates back to database

Hello Epi users,

I’ve pieced together a DynamicQueryAdapter to pull a UBAQ

I’ve got it working as far as pulling the correct data to a grid, but I just cannot find how to write the changes back to the database/UBAQ

(the correct fields in the UBAQ are set to updatable)

This is the code I have so far (Shout out to @dhewi for his many posts about DQA’s!!)

DynamicQueryAdapter yourbaq = new DynamicQueryAdapter(this.oTrans);
		DataTable results;
		yourbaq.BOConnect();
		string baqName = "TWG_PJ_JOBS_DQA";
		Ice.BO.DynamicQueryDataSet dsQuery = yourbaq.DynamicQueryData;
		yourbaq.GetByID("TWG_PJ_JOBS_DQA");
		if (dsQuery.DynamicQuery.Rows.Count == 0)
			{
				Ice.BO.DynamicQueryDataSet dsQDesign = yourbaq.QueryDesignData;
				DataRow targetRow;
				foreach (DataTable table in dsQuery.Tables)
					{
						foreach (DataRow sourceRow in dsQDesign.Tables[table.ToString()].Rows)
							{
								targetRow = table.NewRow();
								targetRow.ItemArray = sourceRow.ItemArray;
								table.Rows.Add(targetRow);
							}
					}
			}
	//	MessageBox.Show("1");//////remove later
		string projID = "0";
		if(edvProject.dataView.Count != 0)
			{
		//	MessageBox.Show("2");//////remove later
			projID =   edvProject.dataView[edvProject.Row]["ProjectID"].ToString();  //Convert.ToString(edvProject.dataView[edvProject.Row]["ProjectID"]);
			//projID = "PJ_21197";//////remove later
			}
		MessageBox.Show("mgs 3 " + projID);//////remove later

		Ice.BO.QueryExecutionDataSet dsBAQ = yourbaq.GetQueryExecutionParameters (dsQuery); 
		dsBAQ.ExecutionParameter[0].ParameterID = "PROJECTID";
		dsBAQ.ExecutionParameter[0].IsEmpty = false;
		dsBAQ.ExecutionParameter[0].ParameterValue = projID.ToString();
		dsBAQ.AcceptChanges();
		yourbaq.Execute(dsQuery, dsBAQ);
			if (yourbaq.QueryResults != null && yourbaq.QueryResults.Tables.Count > 0)
				{
					results = yourbaq.QueryResults.Tables["Results"];
					epiUltraGridC1ShipID.DataSource = yourbaq.QueryResults.Tables["Results"];
					MessageBox.Show("mgs 4 " + projID);//////remove later
		
				}
			else
				{
					results = new DataTable();
					epiUltraGridC1ShipID.DataSource = null;
					MessageBox.Show("mgs 5 " + projID);//////remove later
				}
		EpiDataView edv = (EpiDataView)oTrans.EpiDataViews["AAA_PJ_JOBS_DQA"];
			if (!(edv != null))
				{
					edv = new EpiDataView();
					oTrans.Add("AAA_PJ_JOBS_DQA", edv);
					edv.dataView = results.DefaultView;
					MessageBox.Show("mgs 6 " + projID);//////remove later
				}
			else
				{
					edv.dataView = results.DefaultView;
					MessageBox.Show("mgs 7 " + projID);//////remove later
				}
	}

Hi Lawson,

Try this:

yourbaq.Update(baqName,results.DataSet);

Ross

Thanks @rosshughes,

I’ve seen that mentioned on other posts, I just need to know where to place it?

How are you using the UBAQ in your solution? Is this a grid in a customization that retrieves data that is updated and has a save button? If so, can you add it to a click event?

Ross

Love a DynamicQuery use, even now!

You say you’re putting this in a grid. So it’s in a customisation of an existing screen?

If your EpiDataView is a Script-level variable, the logical thing to do, usually, is to hook into the existing form “save”, and do the update as @rosshughes suggests when that happens. That’s what the user expects.

1 Like

Ok, to try and answer both, in Project Entry I used the Sheet Wizard to add a sheet, I placed an EpiUltraGrid in it and then pieced together the UBAQ and the DQA

I have it firing at Initialization, to get that part to work I had to hardwire a value for the ProjectID and then change the ProjectID if the Row count was not “0”

string projID = "0";  // <<< Added this part and the "if" statement so it would create the EpiDataView below on form load
		if(edvProject.dataView.Count != 0)
			{
				projID =   edvProject.dataView[edvProject.Row]["ProjectID"].ToString();
			}

I have a button on the screen that after the ProjectID is present on the main sheet the user can click the button and it will then load the data into the grid (the data only loads to the grid if the grid is hardwired to the results, if I use EpiBinding from the DataView the grid doesn’t populate/refresh)

if (yourbaq.QueryResults != null && yourbaq.QueryResults.Tables.Count > 0)
				{
					results = yourbaq.QueryResults.Tables["Results"];
					epiUltraGridC1ShipID.DataSource = yourbaq.QueryResults.Tables["Results"];

Below is the full code that is fired off at Initialization and at button click

	public void ShipLinesMisc()
	{
		
	
		DynamicQueryAdapter yourbaq = new DynamicQueryAdapter(this.oTrans);
		DataTable results;
		yourbaq.BOConnect();
		string baqName = "TWG_PJ_JOBS_DQA";
		Ice.BO.DynamicQueryDataSet dsQuery = yourbaq.DynamicQueryData;
		yourbaq.GetByID("TWG_PJ_JOBS_DQA");
		if (dsQuery.DynamicQuery.Rows.Count == 0)
			{
				Ice.BO.DynamicQueryDataSet dsQDesign = yourbaq.QueryDesignData;
				DataRow targetRow;
				foreach (DataTable table in dsQuery.Tables)
					{
						foreach (DataRow sourceRow in dsQDesign.Tables[table.ToString()].Rows)
							{
								targetRow = table.NewRow();
								targetRow.ItemArray = sourceRow.ItemArray;
								table.Rows.Add(targetRow);
							}
					}
			}
		string projID = "0";  // <<< Added this part and the "if" statement so it would create the EpiDataView below on form load
		if(edvProject.dataView.Count != 0)
			{
				projID =   edvProject.dataView[edvProject.Row]["ProjectID"].ToString();
			}
		//MessageBox.Show("mgs 3 " + projID);//////remove later

		Ice.BO.QueryExecutionDataSet dsBAQ = yourbaq.GetQueryExecutionParameters (dsQuery); 
		dsBAQ.ExecutionParameter[0].ParameterID = "PROJECTID";
		dsBAQ.ExecutionParameter[0].IsEmpty = false;
		dsBAQ.ExecutionParameter[0].ParameterValue = projID.ToString();
		dsBAQ.AcceptChanges();
		yourbaq.Execute(dsQuery, dsBAQ);
	
			if (yourbaq.QueryResults != null && yourbaq.QueryResults.Tables.Count > 0)
				{
					results = yourbaq.QueryResults.Tables["Results"];
					epiUltraGridC1ShipID.DataSource = yourbaq.QueryResults.Tables["Results"];
					MessageBox.Show("mgs 4 " + projID);//////remove later
				
				}
			else
				{
					results = new DataTable();
					epiUltraGridC1ShipID.DataSource = null;
					MessageBox.Show("mgs 5 " + projID);//////remove later
				}
		EpiDataView edv = (EpiDataView)oTrans.EpiDataViews["AAA_PJ_JOBS_DQA"];
			if (!(edv != null))
				{
					edv = new EpiDataView();
					oTrans.Add("AAA_PJ_JOBS_DQA", edv);
					edv.dataView = results.DefaultView;
					MessageBox.Show("mgs 6 " + projID);//////remove later
				}
			else
				{
					edv.dataView = results.DefaultView;
					MessageBox.Show("mgs 7 " + projID);//////remove later
				}
					
	}

On the grid that loads there is one column that is editable and the idea is that the user can enter values into this column and then be able to save the changes on save

P.S. I live in Australia so thus the odd hours that I reply

Ok, I’ve found what I was doing wrong and now have it working…
I needed to declare the following in the Script area

DynamicQueryAdapter yourbaq;
DataTable results;

With that done, I could then use them outside of the private void (this may seem common sense to seasoned users but I’m still cutting my teeth on customizations)

I then was able to add the suggestion from @rosshughes

I got the idea to declare them from this post

Thank you @dhewi for the bones of the DQA

@dhewi, Do you know if there is a way to prompt the user to save changes before exiting?

You can hook into the BeforeClose event and check then, but it can be quite tricky getting it 100% right whether anything has been changed.

Thanks @dhewi, any tips would be greatly appreciated, the events ı get, but the checking ı don’t

I’ve always felt that EpiDataView must have a property to call on to check whether the data is “dirty”, but nothing has proved as reliable as I’ve wanted.

The best results I’ve had have been manually setting a Boolean variable when the user changes the data - you can toggle it each way on a DataColumnChange event and the save, then check it on form close.

Ok, thanks for the direction, I’ll let you know how I go!!

Hello @dhewi and anyone else that has worked with DQA’s and UBAQ’s

I’ve got my grid displaying correctly and if I manually update the editable grid cells and hit save the database updates as expected…

The problem I’m having now is, I’ve created a button that updates the editable cells in all highlighted (selected) rows to a value from another field

The grid cell values change to the expected values but when I click save (which runs yourbaq.Update(“uBAQName”,results.DataSet); ) the database doesn’t update and the grid rolls back to the previous values

I’ve studied the grid and noticed that the little pencil icon appears both when I manually update and when I update with the button click

image

Any hints/ideas would be much apreciated

Ok, I sorted my own problem, I had to set the RowMod to “U” for the particular row… I thought I had tried this before I posted, but I mustn’t have been holding my mouth the right way

1 Like

Glad you sorted it. It’s worth bearing in mind that it usually proves more reliable working with the EpiDataView and letting the changes show up in the grid than doing the reverse, wherever possible. And then you can use BeginEdit / EndEdit to sort the RowMod.

Thanks Daryl, I haven’t had much luck with the EpiDataView’s, to get my results to display I’ve had to use epiUltraGridC1ShipID.DataSource = results;
I know how to bind to the EDV in the grid properties but the results only show up if there is data present on the first query run, and then disappear if I rerun the query, I know there is data there on the rerun because if I hardwire the grid to the results the grid populates

To get a bit of the EpiMagic, I’ve used the properties to bind the EDV to the grid and I’ve also hard-wired it too, this lets me hide columns etc

Do you have any tips on getting refreshed results to display in grids via EDV’s???

I’ve leveraged DynamicQuery a lot by now, and pulled the repeatable bits out into a class I declare in the customisation code. Maybe I should just share that with you!

There are two ways to bind the query results to the grid - the native Infragistics way, which is via the DataSource, and the Epicor way, which is the EpiBinding. You don’t need to do both.

If you do the EpiBinding, you’ll get all the EpiMagic just as if it was all native, and updates etc will work as normal. Usually you can update the data and it will show, and there are notifications to trigger if needed.

The only reason to use the DataSource instead is if you want to manually format the grid, because once the EpiMagic is involved you can’t do that - Epicor just overwrites whatever you do. But in that case you need to also manually handle keeping the grid and the EpiDataView in sync with each other, which is obviously extra work.

2 Likes

Thank you for your time Daryl,

I’m interested in learning how to do the following

and

Manually formating grids gets a bit laborious at times especially if there are a lot of columns

I would be interested in this if you are willing/able to share the class. We have a number of UBAQs with input parameters and I’ve been able to wire into grids thanks to the great examples you have previously shared (thanks for those examples btw!)

@LBARKER, @tanner - I’m happy to share, but might be a day or two, because there’s too much extra complication in what I use and it would confuse things. I’ve been meaning to create a stripped-back version and this might be a useful spur.

1 Like