私は現在、新しい部品番号の UPC-A を作成し、それらをデータベースに保存することになっている VS2010 の Windows フォームに取り組んでいます。これまでのところ、私はまだピースをまとめようとしており、チェック ディジットの計算に問題があります。次の 2 つのシナリオを思いつきました。
シナリオ 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 が返されます。これにほぼ 1 日を費やしたので、アドバイスが必要です。最初のシナリオでエラーが発生するのはなぜですか? また、2 番目のシナリオで本来あるべきものとは異なるチェック ディジットが表示されるのはなぜですか?
よろしくお願いします。
クリス
編集:
正しい結果が得られなかったという意味でコードに欠陥があったため、以前の 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);