0 Try replacing this code:
foreach (string x in serialNumberArray)
{
if (!x.Contains(new string(serialNumber)))
{
Enter_count++;
sevenSegmentArrayActual.Value = Enter_count.ToString();
sevenSegmentArrayDifference.Value = (Convert.ToInt32(sevenSegmentArrayTarget.Value) - Convert.ToInt32(sevenSegmentArrayActual.Value)).ToString();
SaveSerialNumber(new string(serialNumber));
digit_count = 0;
Array.Clear(serialNumber, 0, 14);
}
}
with this:
string sn = new string(serialNumber);
if (!serialNumberArray.Contains(sn))
{
Enter_count++;
sevenSegmentArrayActual.Value = Enter_count.ToString();
sevenSegmentArrayDifference.Value = (Convert.ToInt32(sevenSegmentArrayTarget.Value) - Convert.ToInt32(sevenSegmentArrayActual.Value)).ToString();
SaveSerialNumber(sn);
}
digit_count = 0; // need to reset whether s/n duplicated or not
Array.Clear(serialNumber, 0, 14);
Accepted 1 There's definitely a problem when digit_count gets to 14 if the user then presses another digit key rather the ENTER key. I see you've tried to patch it by including a try/catch but I think it needs rewriting.
It's difficult to be sure whether this is all that's wrong but try changing this part of the code:
private void HookManager_KeyUp(object sender, KeyEventArgs e)
{
if ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) || (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9))
{
try
{
serialNumber[digit_count] = DigitFromKeyCode(e.KeyCode);
}
catch (System.IndexOutOfRangeException e1)
{
MessageBox.Show("A non-14 Serial Number is entered",e1.Message); // more than 14-digit is entered
}
digit_count++;
if (digit_count > 14)
{
digit_count = 0;
Array.Clear(serialNumber, 0, 14);
}
}
else if (e.KeyCode == Keys.Enter && digit_count == 14)
{
// etc
to this:
private void HookManager_KeyUp(object sender, KeyEventArgs e)
{
if ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) || (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9))
{
if (digit_count == 14) // if it's already got to 14 start again at 0
{
digit_count = 0;
Array.Clear(serialNumber, 0, 14);
}
serialNumber[digit_count] = DigitFromKeyCode(e.KeyCode);
digit_count++;
}
else if (e.KeyCode == Keys.Enter && digit_count == 14)
{
// etc
1 The problem is that you're still incrementing the count even if the key pressed is not ENTER.
Try it like this:
private int count = 0; // best to start at 0 in case ENTER never pressed
private void HookManager_KeyUp(object sender, KeyEventArgs e)
{
Log(string.Format("KeyUp \t\t {0}\n", e.KeyCode));
if (e.KeyCode == Keys.Enter)
{
count++;
Count_textBox.Text = count.ToString();
}
}
0 thanks for the quick update.
0 Hi Vuples,
I attached the code, and it seems to have some bugs which is not easy to trace. Most of the time, when a less than 14-digits is entered, it is not captured, which is correct.
But there are some few rare instances when a less than 14-digits is entered, it is captured, as seen in the output file as attached.
Those less than 14-digits serial numbers should not be captured in the output file:
06-Jun-13 10:31:11 AM 40000022492
06-Jun-13 10:32:01 AM 400000224922
06-Jun-13 10:32:21 AM 4000002249224
06-Jun-13 10:33:50 AM 4000002249225
6/6/2013 11:00:56 AM 99999999999
thank you in advance
0 BRAVO. You save my day. I owe you a lot :) thanks.
0 Hi Vulpes,
Next, I want to make sure that no repeat of the 14-digit SerialNumber is stored in the output.txt file. Also, if the same serial number is entered again, the counter does not increase.
I try with the attached code, but it does not work. Would need your help again :)
0 Hi Vulpes, thanks again for your professional code which works perfectly to my requirements.
I appreciate your kind help a lot. :)
0 You'll need to change that method slightly to append to the file, otherwise the file will be overwritten:
private void SaveSerialNumber(string SerialNumber)
{
TextWriter tw = new StreamWriter("Output.txt", true);
tw.WriteLine(string.Concat(DateTime.Now, "", SerialNumber));
tw.Close();
}
The previous code then needs changing to:
private int count = 0;
private int digits = 0;
private char[] serialNumber = new char[14]; // field to store digits entered
private void HookManager_KeyUp(object sender, KeyEventArgs e)
{
Log(string.Format("KeyUp \t\t {0}\n", e.KeyCode));
if ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) ||
(e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9))
{
serialNumber[digits] = DigitFromKeyCode(e.KeyCode);
digits++;
if (digits > 14)
{
digits = 0;
Array.Clear(serialNumber, 0, 14);
}
}
else if (e.KeyCode == Keys.Enter && digits == 14)
{
count++;
label1.Text = count.ToString();
SaveSerialNumber(new string(serialNumber));
digits = 0;
Array.Clear(serialNumber, 0, 14);
}
else if (e.KeyCode == Keys.Back)
{
if (digits > 0)
{
digits--;
serialNumber[digits] = '\0';
}
}
else
{
digits = 0;
Array.Clear(serialNumber, 0, 14);
}
}
// add this method to extract digit from KeyCode
private char DigitFromKeyCode(Keys k)
{
string temp = k.ToString();
if (temp[0] == 'D' && temp.Length == 2)
{
return temp[1];
}
else if (temp.StartsWith("NumPad") && temp.Length == 7)
{
return temp[6];
}
else
{
return '\0';
}
}
0 Hi Vulpes, thanks again for your wonderful code added. Another small request...at each count, I want to save those 14-digit serial number to a file, is it possible?
that is, I want to call this function
private void SaveSerialNumber(string SerialNumber)
{
TextWriter tw = new StreamWriter("Output.txt");
tw.WriteLine(string.Concat(DateTime.Now, "", SerialNumber));
tw.Close();
}
0 That's trickier :)
You need to add another field to count the digits entered and, if that has reached 14 when the ENTER key is pressed, increment the main count otherwise reset the digit count to zero and start again.
The problem is what to do when other keys are pressed. You could take a strict view on this and reset the digit count to zero if any other key is pressed at all!
This is fair enough for 'printing' characters such as letters and punctuation but what about non-printing characters such as the arrow keys etc?
It seems reasonable to at least allow the BACKSPACE key to be pressed to enable the user to correct what's already been entered and the following code therefore does that (decrementing the digit count if it's more than zero) but resets to zero if any other key is pressed at all:
private int count = 0;
private int digits = 0; // counts consecutive digits pressed
private void HookManager_KeyUp(object sender, KeyEventArgs e)
{
Log(string.Format("KeyUp \t\t {0}\n", e.KeyCode));
if ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) || (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9))
{
digits++;
if (digits > 14) digits = 0; // too many digits entered
}
else if (e.KeyCode == Keys.Enter && digits == 14)
{
count++; // increment main counter
Count_textBox.Text= count.ToString();
digits = 0; // reset digit counter
}
else if (e.KeyCode == Keys.Back)
{
if (digits > 0) digits--; // decrement digit counter if backspace pressed
}
else
{
digits = 0; // if any other key pressed, reset digit counter
}
}
0 sorry Vulpes, I need an additional requirement such that ONLY if there is a 14 digit number in front of the ENTER, then it would add to the count variable. How should I modify the code then?
0 thank you very much Vulpes, I always look forward for your precise answer.