Hello,
I am writing code to process part numbers from a digital scanner. The digital scanner reads part numbers on a label and if the part is listed in the "datagridview" display of the program then it stores them as "scanned" (not shown here) but if they are not found then it returns an error. This code is designed to catch some of the common errors the scanner sometimes makes to prevent the amount of times the user needs to manually correct it.
I have created a fairly nested loop to accomplish this which may become an issue if there are large sets of data for the system to process. If anyone is able to provide a second set of eyes or some advice on how to optimize this code, I would greatly appreciate your thoughts.
int index;
index = 0;
string[] rejected = new string[10];
foreach (DataGridViewRow row in dgView.Rows)
{
Fix:
if ((string)row.Cells[1].Value != txtScannedIn.Text.Trim())
{
string editedtext;
string originaltext;
originaltext = txtScannedIn.Text.Trim();
editedtext = ScanFix(txtScannedIn.Text, rejected);
if ((string)row.Cells[1].Value == editedtext)
{
MessageBoxButtons buttons = MessageBoxButtons.YesNoCancel;
DialogResult result = MessageBox.Show("Unfound scan " + originaltext + " was autocorrected to " + editedtext + "\n" + "\n" + "Press enter to confirm this change" + "\n" + "Press No suggest new part" + "\n" + "Press Cancel to exit dialog", "Suggested Replacement", buttons);
if (result == DialogResult.Yes)
{
txtScannedIn.Text = editedtext;
}
else if (result == DialogResult.No)
{
rejected[index] = editedtext;
index++;
goto Fix;
}
else if (result == DialogResult.Cancel)
{
break;
}
}
}
Below is the actual method that fixes the scan. Essentially, it loops through the datagrid and uses a Damerau-Levenshtein string distance algorithm "StringDistance" to determine how many changes away the not found scan is from one in the grid. There are two foreach loops so that it first scans and returns for 1 character replacements and then 2 character ones. If anyone has any advice on a potentially more efficient way to accomplish this I would greatly appreciate your help.
public string ScanFix(string NotFound, string[] rejected)
{
foreach (DataGridViewRow row in dgView.Rows)
{
int guess;
guess = StringDistance(NotFound, (string)row.Cells[1].Value);
if (guess <= 1 && Array.Exists(rejected, element => element == (string)row.Cells[1].Value) == false)
{
return (string)row.Cells[1].Value;
}
if (NotFound.Contains((string)row.Cells[1].Value) && Array.Exists(rejected, element => element == (string)row.Cells[1].Value) == false)
{
return (string)row.Cells[1].Value;
}
}
foreach (DataGridViewRow row in dgView.Rows)
{
int secondguess;
secondguess = StringDistance(NotFound, (string)row.Cells[1].Value);
if (secondguess <= 2 && Array.Exists(rejected, element => element == (string)row.Cells[1].Value) == false)
{
return (string)row.Cells[1].Value;
}
}
return NotFound;
}
What I have tried:
I have tried creating a separate method for the section of the first block of code that requires the user to confirm the corrected scan, however I don't think this will make it run faster since it requires so many parameters to be passed to it.
I have done extensive research on ways to optimize code/make it run faster but I have been unable to find ways to minimize nested loop usage in either of these code blocks without sacrificing features. I am fairly new to coding and am fully self taught, so I greatly appreciate any and all advice or tips for this code specifically or perhaps something I can look into to learn more about code optimization.
Thank you very much!