我目前正在使用 VS2010 中的 Windows 窗体,该窗体应该为新部件号创建 UPC-A 并将它们存储在数据库中。到目前为止,我仍在尝试将这些部分组合在一起,并且在计算校验位时遇到了问题。我想出了以下两种情况:
场景 1:按照我们目前在 Excel 中执行的方式进行计算:
string value = uPCDataSet.UPC.Rows[uPCDataSet.UPC.Rows.Count - 1]["UPCNumber"].ToString();
string manCode = value.Substring(1, 5);
string prodCode = value.Substring(7, 5);
int first = Math.Abs(Convert.ToInt32(value));
while (first >= 10)
first /= 10;
int chkDigitSubtotal;
string UPCNumber = first + manCode + prodCode;
chkDigitSubtotal = Convert.ToInt32((UPCNumber.Substring(1, 1)) + (UPCNumber.Substring(3, 1)) +
(UPCNumber.Substring(5, 1)) + (UPCNumber.Substring(7, 1)) + (UPCNumber.Substring(9, 1)) +
(UPCNumber.Substring(11, 1)));
chkDigitSubtotal = (3 * chkDigitSubtotal) + Convert.ToInt32((UPCNumber.Substring(2, 1)) +
(UPCNumber.Substring(4, 1)) + (UPCNumber.Substring(6, 1)) + (UPCNumber.Substring(8, 1)) +
(UPCNumber.Substring(10, 1)));
string chkDigit = ((300 - chkDigitSubtotal).ToString()).Substring(12, 1);
运行此代码时,我收到错误消息“对于 Int32,值太大或太小”。我不明白为什么因为“值”是varchar
12 个字符(它们都是数字)。
场景2:我在网上找到了一段代码。此代码有效,但给了我错误的校验位。我正在使用我们使用您的 Excel 工作表计算的 UPC:
string value = "606891001678"; //valid UPC with check digit
string UPCBody = value.Substring(0, 11);
int sum = 0;
bool odd = true;
for (int i = value.Length - 1; i >= 0; i--)
{
if (odd == true)
{
int tSum = Convert.ToInt32(value[i].ToString()) * 2;
if (tSum >= 10)
{
string tData = tSum.ToString();
tSum = Convert.ToInt32(tData[0].ToString()) + Convert.ToInt32(tData[1].ToString());
}
sum += tSum;
}
else
sum += Convert.ToInt32(value[i].ToString());
odd = !odd;
}
int result = (((sum / 10)+1) *10) - sum;
result = result % 10;
MessageBox.Show(UPCBody + " & " + result);
在这个例子中,校验位显然应该是 8,但它返回 2。我在这上面花了几乎一整天的时间,可以使用一些建议。为什么我在第一种情况下会收到错误,为什么在第二种情况下我会收到与应有的不同的校验位?
在此先感谢您的帮助!
克里斯
编辑:
我删除了之前的两次编辑,因为代码存在缺陷,从某种意义上说我没有得到正确的结果。我发现我们使用 Azalea 条形码,他们有自己的计算校验位的方法(参见 ChkDigitSubtotal)。所以下面的代码有效,并为我的场景提供了正确的校验位。我认为对于所有 UPC-A 计算,此代码将适用于 chkDigitSubtotal。感谢哈里森的出色指导和足智多谋的回答!
string value = uPCDataSet.UPC.Rows[uPCDataSet.UPC.Rows.Count - 1]
["UPCNumber"].ToString();
long chkDigitOdd;
long chkDigitEven;
long chkDigitSubtotal;
string UPCNumber = value.Substring(0, 11);
chkDigitOdd = Convert.ToInt64(UPCNumber.Substring(0, 1)) +
Convert.ToInt64(UPCNumber.Substring(2, 1)) + Convert.ToInt64(UPCNumber.Substring(4, 1))
+ Convert.ToInt64(UPCNumber.Substring(6, 1)) + Convert.ToInt64(UPCNumber.Substring(8,
1)) + Convert.ToInt64(UPCNumber.Substring(10, 1));
chkDigitOdd = (3 * chkDigitOdd);
chkDigitEven = Convert.ToInt64(UPCNumber.Substring(1, 1)) +
Convert.ToInt64(UPCNumber.Substring(3, 1)) + Convert.ToInt64(UPCNumber.Substring(5, 1))
+ Convert.ToInt64(UPCNumber.Substring(7, 1)) + Convert.ToInt64(UPCNumber.Substring(9,
1));
chkDigitSubtotal = (300-(chkDigitEven + chkDigitOdd));
string chkDigit = chkDigitSubtotal.ToString();
chkDigit = chkDigit.Substring(chkDigit.Length - 1, 1);