Home > Enterprise >  Comparing two DataGridViews and deleting the values of the second if exists in the first one
Comparing two DataGridViews and deleting the values of the second if exists in the first one

Time:08-27

I am doing a code where I compare two columns of DGV roles, the first DGV (DGV1) has the raw data with duplicate roles, and the second DGV (DGV4) is a dictionary with all existing roles (no duplicates), it has to go to each row of the dictionary and if the role exists in the DGV1, it should be removed from the dictionary, leaving only the roles in the dictionary that are not currently being used in the raw data. My code is removing the roles, but when the dictionary has a value that doesn't exist in DGV1, it stops working (DGV1 continues to loop until it has an index error). Any suggestion?

NOTE: The rows in the dictionary automatically go to the first index, so there is no need to increment int i.

int eliminado = 0;
int filasDGV1 = dataGridView1.Rows.Count;
int filasDGV4 = dataGridView4.Rows.Count;
int i = 0;
int j = 0;

do
{
    string perfilVacio = dataGridView4["GRANTED_ROLE", i].Value.ToString();
    string perfiles = dataGridView1["GRANTED_ROLE", j].Value.ToString();
    if(perfiles != perfilVacio)
    {
        j  ;
    }
    else if(perfiles == perfilVacio)
    {
        dataGridView4.Rows.RemoveAt(i);
    }

}
while (eliminado <= filasDGV4);

The first excel is DGV1 and the other is DGV2, I highlighted where is the code looping currently

The orange highlight is where the loop change in DGV1 but in the dictionary doesnt exist so its stuck there

CodePudding user response:

Change your loop condition to include a test for the changing index j and also to check whether there are rows left to be eliminated.

int filasDGV1 = dataGridView1.Rows.Count;
int j = 0;

while (j < filasDGV1 && dataGridView4.Rows.Count > 0)
{
    string perfilVacio = dataGridView4["GRANTED_ROLE", 0].Value.ToString();
    string perfiles = dataGridView1["GRANTED_ROLE", j].Value.ToString();
    if(perfiles == perfilVacio)
    {
        dataGridView4.Rows.RemoveAt(0);
    }
    else
    {
        j  ;
    }
}

If you test perfiles != perfilVacio in if you don't have to test perfiles == perfilVacio in else if, because this automatically the case. Either they are equal or they are not. There no other possibility.

Also, it is generally more readable if you ask a positive question in if like == instead of a negative one like !=.

Since i is always 0 I replaced it by the constant 0. The variable eliminado is not required (unless it is incremented when rows are removed to display the number of deleted rows).

The number of rows in dataGridView4 should not be stored in filasDGV4 as this number changes.


Update

According to your comments and the new screenshots, you need two loops. We could use two nested loops; however, this is slow. Therefore, I suggest collecting the unwanted roles in a HashSet<string> first. Testing whether an item is in a HashSet is extremely fast. Then we can loop through the rows of the dictionary and delete the unwanted ones.

var unwanted = new HashSet<string>();
for (int i = 0; i < dataGridView1.Rows.Count: i  )
{
    unwanted.Add(dataGridView1["GRANTED_ROLE", i].Value.ToString());
}

int row = 0;
while (row < dataGridView4.Rows.Count)
{
    string perfilVacio = dataGridView4["GRANTED_ROLE", row].Value.ToString();
    if(unwanted.Contains(perfilVacio))
    {
        dataGridView4.Rows.RemoveAt(row);
    }
    else
    {
        row  ;
    }
}

Suggestion: Using data binding to bind your DataGridViews to generic lists would enable you to work on these lists instead of working on the DGVs. This would simplify the data handling considerably.

  • Related