EAN-13 Check Digit Calculator

I am trying to write a method that returns the check digit for EAN-13 barcodes but I need to be able to round a number UP to the nearest 10 but I am really struggling to get it to work. Anyone clever out their who can help with this.

For example 21 would return 30, 38 would return 40 etc.

Function RoundUp(Value As Integer) As Integer Dim i As Integer = ((value / 10) + 0.9) Return i * 10 End Function

Thanks Wayne, that is perfect, exactly what I needed.

i= Ceil(a/10)*10

I had to look up the Ceil function as I havent used that in years, interesting, may need to use that for rounding decimals in future. Thanks.

In case anyone is interested, here is the function I created to calculate the EAN-13 check digit, I know it could be written much cleaner :wink:

[code]function GetEAN13CheckDigit(barcode as String) as Integer
if len(barcode)<>12 then
return -1
else
dim result as integer = 0
dim calc as integer = 0
dim n as integer = 0
dim roundedResult as integer = 0

for lp as integer = 1 to 12
  if (lp mod 2)=0 then
    calc = val(mid(barcode, lp, 1)) * 3
  else
    calc = val(mid(barcode, lp, 1)) * 1
  end if
  result = result + calc
next

roundedResult = Ceil(result/10)*10

return roundedResult - result

end if
end function[/code]

@Wayne Golding , You are aware that your solution only works correctly with positive numbers?
-125 returns -110 but should be -120. The Ceil-function returns the right number.

@Nathan Wright , please keep in mind that negative numbers return the largest negative number that fits within the value of the parameter, that’s why -120 should be returned in the above example.
If you want the result to be -130 then use the Floor function.

Thanks Andre, for EAN-13 that should not be an issue because the number will never be negative but useful for me to remember that for future.

@Nathan Wright , I was thinking of your earlier remark to use it for rounding decimals.

Ah, that makes sense :wink:

[quote=88915:@Nathan Wright]I am trying to write a method that returns the check digit for EAN-13 barcodes but I need to be able to round a number UP to the nearest 10 but I am really struggling to get it to work. Anyone clever out their who can help with this.

For example 21 would return 30, 38 would return 40 etc.[/quote]

@Nathan - I actually just posted my barcodes module :slight_smile: Since you already own SimDesignerCanvas, it comes as part of the package. The version in the forums is a trial for other scanners to be tested. But if you’d like the release version early, I’d be glad to forward that to you.

thank I used

the MBS Barcode generator class has a few checksum calculation functions, too:

http://www.monkeybreadsoftware.net/class-barcodegeneratormbs.shtml

[quote=248906:@Christian Schmitz]the MBS Barcode generator class has a few checksum calculation functions, too:

http://www.monkeybreadsoftware.net/class-barcodegeneratormbs.shtml[/quote]

I can highly recommend it. My Barcode Designer is using it too. And as you can see in the Screenshots, it’s displaying the Checksum too.

Please forgive the question coming from one who knows next to nothing on this subject: how does the GetEAN13CheckDigit function work? I mean: what hardware is needed and how to interact with it?
Thanks.

This reminds me to an helper App I’ve once made couple of years for a customer… his internal ProductNumbers and Packages should be recocnized by Handscanners. I’ve used a free EAN13 TrueType Font and made this small helper App to convert the Numbers into printable string. Something like “4260341230320” became “4CQADOL*cdadca+” and was saved side-by-side in his database. Was a challange to find out the algorithm but I remember it sounded more complicated than it really was.

Here’s a Screenshot of this little App.

The conversion algorithm is here:

  
function MakeEAN(ProductNumber as String) as String
  
  Dim i, checksum, first as integer
  dim CB, ean13 as String
  dim tableA As Boolean
  
  ean13 = ""
  
  If ProductNumber.len = 13 Then
    
    For i = 1 To 12
      If Asc(Mid(ProductNumber, i, 1)) < 48 Or Asc(Mid(ProductNumber, i, 1)) > 57 Then
        i = 0
        Exit For
      End If
    Next
    
    If i = 13 Then
      
      For i = 12 DownTo 1 Step -2
        checksum = checksum + Val(Mid(ProductNumber, i, 1))
      Next
      checksum = checksum * 3
      For i = 11 DownTo 1 Step -2
        checksum = checksum + Val(Mid(ProductNumber, i, 1))
      Next
      ProductNumber = ProductNumber + chr((10 - checksum Mod 10) Mod 10)
      
      CB = Left(ProductNumber, 1) + Chr(65 + Val(Mid(ProductNumber, 2, 1)))
      first = Val(Left(ProductNumber, 1))
      
      For i = 3 To 7
        tableA = False
        Select Case i
        Case 3
          Select Case first
          Case 0 To 3
            tableA = True
          End Select
        Case 4
          Select Case first
          Case 0, 4, 7, 8
            tableA = True
          End Select
        Case 5
          Select Case first
          Case 0, 1, 4, 5, 9
            tableA = True
          End Select
        Case 6
          Select Case first
          Case 0, 2, 5, 6, 7
            tableA = True
          End Select
        Case 7
          Select Case first
          Case 0, 3, 6, 8, 9
            tableA = True
          End Select
        End Select
        
        If tableA Then
          CB = CB + Chr(65 + Val(Mid(ProductNumber, i, 1)))
        Else
          CB = CB + Chr(75 + Val(Mid(ProductNumber, i, 1)))
        End If
        
      Next
      
      // Add middle separator
      CB = CB + "*"  
      
      For i = 8 To 13
        CB = CB + Chr(97 + Val(Mid(ProductNumber, i, 1)))
      Next
      
      // Add end mark
      CB = CB + "+"   
      ean13 = CB
      
    End If
  End If
  
  return ean13
  
end function