Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 计算UPC-A条形码的校验位_C#_Visual Studio 2010_Check Digit - Fatal编程技术网

C# 计算UPC-A条形码的校验位

C# 计算UPC-A条形码的校验位,c#,visual-studio-2010,check-digit,C#,Visual Studio 2010,Check Digit,我目前正在VS2010中开发一个windows窗体,该窗体应该为新零件号创建UPC-a并将其存储在数据库中。到目前为止,我仍在试图把这些碎片拼凑起来,但我在计算支票数字时遇到了问题。我提出了以下两种情况: 场景1:按照我们目前在Excel中的方式进行计算: string value = uPCDataSet.UPC.Rows[uPCDataSet.UPC.Rows.Count - 1]["UPCNumber"].ToString(); string manCode = value.Substri

我目前正在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来说太大或太小”。我不明白为什么,因为“value”是一个包含12个字符的
varchar
(它们都是数字)

场景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。 我花了差不多一整天的时间在这上面,我需要一些建议。为什么我在第一个场景中得到了错误,为什么我在第二个场景中得到了与应该得到的不同的校验位

提前感谢您的帮助

克里斯

编辑:

我删除了之前的两次编辑,因为代码有缺陷,我没有得到正确的结果。我发现我们使用的是杜鹃花条形码,它们有自己的计算校验位的方法(参见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);

如果
value
是一个12位长的字符串,那么它太大,无法放入
int
中。根据我所读到的第一个例子中计算错误的情况,使用
长的

  • String.Substring
    +
    String.Substring
    或“1”+“1”=“11”。你是 寻找1+1=2。您需要先将每个子字符串转换为int 添加

二进制+运算符是为数字和字符串类型预定义的。对于 数值类型,+计算其两个操作数之和。当一个或多个 两个操作数都是字符串类型,+连接字符串 操作数的表示形式

  • String.Substring
    基于0,因此缺少
    String.子字符串(0,1)
    用于偶数数字

startIndex:子字符串的从零开始的字符位置 在这种情况下

  • 您的校验位字符串尝试获取小于12位的字符串的第12位。此外,这不是链接中显示的计算。它正在寻找这个数字的10-10模。这也发生在更新的编辑行中
string chkDigit=((300-chkDigitSubtotal).ToString()).Substring(12,1)

您正试图从第12个0字符中获取
子字符串,或从第13个字符中获取长度为1的子字符串。但是,chkDigitSubtotal的值不会太大/太长

至于您的错误,正如Golden Dragon在其回答中所述,您正在将一个12字符的字符串转换为一个数字,该字符串不适合
Int32
,您应该使用长字符串

int first = Math.Abs(Convert.ToInt32(value));

long first = Math.Abs(Convert.ToInt64(value));
首先,我会检查您的计算是否在前面的步骤中正常运行

更新

在编辑2中,最后一行的变量看起来是反向的。您希望取109除以10的余数(即9),代码取10除以109的余数(即0),因此进行更改

chkDigitSubtotal = 10 - (10 % (chkDigitEven + chkDigitOdd));


现在10-9=1,这是您的校验位。

我不知道您的问题的答案,但C#没有一个称为“varchar”的类型。这听起来像是数据库中的一种类型。Int32可以处理从-2147483648到+2147483647的数字,虽然它是一个10位数的数字,但不支持所需的完整范围。加上支票数字,你需要11个数字。尝试使用
Decimal
类型,它支持28位数字。@Steve,varchar确实是SQL数据库中“value”的字段类型。我会查一下十进制数,看看它是否能帮我找到答案。谢谢你的提示!一旦将值从数据库加载到.NET程序中,就可以使用.NET CLR类型。顺便说一句,这里是C#中的值类型列表:在计算
chkDigitSubtotal
(在第一个示例中)时,添加6个1位字符串并将其转换为数字。最多可能是999999。然后乘以3=299997,再加上一个5位数的字符串,最大值为99999=309996。现在取这个值,从300=-3099696中减去它。我看到8个字符,包括减号(不包括逗号)。我不确定你将如何接受8个字符长的字符串的第12个字符?我算错了吗?非常有用!谢谢你的详细回答,我想我对该做什么有了更好的想法。我更新了代码,但现在得到了一个完全不同的错误。有什么想法吗?@campagnolo_1我在答案上加了一行,告诉你为什么会有错误。找到答案了。谢谢你的帮助@campagnolo_1很高兴我能帮上忙。我真的很感激你不仅给了我代码,还指出了我的缺陷,并为我提供了研究资源。干杯
chkDigitSubtotal = 10 - ((chkDigitEven + chkDigitOdd) % 10);