DataView.Find problem

I am really pulling my hair out with this!  I want to find a record in DataTable dtSegDesc based on two fields, Segment_ID 

and Segment_Value ...


private void CheckDescriptions()
{
//This method is called when a new account is created to see if any segment values do
//not yet exist in the Acct_Segment_Description table.  If they don't they are created.

int intMyRow;
int intSegID;
object[] values = new object[2];

//The new account is currently in arySeg
Global.sbGlobalBar.Text = "Checking Subdivions ...";

dvSegDesc.Sort = "Segment_ID,Segment_Value";

//Loop through each segment of the new account
foreach(Segment segment in arySeg)
{
//Is this segment's value already in dtSegDesc

//Find out what the segment_id is for this segment_name
intMyRow = this.dvStructure.Find(segment.Name);

intSegID = Convert.ToInt32(dvStructure[intMyRow]["Segment_ID"]);

values[0] = intSegID;
values[1] = "" + segment.Value + "";

this.intRowIndex = dvSegDesc.Find(values);

if(intRowIndex == -1) //It is not.
{
//Add a new row to dtSegDesc
DataRow row = dtSegDesc.NewRow();

//Set the values for the new row
row.BeginEdit();
row["Segment_ID"] = Convert.ToInt32(dvStructure[intMyRow]["Segment_ID"]);
row["Segment_Value"] = segment.Value;
row.EndEdit();

dtSegDesc.Rows.Add(row);
}
}
}


The problem boils down to the line

this.intRowIndex = dvSegDesc.Find(values);

values is an array that holds the Segment_ID int value and the Segment_Value string value.  No matter how I put the values in 

value the Find method does not find records I know are there.

Am I missing something


Thank you.

jmatt


Answer this question

DataView.Find problem

  • DJ MCFLY - NY

    I think array declaration is different C# vs VB.net.

    In C# 

    int[] numbers = new int[2];

    Is an array of two intgers, numbers[0] and numbers[1]

    In VB.net

    Dim numbers(2) AS int

    Is and array of three integers, numbers[0] numbers[1] and numbers[2]

    In C# [2] is the number of elements where in VB.net it is the upper bound.

    I tried first segment does and does not exist with and without dtSegDesc.AcceptChanges().  It always fails on the second iteration!

    jmatt

  • mBurger

    Well, assuming it's the same across languages, the code:
    object[] values = new object[2]; 

    Should create an Object Array with a length of three (0,1,2).  In VB the declaration would be:

    Dim values(2) As Object

    This would create an array with three Objects...  value(0), value(1), and value(2)  I'm sure this is the same in C...

    So first, try changing your code to:

    object[] values = new object[1]


    Also, does the code always fail on the second and subsequent itterations   Or does it only fail after you insert a new row   That is; if the first segment does exist but the second and third do not, does the code work for the second and not the third, or does it fail for both

    What I'm getting at here is that you may need to call AcceptChanges on your table after adding a row before the dataview will work properly again.

    Check those things and if you still have the problem, post back!

  • Mal555

    Doesn't

    object[] values = new object[2];

    create an array for two objects

    All the quotes was me flailing around to make sure I was passing in values correctly!


    What I have found out after some changes to the previous code ...

    dvSegDesc.Find(values) works the first time through the loop, that is it finds the record with the supplied Segment_ID and Segment_Value.  It fails from there on even though I check values[0]  and values[1] in the Immediate Window and they are correct and exist in dvSegDesc the Find method returns -1!!!!  Any thoughts on what I am doing wrong

    foreach(Segment segment in arySeg)
    {
    //Is this segment's value already in dtSegDesc

    //First find out what the segment_id is for this segment_name
    intMyRow = this.dvStructure.Find(segment.Name);
    intSegID = Convert.ToInt32(dvStructure[intMyRow]["Segment_ID"]);

    //Get the values into an array
    values[0] = intSegID;
    values[1] = segment.Value;


    this.intRowIndex = dvSegDesc.Find(values);


    if(intRowIndex == -1) //It is not.
    {
    //Add a new row to dtSegDesc
    DataRow row = dtSegDesc.NewRow();

    //Set the values for the new row
    row.BeginEdit();
    row["Segment_ID"] = intSegID;
    row["Segment_Value"] = segment.Value;
    row.EndEdit();

    dtSegDesc.Rows.Add(row);
    }
    }

    Thank you
    jmatt

  • Davy Van Melkebeke

    <b>edited by KraGiE: please use code blocks to make it readable.</b>

    OK I gave up my first approach and did this:

    private void CheckDescriptions()
    {
    int intMyRow;
    int intSegID;

    //Loop through each segment of the new account
    foreach(Segment segment in arySeg)
    {
    //First find out what the segment_id is for this segment_name
    intMyRow = this.dvStructure.Find(segment.Name);
    intSegID = Convert.ToInt32(dvStructure[intMyRow]["Segment_ID"]);

    //Filter DataView dvSegDesc by Segment_ID
    dvSegDesc.RowFilter = "Segment_ID = '" + intSegID + "'";

    //Look for Segment_VAlue in the filtered DataView
    dvSegDesc.Sort = "Segment_Value";
    intRowIndex = dvSegDesc.Find(segment.Value);

    if(intRowIndex == -1) //It is not there so add it to dtSegDesc.
    {
    //Add a new row to dtSegDesc
    DataRow row = dtSegDesc.NewRow();

    //Set the values for the new row
    row.BeginEdit();
    row["Segment_ID"] = intSegID;
    row["Segment_Value"] = segment.Value;
    row.EndEdit();

    dtSegDesc.Rows.Add(row);
    }
    }


    if(this.dsAccounts.HasChanges(DataRowState.Added))
    {
    try
    {
    this.daSegDesc.Update(dsAccounts,dtSegDesc.ToString());
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
    }

    //Remove filter and return to original sort
    this.dvSegDesc.RowFilter = null;
    this.dvSegDesc.Sort = "Segment_Value";
    }

    First filter the DataView by Segment_ID and then look for Segment_Value.  
    This does what I want.

    I think the first approach is buggy!

    Thanks for the help!

    jmatt

  • ampijanka

    Is it becuase Values() has a length of 3 and there are only two values to compare   When you pass Values() to Find() it contains three objects:  intSegID, segment.Value, and Nothing.

    Wait, also, what's with:  values[1] = "" + segment.Value + "";    Are there supposed to be single quotes between those double quotes   

  • Ferry Lukito

    As I look into it what I describe was true for VB6.  I believe VB.net arrays work the same as C# arrays   I am not a VB.net programmer.

    jmatt

  • DataView.Find problem