CurrentRow ID from Dataview

Hi

Should hopefully be an easy question… I have the below line of code which works great, fires on AfterRowChange on the dataView.

string jobNum = args.CurrentView.dataView[args.CurrentRow]["JobHead_JobNum"].ToString();

What I would like to do, is get the ID of the row. I want to be able to identify the row above it in the data grid, and make a change to the selected row and the one above. (I have a ProductionSequence_c field on the JobHead table - I want to have an UP and DOWN button, to re-arrange production order).

I’ve tried this, but it blows up:

currentRowID = Convert.ToInt32(args.CurrentView.dataView[args.CurrentRow]);

There must be a really simple way, but can’t find the syntax.

Many Thanks
Mark

OK, so as is always the way once I posted I then got a bit further along:

foreach (PropertyInfo prop in args.GetType().GetProperties())
{
	if(prop.Name == "CurrentRow")
	{
	      currentRowID = Convert.ToInt32(prop.GetValue(args, null));
	}
}

This gives me the CurrentRow ID, but its for the underlying DataView on the dashboard itself. On top of that dataView, there are 4 datagrids (one per tab). I want to get the CurrentRow ID, but within the Context of each grid. In testing, on a particular grid the row I’m on might be ID 32, but the one above it is 12. I know that it relates back to the sort order on the base dataView.

For clarity, the dataViews are these:

V_JobDashboard_1View (base one, against which I’m using the AfterRowChange method successfully)
V_JobDashboard_1View1
V_JobDashboard_1View2
V_JobDashboard_1View3
V_JobDashboard_1View4

Time to pester a few peeps… :smiley:

@Chris_Conn
@josecgomez
@Bart_Elia
@Mark_Wonsil

So something like this?

// Replace tableName with your DataView V_Job....
EpiDataView dv = (EpiDataView)oTrans.EpiDataViews[ "tableName" ]; // or use oTrans.Factory("name")
System.Data.DataRow row = dv.CurrentDataRow;

string test = row["QuoteLine"].ToString();

Then you repeat the same for the other views, all in 1 helper function and you can get all Active Rows / Their Values at the same time.

2nd One more thing to get the actual index if you just need that it would be

int currentIndex = _dv_table_stuff_here.Rows.IndexOf(args.Row); // if you need it

Lastly, my favorite; if the user doesn’t have anything selected or the wrong one selected you can always query the right one based on a whereClause, Select() or LINQ AsEnumerable() (NOTE: AsEnumerable requires using System.Linq)

int countExceptions = this.BAQResults.Tables["Results"].Select("Calculated_isException = 1").Length;

foreach (DataRow baqRow in this.BAQResults.Tables["Results"].Select("Calculated_isException = 0"))
{
  // do work
}
// Get Record for Update
string whereClause = string.Format("MtlSeq = {0} and MtlPartNum = '{1}'", srcMtlSeq, srcMtlPartNum);
DataRow matchingRow = edvECOMtl.dataView.Table.Select(whereClause)[0]; // get only 1 DataRow [0] you can also get them all just will return at DataRow[] instead
matchingRow.BeginEdit();
	matchingRow["RelatedOperation"] = srcRelatedOp;
matchingRow.EndEdit();
3 Likes

Does args.CurrentRow not give you what you need directly? args.CurrentRow - 1 would give you the row above, normally.

Either that or args.CurrentView.dataView[args.CurrentRow][“RowIdent”]?

Could you use the row of the grid itself? That contains an index value.

Thanks for the replies. I looked at it again just now, and a break away from it coupled with new advice is great. I have 5 dataviews on the assembly, 4 that are linked to the grids on each of 4 tabs. The 5th one, is the underlying result of the dashboard query and contains all of the data.

My original code works against the underlying dataview because that’s where the AfterRow method is:

private void V_JobDashboard_1View_AfterRowChange(EpiRowChangedArgs args)
	{
		// Working, but refers to the underlying dataView
		foreach (PropertyInfo prop in args.GetType().GetProperties())
	    {
	    	if(prop.Name == "CurrentRow")
			{
				//var type = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
	        	//MessageBox.Show(prop.Name + " / " + prop.GetValue(args, null).ToString());
				currentRowID = Convert.ToInt32(prop.GetValue(args, null));
			}
	         
	    }
}

I can easily create 4 new methods which relates to the AfterRowChange method of each dataview (grid). Can I tell in code which grid the user currently has active on screen?

@Chris_Conn you said to use the row from the grid and get it’s Index - can I get from the index of one row on the grid, to the index of the row above it and then to the dataview to be able to amend by UD field?

Not sure if you read my post - I edited it, might have not seen the updates if you are using email reply. But Read it again :slight_smile: CurrentRow ID from Dataview - #3 by markdamen - ERP 10 - Epicor User Help Forum

All I know is playing with the grid is like playing with fire :slight_smile: sometimes it will choke on you, you know after like a refresh button or RowDelete reshuffling your index. When you do it on the Grid Level you end up sometimes with stupid hacks like this:

If you can stick to the DataView / DataRow’s.

But you can tell probably which Active View the User is on via:

(oTrans.LastView).ViewName == "UD06View" // if statement use oTrans.LastView perhaps
1 Like

So I’ve read both of your posts, but I’m still struggling…!

The first reply that you made, I read the C# code blocks (in displayed order) as performing these actions:

Block 1 - get the current row from the identified EpiDataView, and then sets a string equal to a column value from that row

Block 2 - doesn’t compile. I have this code below, which says that EpiDataView doesn’t contain a definition for ‘Rows’

int currentIndex = dv.Rows.IndexOf(row);

Block 3 - I think I already have an index for the row(s) that I’m interested in, by doing this below code on each of the 4 AfterRowChange methods. I have 4 int variables at class level to store the result, which I can then consume in my ResequenceJob() method:

foreach (PropertyInfo prop in args.GetType().GetProperties())
	    {
	    	if(prop.Name == "CurrentRow")
			{
				//var type = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
	        	//MessageBox.Show(prop.Name + " / " + prop.GetValue(args, null).ToString());
				currentRowIDFresh = Convert.ToInt32(prop.GetValue(args, null));
			}
	         
	    }

I think I’m just stuck on a simple question - if I can make this work, I’ll post the working code for you guys to review and suggest alternative ways of achieving the same but making it look more pretty. I’m not sure I’ve conveyed the end goal correctly reading back the current replies.

How do I interact with the rows in the EpiDataView using indexing?

dv.Table[0].Row[myCurrentRowID - 1]["Column_c"] = 50;
dv.Rows[myCurrentRowID - 1]["Column_c"] = 50

Block 1: Provided a gist on how to do this:

public void MyCoolMethod()
{
	EpiDataView dv = null;

	dv = oTrans.Factory("V_JobDashboard_1View1");
	System.Data.DataRow row_1View1 = dv.CurrentDataRow; // ** I wonder if you can do - 1 or + 1 on this one, but honestly in the DataRow World it doesnt matter if you have Grid Groupings, the row is still the same Row, no?

        // Instead of trying to grab it by the index, just let CurrentDataRow get it for you.
	dv = oTrans.Factory("V_JobDashboard_1View2");
	System.Data.DataRow row_1View2 = dv.CurrentDataRow;

	dv = oTrans.Factory("V_JobDashboard_1View3");
	System.Data.DataRow row_1View3 = dv.CurrentDataRow;

	dv = oTrans.Factory("V_JobDashboard_1View4");
	System.Data.DataRow row_1View4 = dv.CurrentDataRow;

	// Now you have row_1View1, row_1View2, row_1View3, row_1View4
	// With the Currently "Active/Selected" Row
	// Now you can do with it as you please
	
	// Read Values
	var x = row_1View4["ColumnHere"].ToString();

	// Update Values
	row_1View1.BeginEdit();
		row_1View1["ColumnHere"] = "Hello";
	row_1View1.EndEdit();

	row_1View4.BeginEdit();
		row_1View4["RelatedOperation"] = srcRelatedOp;
	row_1View4.EndEdit();

}

Block 2: Needs to go on the Table (Conceptual, BUT you shouldnt even needs this)

EpiDataView dv = oTrans.Factory("ViewName");
System.Data.DataRow row_1View1 = dv.CurrentDataRow;
int currentIndex = xyz.dataView.Table.Rows.IndexOf(   row_1View1 ); // Could be Wrong lookup IndexOf, Its been a while

Block 3: Shows a more accurate method, more solid by Querying the Sub-Views based on Keys so you don’t relie on the User actually Selecting a thing (Mercy of UI Events, Focus, LostFocus)

How I would do it:

public void MyCoolMethod()
{
	EpiDataView dv = null;

	dv = oTrans.Factory("V_JobDashboard_1View1"); // My Main Grid
	System.Data.DataRow row_1View1 = dv.CurrentDataRow;

	dv = oTrans.Factory("V_JobDashboard_1View2");
	System.Data.DataRow row_1View2 = dv.dataView.Table.Select("MyKey1 = '{0}'", row_1View1["JobNum"].ToString())[0];

	dv = oTrans.Factory("V_JobDashboard_1View3");
	System.Data.DataRow row_1View3 = dv.dataView.Table.Select("MyKey1 = '{0}' and AnotherKey = '{1}'", row_1View1["JobNum"].ToString(), row_1View2["KeyFromTheSECONDGrid"].ToString() );

}
1 Like

You could even create a method that brings the bundle pack in a nice Dictionary


private Dictionary<string, DataRow[]> CreateParamsList(string whereClauseUD100A = "")
{
       EpiDataView dv1 = oTrans.Factory("V_JobDashboard_1View1"); // My Main Grid
       EpiDataView dv2 = oTrans.Factory("V_JobDashboard_1View2")
       EpiDataView dv3 = oTrans.Factory("V_JobDashboard_1View3")
       DataRow row_dv3 = dv3.CurrentDataRow;

	Dictionary<string, DataRow[]> dict = new Dictionary<string, DataRow[]>()
	{
		{ "MyGrid1", dv1.dataView.Table.Select() },
		{ "MyGrid2", dv2.dataView.Table.Select( String.Format("CheckBox10 = {0}", false) ) },
	};

	return dict;
}

Then you could call it from an event like AfterRowChanged (Just a sample with fake vars)

Dictionary<string, DataRow[]> dict = CreateParamsList();

if (dict.ContainsKey("MyGrid1"))
{
	List<string> whereClauseListSerial = new List<string>();
	DataRow[] serials = dict["MyGrid1"];

	foreach (var x in serials) {
		whereClauseListSerial.Add( string.Format("(SerialNumber = '{0}' AND PartNum = '{1}')", x["ChildKey5"].ToString(), x["smShortChar04_c"].ToString()) );
	}

	if (whereClauseListSerial.Count >= 1) {
		this.SearchOnSerialNoAdapterShowDialog( String.Join(" OR ", whereClauseListSerial.ToArray()) );
	}
}

The MyCoolMethod() in the previous post should suffice.

@hkeric.wci is there any epimagic on trying to use this with the RcvDtl dataset on Container Receipt. I keep getting a record not available error.
Here’s my snippet

EpiDataView edvRcvArrive = oTrans.Factory ("ArrivedRcvDtl");
DataTable dtf = edvRcvArrive.dataView.ToTable();

Infragistics.Win.UltraWinGrid.SelectedRowsCollection selectedRows;
selectedRows = epiUltraGridC2.Selected.Rows;
List<string> RcvLines = new List<string> ();
try
{
  foreach(UltraGridRow rowSelected in selectedRows)
	{
      RcvLines.Add(rowSelected.Cells["SysRowID"].Value.ToString());
	}
   

   foreach (string RcvLineSysRowID in RcvLines) 
	{ 
	string whereClause = string.Format("SysRowID = '{0}'", RcvLineSysRowID);
	MessageBox.Show(whereClause);
	DataRow editRow = edvRcvArrive.dataView.Table.Select(whereClause)[0];


		editRow.BeginEdit();
			editRow["Received"] = true;
			editRow["ReceivedComplete"] = true;
		editRow.EndEdit();
		oTrans.Update();
	}