Codici a barre - Seconda parte (EAN 8 ed EAN 13) Inviato da Roberto venerdì 23 maggio 2008 Ultimo aggiornamento domenica 25 maggio 2008 Il Blog di Excelvba Come promesso, ecco il codice EAN nelle sue varianti EAN 8 ed EAN 13. Il codice à pronto per essere incollato in un modulo standar del vostro progetto VBA. Per la comprensione del suo funzionamento ho usato questa fonte: http://it.wikipedia.org/wiki/european_article_number Un unica nota negativa à che il testo del codice a barre andrebbe stampato con il tipo carattere OCR-B, non disponibile in Excel, quindi ho utilizzato Arial. Un saluto r   Progetto VBA di Roberto Mensa (nickname r) Codice a Barre tipi EAN 8 e EAN 13 Soluzioni di scrittura di codici a barre in Excel e Word utilizzando i font in dotazione o immagini prodotte in Excel In particolare ci si riferisce ai codici a barre tipo: - EAN 8 - EAN 13
Il modulo comprende funzioni per il calcolo e/o la verifica dei check digit oltre a funzioni per la codifica e decodifica in scrittura o in lettura dei codici EAN Indice delle routine: - StampaCodEan - ScriviCodEan - CreaImmagineCodEAN - CheckDigitEan_8_13 - EANCodifica - VerificaTestoCodEan - EsempioTest  Sub StampaCodEan(ByVal Testo As String, _  ByVal NumeroEAN As Long, _  Optional ByRef Rng As Range)     Consente la stampa di codici a barre di tipo: - EAN 8 - EAN 13 Testo à il testo da codificare. NumeroEAN indica il tipo di EAN pu㲠avere valore 8 o 13
Il parametro opzionale viene utilizzato in questo modo: - Se Rng à omesso verrã chiamata la routine   CreaImmagineCodEAN che restituisce una immagine del   codice a barre. - Se viceversa Rng indica una cella verrã chiamata la   routine ScriviCodEan che utilizzando il font   "Playbill" scriverã nella cella il codice a barre   senza il numero sotto. Utilizza anche le funzione: - VerificaTestoCodEan - CheckDigitEan_8_13 Dim StrBin As String Dim numcar As Long Dim TempS As String Dim ArrColor() As Boolean Dim B As Long Dim T As Long Dim Z As Long If VerificaTestoCodEan(Testo) Then _    Err.Raise 1001,, _ "Nel testo: " & Testo & Chr(13) & _ "hai usato caratteri non validi!" & _ Chr(13) & _ "Caratteri ammessi: " & _ Chr(13) & _ "0 1 2 3 4 5 6 7 8 9" Select Case NumeroEAN    Case 8 Select Case Len(Testo)
Case 7     Testo = Testo & _  CheckDigitEan_8_13(Testo) Case 8     If CheckDigitEan_8_13(Testo, True) = False Then  Err.Raise 1001,, _  "Carattere di controllo non valido!"     End If Case Else     Err.Raise 1001,, _     "Il testo che hai usato ha " & _     Len(Testo) & _     " caratteri!" & _     Chr(13) & _     "Il testo deve essere di 7 " & _     " o 8 caratteri (se giã " & _     "comprensivo di codice di controllo!" End Select StrBin = EANCodifica(Testo, 8)    Case 13 Select Case Len(Testo) Case 12     Testo = Testo & _  CheckDigitEan_8_13(Testo)      StrBin = EANCodifica(Testo, 13) Case 13     If CheckDigitEan_8_13(Testo, True) Then  StrBin = EANCodifica(Testo, 13)     Else  Err.Raise 1001,, _  "Carattere di controllo errato!"
    End If Case Else     Err.Raise 1001,, _     "Il testo che hai usato ha " & _     Len(Testo) & _     " caratteri!" & _     Chr(13) & _     "Il testo deve essere di 12 " & _     " o 13 caratteri (se giã " & _     "comprensivo di codice di controllo!" End Select    Case Else    End Select  If Rng Is Nothing Then    Call CreaImmagineCodEAN(StrBin, _      NumeroEAN, _      Testo, _      ActiveWorkbook)    ActiveSheet.Paste Else    If Rng.Count = 1 Then Call ScriviCodEan(Testo, _  Rng, _  NumeroEAN, _  StrBin)    Else Err.Raise 1001,, "Rng deve indicare" & _      "una cella singola!"    End If
 End If End Sub Sub ScriviCodEan(ByVal Testo As String, _  ByRef Rng As Range, _  ByVal NumeroEAN As Long, _  ByRef StrBin As String) Utilizzando il font "Playbill" scrive in Rng il codice a barre senza numero. Dim StrBin As String Dim numcar As Long Dim TempS As String Dim T As Long Dim Bc As String Dim Z As Long Const FontBC As String = "Playbill" il piã¹ adatto à "Playbill" ma anche i tipi: "Stencil" "Britannic Bold" funzionano. T = Len(StrBin) For Z = 1 To T    Bc = Bc & " " Next Z Application.ScreenUpdating = False With Rng   Â.Value = Bc    in word sostituire.value = Bc con:
  Â.Text = Bc   Â.Font.Name = FontBC   Â.Font.Size = 10   Â.Font.ColorIndex = 1    in word sostituire.font.colorindex = 1 con:   Â.Font.Color = wdcolorautomatic          For Z = 1 To T      If Mid(StrBin, Z, 1) = "0" Then _     Â.Characters(Z, 1).Font.ColorIndex = 2      in word sostituire con:     Â.Characters(ArrColor(Z)).Font.Color = _      wdcolorwhite    Next Z End With Application.ScreenUpdating = True End Sub Sub CreaImmagineCodEAN(ByRef StrBin As String, _  ByVal NumeroEAN As Long, _  ByVal Testo As String, _  Optional ByRef Wb As Excel.Workbook) Restituisce una immagine del codice a barre Dim NewRng As Excel.Range Dim B As Long Dim Z As Long Dim T As Long Dim V As Variant Dim sh As Excel.Worksheet Const TotR13 As Long = 113 Const TotR8 As Long = 81
If Wb Is Nothing Then _    Wb = ActiveWorkbook B = Len(StrBin) Application.ScreenUpdating = False Application.DisplayAlerts = False Set NewRng = _    Wb.Worksheets.Add.Cells(1, 1) Set sh = NewRng.Parent With sh   Â.Cells.ColumnWidth = 0.08   Â.Cells.NumberFormat = "@"    With.Rows.Item(1).RowHeight = 1.5.Item(2).RowHeight = 40.Item("3:4").RowHeight = 4.5    End With End With Select Case NumeroEAN    Case 13 Set NewRng = _ NewRng.Resize(4, TotR13) T = TotR13 + 11 For Z = 1 To B     If Mid(StrBin, Z, 1) = "1" Then _     NewRng.Item(T + Z).Interior.ColorIndex = 1 Next Z T = T + TotR13
V = Array(1, 3, 47, 49, 93, 95) For Z = 0 To UBound(V)     With NewRng.Item(T + V(Z)) Â.Interior.ColorIndex = 1     End With Next Set NewRng = sh.cells(3, 1) NewRng.Resize(2, 11).Merge With NewRng    Â.HorizontalAlignment = xlright    Â.Value = Left(Testo, 1) End With Set NewRng = sh.cells(3, 15) NewRng.Resize(2, 43).Merge With NewRng    Â.HorizontalAlignment = xlcenter    Â.Value = Left(Right(Testo, 12), 6) End With Set NewRng = sh.cells(3, 61) NewRng.Resize(2, 43).Merge With NewRng    Â.HorizontalAlignment = xlcenter    Â.Value = Right(Testo, 6) End With
Set NewRng = sh.cells(1, 1) With NewRng.Resize(4, TotR13)    Â.VerticalAlignment = xlcenter    Â.Font.Size = 8    Â.CopyPicture _  Appearance:=xlPrinter, _  Format:=xlPicture End With     Case 8 Set NewRng = _ NewRng.Resize(4, TotR8)  T = TotR8 + 7 For Z = 1 To B     If Mid(StrBin, Z, 1) = "1" Then _     NewRng.Item(T + Z).Interior.ColorIndex = 1 Next Z T = T + TotR8 V = Array(1, 3, 33, 35, 65, 67) For Z = 0 To UBound(V)     With NewRng.Item(T + V(Z)) Â.Interior.ColorIndex = 1     End With Next Set NewRng = sh.cells(3, 11) NewRng.Resize(2, 29).Merge With NewRng
   Â.HorizontalAlignment = xlcenter    Â.Value = Left(Testo, 4) End With Set NewRng = sh.cells(3, 43) NewRng.Resize(2, 29).Merge With NewRng    Â.HorizontalAlignment = xlcenter    Â.Value = Right(Testo, 4) End With Set NewRng = sh.cells(1, 1) With NewRng.Resize(4, TotR8)    Â.VerticalAlignment = xlcenter    Â.Font.Size = 8    Â.CopyPicture _  Appearance:=xlPrinter, _  Format:=xlPicture End With End Select sh.delete Application.ScreenUpdating = True Application.DisplayAlerts = True End Sub Function CheckDigitEan_8_13(ByVal Testo As String, _ Optional ByVal Verifica As Boolean) As Variant Se il parametro opzionale à omesso o ha valore False la funzione restituisce il check digit(per codice EAN 8
o EAN 13) ovvero restituisce un carattere (string) che deve essere accodato a Testo. La funzione puã² viceversa essere utilizzata per il controllo del check digit (ultima cifra), in questo caso il parametro Verifica deve avere valore True e Testo deve essere comprensivo di carattere di controllo. La funzione una volta eseguita la verificaâ restituirã True se il check digit à corretto oppure False se à errato (come tipi boolean), False verrã restituito anche nel caso la lunghezza di testo non corrisponde a 8 o a 13 caratteri. La funzione à quindi utilizzabile sia in fase di lettura del codice a barre (Verifica = True) sia in scrittura (Verifica = False e conseguente restituzione del solo carattere di controllo) Dim arrb() As Byte Dim L As Long Dim TempL As Long Dim P As Long Dim D As Long Dim S As Long Dim temp As Variant Dim StrTemp As String Dim Pd As Boolean    If Verifica Then If Len(Testo) = 8 Or Len(Testo) = 13 Then
StrTemp = Right(Testo, 1) Testo = Left(Testo, Len(Testo) - 1) Else CheckDigitEan_8_13 = False Exit Function End If    Else If Len(Testo) = 7 Or Len(Testo) = 12 Then Else Err.Raise 1001,, _ "Il testo che hai usato ha " & _ Len(Testo) & _ " caratteri!" & _ Chr(13) & _ "Il testo assente di codice " & _ "di controllo deve essere di 7 " & _ " o 12 caratteri!" End If    End If    Testo = StrReverse(Testo)       arrb = Testo    S = LenB("A")     For L = 0 To UBound(arrB) Step S temp = arrb(l) Select Case temp Case 45 To 57 Case Else
    Err.Raise 1001,, Chr(temp) & _     " à un carattere non valido!" & _     Chr(13) & _     "Caratteri ammessi: " & _     Chr(13) & _     "0 1 2 3 4 5 6 7 8 9" End Select TempL = TempL + 1 Select Case TempL Mod 2 Case 0     D = D + CInt(Chr(temp)) Case Else     P = P + CInt(Chr(temp)) End Select    Next L       D = (P * 3) + D       For P = 0 To 9 If (D + P) Mod 10 = 0 Then Exit For    Next P       If Verifica Then If CStr(P) = StrTemp Then CheckDigitEan_8_13 = True Exit Function Else CheckDigitEan_8_13 = False Exit Function
End If    Else CheckDigitEan_8_13 = CStr(P)    End If    End Function Function EANCodifica(ByVal Testo As String, _  ByVal NumeroEAN As Long) As String Codifica in stringa binaria Dim arrean(9, 2) As String Dim arrc(9) As String Dim S As String Dim L As Long Dim StrTemp As String Const Clat As String = "101" Const Ccent As String = "01010" If NumeroEAN = 8 Then ElseIf NumeroEAN = 13 Then Else    Err.Raise 1001,, _    "Numero erato di caratetri!" End If arrean(0, 0) = "0001101" arrean(1, 0) = "0011001" arrean(2, 0) = "0010011" arrean(3, 0) = "0111101" arrean(4, 0) = "0100011" arrean(5, 0) = "0110001"
arrean(6, 0) = "0101111" arrean(7, 0) = "0111011" arrean(8, 0) = "0110111" arrean(9, 0) = "0001011" arrean(0, 1) = "0100111" arrean(1, 1) = "0110011" arrean(2, 1) = "0011011" arrean(3, 1) = "0100001" arrean(4, 1) = "0011101" arrean(5, 1) = "0111001" arrean(6, 1) = "0000101" arrean(7, 1) = "0010001" arrean(8, 1) = "0001001" arrean(9, 1) = "0010111" arrean(0, 2) = "1110010" arrean(1, 2) = "1100110" arrean(2, 2) = "1101100" arrean(3, 2) = "1000010" arrean(4, 2) = "1011100" arrean(5, 2) = "1001110" arrean(6, 2) = "1010000" arrean(7, 2) = "1000100" arrean(8, 2) = "1001000" arrean(9, 2) = "1110100" arrc(0) = "00000" 0 AAAAAACCCCCC arrc(1) = "01011" 1 AABABBCCCCCC arrc(2) = "01101" 2 AABBABCCCCCC arrc(3) = "01110" 3 AABBBACCCCCC arrc(4) = "10011" 4 ABAABBCCCCCC arrc(5) = "11001" 5 ABBAABCCCCCC arrc(6) = "11100" 6 ABBBAACCCCCC arrc(7) = "10101" 7 ABABABCCCCCC
arrc(8) = "10110" 8 ABABBACCCCCC arrc(9) = "11010" 9 ABBABACCCCCC Select Case NumeroEAN Â Â Â Case 8 For L = 1 To 4 StrTemp = StrTemp & _ arrean(cint(mid(testo, L, 1)), 0) Next L StrTemp = StrTemp & Ccent For L = 5 To 8 StrTemp = StrTemp & _ arrean(cint(mid(testo, L, 1)), 2) Next L Â Â Â Case 13 S = arrc(cint(left(testo, 1))) StrTemp = StrTemp & _ arrean(cint(mid(testo, 2, 1)), 0) For L = 3 To 7 StrTemp = StrTemp & _ arrean(cint(mid(testo, L, 1)), _ Â CInt(Mid(S, L - 2, 1))) Next L StrTemp = StrTemp & Ccent For L = 8 To 13
StrTemp = StrTemp & _ arrean(cint(mid(testo, L, 1)), 2) Next L End Select StrTemp = Clat & StrTemp & Clat EANCodifica = StrTemp Debug.Print Len(StrTemp) End Function Function VerificaTestoCodEan(ByVal Testo As String _    ) As Boolean Nel caso un carattere NON sia valido la funzione restituisce VERO Dim arrb() As Byte Dim L As Long If Len(Testo) = 0 Then    VerificaTestoCodEan = True    Exit Function End If arrb = Testo Dim temp As Byte For L = 0 To UBound(arrB) _     Step LenB("a")        temp = arrb(l)       Select Case temp
Case 45 To 57 Case Else VerificaTestoCodEan = True Exit Function    End Select    Next L End Function Sub EsempioTest() Dim ArrTesto As Variant Dim Testo As Variant Dim L As Long Dim i As Long ArrTesto = Array("40235479", "4023547", _ "123456789012", "2412345678901") For Each Testo In ArrTesto    i = i + 1    Select Case Len(Testo) Case 7 Call StampaCodEan(CStr(Testo), 8, Cells(i, 1)) Call StampaCodEan(CStr(Testo), 8) Case 8 Call StampaCodEan(CStr(Testo), 8, Cells(i, 1)) Call StampaCodEan(CStr(Testo), 8) Case 12 Call StampaCodEan(CStr(Testo), 13, Cells(i, 1)) Call StampaCodEan(CStr(Testo), 13) Case 13 Call StampaCodEan(CStr(Testo), 13, Cells(i, 1)) Call StampaCodEan(CStr(Testo), 13)    End Select
Next End Sub    Â