Italian Convertire ean 128 in una mappa [Risolto] Grazie sirjo66

sirjo66

Well-Known Member
Licensed User
Longtime User
B4X:
Sub Globals
    Dim decoders As Map
    Dim FNC1 As String = Chr(29) ' se vuoi puoi cambiare Chr(29) con "-"
End Sub

Sub Activity_Create(FirstTime As Boolean) 'ignore
    
    ' creo mappa dei decoders
    decoders.Initialize
    ' Lnn = fixed length, nn digits
    ' Fnn = float, nn digit
    ' Vnn = variable, nn max length
    ' D6 = date
    ' https://it.wikipedia.org/wiki/GS1-128
    decoders.Put("00","L18")
    decoders.Put("01", "L14")
    decoders.Put("02", "L14")
    decoders.Put("10", "V20")
    decoders.Put("11", "D6")
    decoders.Put("12", "D6")
    decoders.Put("13", "D6")
    decoders.Put("15", "D6")
    decoders.Put("17", "D6")
    decoders.Put("20", "L2")
    decoders.Put("21", "V20")
    decoders.Put("22", "V29")
    ' ....... qui lascio a te aggiungere tutti gli altri che ti servono
    decoders.Put("30", "V8")
    ' da 310 a 369 sono tutti Float, non serve definirli
    ' da 390 a 394 sono tutti Float variabili, non serve definirli

    '....
    '....
    
    decoders.Put("415", "L13")
    decoders.Put("416", "L13")
    
    decoders.Put("422", "V3") 'Paese di Origine nato
    decoders.Put("423", "V15") 'Paese di sezionato
    decoders.Put("424", "V3") 'Paese di Allevato
    decoders.Put("425", "V15") 'Paese di Macellato
    decoders.Put("426", "V3") ' Paese da capire meglio
    decoders.Put("427", "V3") ' Paese da capire meglio
    
    decoders.Put("8020", "V25")
    
    ' eccetera eccetera, devi aggiungere tutti quelli che ti servono

    ' --------------------------------------------------------------------
        
    ' test di decodifica
    
    Dim mappa As Map = Decodifica("422380423380" & FNC1 & "424380425380")
    Log(mappa)

'    Dim mappa As Map = Decodifica("010123456789012810123456789" & FNC1 & "21987654321")
'    Log(mappa)
'    Dim mappa As Map = Decodifica("01980081105541283103009140172309201002743989")
'    Log(mappa)
'    Dim mappa As Map = Decodifica("41580320890098748020123456789123456789392205799")
'    Log(mappa)
'    Dim mappa As Map = Decodifica("01080320890000173103002584392200646")
'    Log(mappa)
'    Dim mappa As Map = Decodifica("01080320890000173103002584392200646" & FNC1 & "393200314")
'    Log(mappa)

    ExitApplication
    
End Sub

Sub Decodifica(codice As String) As Map
    
    ' F = fix
    ' D = decimal
    ' V = variable
    ' D = date
    
    Dim mappa As Map
    mappa.Initialize
    
    Do While codice <> ""
        
        If codice.StartsWith(FNC1) Then
            codice = codice.SubString(1)
            If codice = "" Then Exit
        End If
        
        ' ----------------------------------------------------------------------------------------
        ' per primo cerco i codici a due cifre
        Dim cod As String = codice.SubString2(0, 2)

        Dim decoder As String = decoders.Get(cod)
        If decoder = "null" Then
            cod = codice.SubString2(0, 3) ' ora cerco quelli a 3 cifre
            
            decoder = decoders.Get(cod)
            
            If decoder = "null" Then
                Dim codInt As Int = cod
                If codInt >= 310 And codInt <= 369 Then ' prima di tutto controllo che non siano i valore Float
                    decoder = "F6"
                End If
                
                If codInt >= 390 And codInt <= 394 Then ' controllo che non sia un Float Variabile
                    decoder = "F0" ' float a lunghezza variabile
                End If

                If decoder = "null" Then
                    ' provo con quelli a 4 cifre
                    cod = codice.SubString2(0, 4)
                    decoder = decoders.Get(cod)
                    If decoder = "null" Then
                        Msgbox("Codice AI " & cod & " non riconosciuto", "ERRORE") 'ignore
                        Return Null
                    End If
                End If
            End If
        End If
        
        Dim len As Int = decoder.SubString(1)
        Select decoder.SubString2(0, 1) ' estraggo il tipo (L, F, D, V)
            Case "L" ' lunghezza fissa
                mappa.Put(cod, codice.SubString2(cod.Length, cod.Length + len))
                codice = codice.SubString(cod.Length + len)
                Continue
                
            Case "F" ' float
                Dim decimali As Int = codice.SubString2(cod.Length, cod.Length + 1)
                Dim valore As String
                If len = 0 Then ' lunghezza variabile
                    Dim vn As String = codice.SubString(cod.Length + 1).IndexOf(FNC1)
                    If vn = -1 Then
                        valore = codice.SubString(cod.Length + 1)
                        len = valore.Length
                    Else
                        valore = codice.SubString2(cod.Length + 1, cod.Length + 1 + vn)
                        len = codice.SubString2(cod.Length, cod.Length + vn).Length + 1
                    End If
                Else
                    ' lunghezza fissa
                    valore = codice.SubString2(cod.Length + 1, cod.Length + 1 + len)
                End If
                Dim intero As String = valore.SubString2(0, valore.Length - decimali)
                Dim frazione As String = valore.SubString(intero.Length)
                
                Dim valoreFloat As Float = intero & "." & frazione
                mappa.Put(cod, valoreFloat)

                codice = codice.SubString(cod.Length + 1 + len)
                Continue
                    
            Case "D" ' data ddMMyy
                DateTime.DateFormat = "yyMMdd"
                Dim data As String = codice.SubString2(cod.Length, cod.Length + len)
                Dim dataLong As Long = DateTime.DateParse(data)
                mappa.Put(cod, dataLong)
                codice = codice.SubString(cod.Length + len)
                Continue
                
            Case "V" ' variabile
                Dim vn As String = codice.SubString(cod.Length).IndexOf(FNC1)
                If vn = -1 Then
                    Dim valore As String = codice.SubString(cod.Length)
                    If valore.Length > len Then 
                        valore = valore.SubString2(0, len)
                    End If
                    mappa.Put(cod, valore)
                    codice = codice.SubString(cod.Length + valore.Length)
                Else
                    If vn > len Then vn = len
                    mappa.Put(cod, codice.SubString2(cod.Length, cod.Length + vn))
                    codice = codice.SubString(cod.Length + vn)
                End If
                Continue

        End Select
            
    Loop
    
    Return mappa
    
End Sub
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Sto leggendo questi codici:
11150613422380423380424380425380 HumanCode: (11)150613(422)380(423)380(424)380(425)380
(MyMap) {11=1371254400000, 422=380423380424380425380}



70061506147030380999x7031380999x humancode: (7006)150614(7030)380999x(7031)380999x
(MyMap) {7006=1402790400000, 7030=380999x7031380999x}
provali con il nuovo codice che ti ho appena inviato
quando mi dai un codice da provare devi assolutamente dirmi dove c'è il FNC1
 

Xfood

Expert
Licensed User
non va con questi codici
70061506147030380999x7031380999x humancode: (7006)150614(7030)380999x(7031)380999x
(MyMap) {7006=1434240000000, 7030=380999x7031380999x}



11150613422380423380424380425380 humancode: (11)150613(422)380(423)380(424)380(425)380
(MyMap) {11=1434153600000, 422=380, 423=380424380425380}
 

sirjo66

Well-Known Member
Licensed User
Longtime User
.... devi dirmi dove ci sono i codici FNC1

il codice AI 7006 non lo trovo
 

Xfood

Expert
Licensed User
non ci sono codici FNC1, non so come mai, e' un'etichetta fornitore
7006 data concelamento prodotto

i codici completi dovrebbero essere questi
00 * N18,csum,key dlpkey # SSCC
01 * N14,csum,key ex=02,255,37 dlpkey=22,10,21|235 # GTIN
02 * N14,csum,key req=37 # CONTENT
10 X..20 req=01,02,8006,8026 # BATCH/LOT
11 * N6,yymmd0 req=01,02,8006,8026 # PROD DATE
12 * N6,yymmd0 req=8020 # DUE DATE
13 * N6,yymmd0 req=01,02,8006,8026 # PACK DATE
15 * N6,yymmd0 req=01,02,8006,8026 # BEST BEFORE or BEST BY
16 * N6,yymmd0 req=01,02,8006,8026 # SELL BY
17 * N6,yymmd0 req=01,02,255,8006,8026 # USE BY or EXPIRY
20 * N2 req=01,02,8006,8026 # VARIANT
21 X..20 req=01,8006 ex=235 # SERIAL
22 X..20 req=01 # CPV
235 X..28 req=01 # TPX
240 X..30 req=01,02,8006,8026 # ADDITIONAL ID
241 X..30 req=01,02,8006,8026 # CUST. PART No.
242 N..6 req=01,02,8006,8026 # MTO VARIANT
243 X..20 req=01 # PCN
250 X..30 req=01,8006 req=21 # SECONDARY SERIAL
251 X..30 req=01,8006 # REF. TO SOURCE
253 N13,csum,key [X..17] dlpkey # GDTI
254 X..20 req=414 # GLN EXTENSION COMPONENT
255 N13,csum,key [N..12] dlpkey ex=01,02,415,8006,8020,8026 # GCN
30 N..8 req=01,02 # VAR. COUNT
3100-3105 * N6 req=01,02 ex=310n # NET WEIGHT (kg)
3110-3115 * N6 req=01,02 ex=311n # LENGTH (m)
3120-3125 * N6 req=01,02 ex=312n # WIDTH (m)
3130-3135 * N6 req=01,02 ex=313n # HEIGHT (m)
3140-3145 * N6 req=01,02 ex=314n # AREA (m²)
3150-3155 * N6 req=01,02 ex=315n # NET VOLUME (l)
3160-3165 * N6 req=01,02 ex=316n # NET VOLUME (m³)
3200-3205 * N6 req=01,02 ex=320n # NET WEIGHT (lb)
3210-3215 * N6 req=01,02 ex=321n # LENGTH (in)
3220-3225 * N6 req=01,02 ex=322n # LENGTH (ft)
3230-3235 * N6 req=01,02 ex=323n # LENGTH (yd)
3240-3245 * N6 req=01,02 ex=324n # WIDTH (in)
3250-3255 * N6 req=01,02 ex=325n # WIDTH (ft)
3260-3265 * N6 req=01,02 ex=326n # WIDTH (yd)
3270-3275 * N6 req=01,02 ex=327n # HEIGHT (in)
3280-3285 * N6 req=01,02 ex=328n # HEIGHT (ft)
3290-3295 * N6 req=01,02 ex=329n # HEIGHT (yd)
3300-3305 * N6 req=00,01 ex=330n # GROSS WEIGHT (kg)
3310-3315 * N6 req=00,01 ex=331n # LENGTH (m), log
3320-3325 * N6 req=00,01 ex=332n # WIDTH (m), log
3330-3335 * N6 req=00,01 ex=333n # HEIGHT (m), log
3340-3345 * N6 req=00,01 ex=334n # AREA (m²), log
3350-3355 * N6 req=00,01 ex=335n # VOLUME (l), log
3360-3365 * N6 req=00,01 ex=336n # VOLUME (m³), log
3370-3375 * N6 req=01 ex=337n # KG PER m²
3400-3405 * N6 req=00,01 ex=340n # GROSS WEIGHT (lb)
3410-3415 * N6 req=00,01 ex=341n # LENGTH (in), log
3420-3425 * N6 req=00,01 ex=342n # LENGTH (ft), log
3430-3435 * N6 req=00,01 ex=343n # LENGTH (yd), log
3440-3445 * N6 req=00,01 ex=344n # WIDTH (in), log
3450-3455 * N6 req=00,01 ex=345n # WIDTH (ft), log
3460-3465 * N6 req=00,01 ex=346n # WIDTH (yd), log
3470-3475 * N6 req=00,01 ex=347n # HEIGHT (in), log
3480-3485 * N6 req=00,01 ex=348n # HEIGHT (ft), log
3490-3495 * N6 req=00,01 ex=349n # HEIGHT (yd), log
3500-3505 * N6 req=01,02 ex=350n # AREA (in²)
3510-3515 * N6 req=01,02 ex=351n # AREA (ft²)
3520-3525 * N6 req=01,02 ex=352n # AREA (yd²)
3530-3535 * N6 req=00,01 ex=353n # AREA (in²), log
3540-3545 * N6 req=00,01 ex=354n # AREA (ft²), log
3550-3555 * N6 req=00,01 ex=355n # AREA (yd²), log
3560-3565 * N6 req=01,02 ex=356n # NET WEIGHT (t oz)
3570-3575 * N6 req=01,02 ex=357n # NET VOLUME (oz)
3600-3605 * N6 req=01,02 ex=360n # NET VOLUME (qt)
3610-3615 * N6 req=01,02 ex=361n # NET VOLUME (gal.)
3620-3625 * N6 req=00,01 ex=362n # VOLUME (qt), log
3630-3635 * N6 req=00,01 ex=363n # VOLUME (gal.), log
3640-3645 * N6 req=01,02 ex=364n # VOLUME (in³)
3650-3655 * N6 req=01,02 ex=365n # VOLUME (ft³)
3660-3665 * N6 req=01,02 ex=366n # VOLUME (yd³)
3670-3675 * N6 req=00,01 ex=367n # VOLUME (in³), log
3680-3685 * N6 req=00,01 ex=368n # VOLUME (ft³), log
3690-3695 * N6 req=00,01 ex=369n # VOLUME (yd³), log
37 N..8 req=00 req=02,8026 # COUNT
3900-3909 N..15 req=255,8020 ex=390n,391n,394n,8111 # AMOUNT
3910-3919 N3,iso4217 N..15 req=8020 ex=391n # AMOUNT
3920-3929 N..15 req=01 req=30,31nn,32nn,35nn,36nn ex=392n,393n # PRICE
3930-3939 N3,iso4217 N..15 req=30,31nn,32nn,35nn,36nn ex=393n # PRICE
3940-3943 N4 req=255 ex=394n,8111 # PRCNT OFF
3950-3955 N6 req=30,31nn,32nn,35nn,36nn ex=392n,393n,395n,8005 # PRICE/UoM
400 X..30 # ORDER NUMBER
401 X..30,key dlpkey # GINC
402 N17,csum,key dlpkey # GSIN
403 X..30 req=00 # ROUTE
410 * N13,csum,key # SHIP TO LOC
411 * N13,csum,key # BILL TO
412 * N13,csum,key # PURCHASE FROM
413 * N13,csum,key # SHIP FOR LOC
414 * N13,csum,key dlpkey=254|7040 # LOC No.
415 * N13,csum,key req=8020 dlpkey=8020 # PAY TO
416 * N13,csum,key # PROD/SERV LOC
417 * N13,csum,key dlpkey=7040 # PARTY
420 X..20 ex=421 # SHIP TO POST
421 N3,iso3166 X..9 ex=4307 # SHIP TO POST
422 N3,iso3166 req=01,02,8006,8026 ex=426 # ORIGIN
423 N..15,iso3166list req=01,02 ex=426 # COUNTRY - INITIAL PROCESS
424 N3,iso3166 req=01,02 ex=426 # COUNTRY - PROCESS
425 N..15,iso3166list req=01,02 ex=426 # COUNTRY - DISASSEMBLY
426 N3,iso3166 req=01,02 # COUNTRY - FULL PROCESS
427 X..3 req=01,02 req=422 # ORIGIN SUBDIVISION
4300 X..35,pcenc req=00 # SHIP TO COMP
4301 X..35,pcenc req=00 # SHIP TO NAME
4302 X..70,pcenc req=00 # SHIP TO ADD1
4303 X..70,pcenc req=4302 # SHIP TO ADD2
4304 X..70,pcenc req=00 # SHIP TO SUB
4305 X..70,pcenc req=00 # SHIP TO LOC
4306 X..70,pcenc req=00 # SHIP TO REG
4307 X2,iso3166alpha2 req=00 # SHIP TO COUNTRY
4308 X..30 req=00 # SHIP TO PHONE
4309 N10,latitude N10,longitude req=00 # SHIP TO GEO
4310 X..35,pcenc req=00 # RTN TO COMP
4311 X..35,pcenc req=00 # RTN TO NAME
4312 X..70,pcenc req=00 # RTN TO ADD1
4313 X..70,pcenc req=4312 # RTN TO ADD2
4314 X..70,pcenc req=00 # RTN TO SUB
4315 X..70,pcenc req=00 # RTN TO LOC
4316 X..70,pcenc req=00 # RTN TO REG
4317 X2,iso3166alpha2 req=00 # RTN TO COUNTRY
4318 X..20 req=00 # RTN TO POST
4319 X..30 req=00 # RTN TO PHONE
4320 X..35,pcenc req=00 # SRV DESCRIPTION
4321 N1,yesno req=00 # DANGEROUS GOODS
4322 N1,yesno req=00 # AUTH TO LEAVE
4323 N1,yesno req=00 # SIG REQUIRED
4324 N6,yymmd0 N4,hhmm req=00 # NOT BEF DEL DT
4325 N6,yymmd0 N4,hhmm req=00 # NOT AFT DEL DT
4326 N6,yymmdd req=00 # REL DATE
7001 N13 req=01,02,8006,8026 # NSN
7002 X..30 req=01,02 # MEAT CUT
7003 N6,yymmdd N4,hhmm req=01,02 # EXPIRY TIME
7004 N..4 req=01 req=10 # ACTIVE POTENCY
7005 X..12 req=01,02 # CATCH AREA
7006 N6,yymmdd req=01,02 # FIRST FREEZE DATE
7007 N6,yymmdd [N6],yymmdd req=01,02 # HARVEST DATE
7008 X..3 req=01,02 # AQUATIC SPECIES
7009 X..10 req=01,02 # FISHING GEAR TYPE
7010 X..2 req=01,02 # PROD METHOD
7011 N6,yymmdd [N4],hhmm req=01,02 # TEST BY DATE
7020 X..20 req=01,8006 req=416 # REFURB LOT
7021 X..20 req=01,8006 # FUNC STAT
7022 X..20 req=7021 # REV STAT
7023 X..30,key # GIAI - ASSEMBLY
7030 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 0
7031 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 1
7032 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 2
7033 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 3
7034 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 4
7035 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 5
7036 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 6
7037 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 7
7038 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 8
7039 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 9
7040 N1 X1 X1 X1,importeridx # UIC+EXT
710 X..20 req=01 # NHRN PZN
711 X..20 req=01 # NHRN CIP
712 X..20 req=01 # NHRN CN
713 X..20 req=01 # NHRN DRN
714 X..20 req=01 # NHRN AIM
715 X..20 req=01 # NHRN NDC
7230 X2 X..28 req=01,8004 # CERT # 1
7231 X2 X..28 req=01,8004 # CERT # 2
7232 X2 X..28 req=01,8004 # CERT # 3
7233 X2 X..28 req=01,8004 # CERT # 4
7234 X2 X..28 req=01,8004 # CERT # 5
7235 X2 X..28 req=01,8004 # CERT # 6
7236 X2 X..28 req=01,8004 # CERT # 7
7237 X2 X..28 req=01,8004 # CERT # 8
7238 X2 X..28 req=01,8004 # CERT # 9
7239 X2 X..28 req=01,8004 # CERT # 10
7240 X..20 req=01,8006 # PROTOCOL
7241 N2,mediatype req=8017,8018 # AIDC MEDIA TYPE
7242 X..25 req=8017,8018 # VCN
8001 N4,nonzero N5,nonzero N3,nonzero N1,winding N1 req=01 # DIMENSIONS
8002 X..20 # CMT No.
8003 N1,zero N13,csum,key [X..16] dlpkey # GRAI
8004 X..30,key dlpkey=7040 # GIAI
8005 N6 req=01,02 # PRICE PER UNIT
8006 N14,csum N4,pieceoftotal ex=01,37 dlpkey=22,10,21 # ITIP
8007 X..34,iban req=415 # IBAN
8008 N8,yymmddhh [N..4],mmoptss req=01,02 # PROD TIME
8009 X..50 req=00,01 # OPTSEN
8010 Y..30,key dlpkey=8011 # CPID
8011 N..12,nozeroprefix req=8010 # CPID SERIAL
8012 X..20 req=01,8006 # VERSION
8013 X..25,csumalpha,key dlpkey # GMN
8017 N18,csum,key ex=8018 dlpkey=8019 # GSRN - PROVIDER
8018 N18,csum,key ex=8017 dlpkey=8019 # GSRN - RECIPIENT
8019 N..10 req=8017,8018 # SRIN
8020 X..25 req=415 # REF No.
8026 N14,csum N4,pieceoftotal req=37 ex=02,8006 # ITIP CONTENT
8030 Z..90 req=00,01,253,255,8003,8004,8006,8010,8017,8018 # DIGSIG
8110 X..70,couponcode
8111 N4 req=255 # POINTS
8112 X..70,couponposoffer
8200 X..70 req=01 # PRODUCT URL
90 X..30 # INTERNAL
91-99 X..90 # INTERNAL
 

sirjo66

Well-Known Member
Licensed User
Longtime User
cosa vorrebbe dire 7030 N3,iso3166999 X..27 req=01,02 # PROCESSOR # 0 ??
 

Xfood

Expert
Licensed User
il 7030 identifica il paese di macellazione come codice iso 3 caratteri , Italia=380 , piu omologa macellazione
Processor #0 non so cosa vuol dire
quindi il nostro (7030)380999x = Paese di macellazione=380(Italia) omologa macello 999x
(7031)380999x = Paese di Sezionamento=380(Italia) omologa sezionamento 999x
 

sirjo66

Well-Known Member
Licensed User
Longtime User
ok, ma dalla documentazione sembra che il campo è variabile fino al massimo a 27 caratteri.
Come faccio a capire dove termina il campo ???
Che sia quella "x" ??
 

Xfood

Expert
Licensed User
quindi errore del fornitore, ci vuole il carattere FNC1 per forza su alcuni campi per determinare la fine?
 

Xfood

Expert
Licensed User
devo recuperare una 10 di etichette diverse e fare le prove ma ormai posso recuperare le etichette non prima di lunedi
 

sirjo66

Well-Known Member
Licensed User
Longtime User
quindi errore del fornitore, ci vuole il carattere FNC1 per forza su alcuni campi per determinare la fine?
Si.
Praticamente, per i campi a lunghezza variabile, se il campo è più corto della lunghezza massima definita, ci vuole il campo FNC1 per segnalare il "fine campo"

ho aggiunto un
B4X:
decoders.Put("7006", "D6") ' Data congelamento prodotto

Ora mi sembra che il problema sia solo il 7030
 

Xfood

Expert
Licensed User
vado a dormire, grazie per il tuo grande aiuto, credo che ci siamo,
dovrebbe funzionare se l'etichetta e' stata composta secondo le regole corrette gs1
la tua funzione sembra andare bene.
Grazie mille, ti aggiorno appena ho un po di etichette di fornitori diversi da provare.
Buona notte
 

sirjo66

Well-Known Member
Licensed User
Longtime User
per quel che riguarda il 7030 c'è scritto che deve rispettare iso3166999, il quale dice:

The iso3166999 linter ensures that the data represents an ISO 3166 "num-3" country code, or the value "999"

Tradotto:
Il linter iso3166999 garantisce che i dati rappresentino un codice paese ISO 3166 "num-3" o il valore "999"

Dice "o" il valore 999, non "e" il valore 999, per cui secondo me è sbagliato il codice fornito dal produttore, anche perchè quella "x" finale secondo me non c'entra nulla.
Chiedi spiegazioni al produttore, se ti dice che quella "x" serve come fine campo posso modificare il source code
 
Last edited:

William Lancee

Well-Known Member
Licensed User
Longtime User
I ate a wonderful starter of Asparagus Arancini and Risoto Seafood as a second at La Casetta, a local restaurant a 3 minute walk from where I live.
And yes, it's Toronto in Canada.

When I got home I was inspired to watch the Italian Forum and I found a puzzle. I love puzzles.

Barcode scanners should report application ID codes separately from the data. But in this case they do not.
Is it possible to analyze numbers and retrieve sections? Yes, with some clauses.

The 128 barcode structure has some redundancies.

Your dataset (the parser only sees code):
'Code: 41580320890098748020123456789123456789392205799
'Parser: 415 8032089009874 8020 123456789123456789392205799
'Human: (415)8032089009874(8020)123456789123456789392205799
'
'Code: 01080320890000173103002584392200646
'Parser: 01 08032089000017 3103 002584
'Human: (01)08032089000017(3103)002584(3922)00646
'
SKU: 010803208900001731330012841515082010lot123
'Parser: 01 08032089000017 3133 001284 15 150820 10 lot123
'Human: (01)08032089000017(3133)001284(15)150820(10)lot123
'
'Code: 301921123456789012
'Parser: 30 19 21 123456789012
'Human: (30)19(21)123456789012
'
'Code: 4218402050
'Parser: 421 8402050
'Human: (421)84020500 Actual bar code is: [Start C] [FNC1] 42 18 40 20 50 [Code A] 16 [Check symbol 92] [Stop]

The scheme is that there is an Application Identifier (AI) followed by a fixed number (mostly but not always) of digits.

https://www.databar-barcode.info/application-identifiers/

The attached project uses this to analyze the numerical content.

So the condition: when AI has a variable number of digits, you have to make a guess.
In the published examples, Code: 301921123456789012
AI=30 can have a variable number of digits. If I do 2 works in the example, but probably not in general.

I hope, however, that this will help to find a solution.
 

Attachments

  • code128.zip
    11.9 KB · Views: 149

William Lancee

Well-Known Member
Licensed User
Longtime User
Ho pubblicato la mia versione italiana sopra, ma è stata automaticamente tradotta in inglese.
Il file zip è al numero 96

Ho mangiato un meraviglioso antipasto di Arancini di Asparagi e Risoto Frutti di Mare come secondo a La Casetta, un ristorante locale a 3 minuti a piedi da dove vivo.
E sì, è Toronto in Canada.

Quando sono tornato a casa ho avuto l'ispirazione di guardare il Forum italiano e ho trovato un puzzle. Adoro i puzzle.

Gli scanner di codici a barre dovrebbero riportare i codici ID dell'applicazione separatamente dai dati. Ma in questo caso non lo fanno.
È possibile analizzare i numeri e recuperare le sezioni? Sì, con alcune clausole.

La struttura del codice a barre 128 presenta alcune ridondanze.

Il tuo set di dati (il parser vede solo il codice):
'Code: 41580320890098748020123456789123456789392205799
'Parser: 415 8032089009874 8020 123456789123456789392205799
'Human: (415)8032089009874(8020)123456789123456789392205799
'
'Code: 01080320890000173103002584392200646
'Parser: 01 08032089000017 3103 002584
'Human: (01)08032089000017(3103)002584(3922)00646
'
'Code: 010803208900001731330012841515082010lot123
'Parser: 01 08032089000017 3133 001284 15 150820 10 lot123
'Human: (01)08032089000017(3133)001284(15)150820(10)lot123
'
'Code: 301921123456789012
'Parser: 30 19 21 123456789012
'Human: (30)19(21)123456789012
'
'Code: 4218402050
'Parser: 421 8402050
'Human: (421)84020500 Actual bar code is: [Start C] [FNC1] 42 18 40 20 50 [Code A] 16 [Check symbol 92] [Stop]

Lo schema è che esiste un Identificatore dell'Applicazione (AI) seguito da un numero fisso (per lo più ma non sempre) di cifre.


Il progetto allegato sfrutta questo per analizzare il contenuto numerico.

Quindi la condizione: quando l'IA ha un numero variabile di cifre, devi fare un'ipotesi.
Negli esempi pubblicati, Codice: 301921123456789012
L'AI=30 può avere un numero variabile di cifre. Se lo faccio 2 funziona nell'esempio, ma probabilmente non in generale.

Spero comunque che questo possa aiutare a trovare una soluzione.
 

Xfood

Expert
Licensed User
Ho pubblicato la mia versione italiana sopra, ma è stata automaticamente tradotta in inglese.
Il file zip è al numero 96

Ho mangiato un meraviglioso antipasto di Arancini di Asparagi e Risoto Frutti di Mare come secondo a La Casetta, un ristorante locale a 3 minuti a piedi da dove vivo.
E sì, è Toronto in Canada.

Quando sono tornato a casa ho avuto l'ispirazione di guardare il Forum italiano e ho trovato un puzzle. Adoro i puzzle.

Gli scanner di codici a barre dovrebbero riportare i codici ID dell'applicazione separatamente dai dati. Ma in questo caso non lo fanno.
È possibile analizzare i numeri e recuperare le sezioni? Sì, con alcune clausole.

La struttura del codice a barre 128 presenta alcune ridondanze.

Il tuo set di dati (il parser vede solo il codice):
'Code: 41580320890098748020123456789123456789392205799
'Parser: 415 8032089009874 8020 123456789123456789392205799
'Human: (415)8032089009874(8020)123456789123456789392205799
'
'Code: 01080320890000173103002584392200646
'Parser: 01 08032089000017 3103 002584
'Human: (01)08032089000017(3103)002584(3922)00646
'
'Code: 010803208900001731330012841515082010lot123
'Parser: 01 08032089000017 3133 001284 15 150820 10 lot123
'Human: (01)08032089000017(3133)001284(15)150820(10)lot123
'
'Code: 301921123456789012
'Parser: 30 19 21 123456789012
'Human: (30)19(21)123456789012
'
'Code: 4218402050
'Parser: 421 8402050
'Human: (421)84020500 Actual bar code is: [Start C] [FNC1] 42 18 40 20 50 [Code A] 16 [Check symbol 92] [Stop]

Lo schema è che esiste un Identificatore dell'Applicazione (AI) seguito da un numero fisso (per lo più ma non sempre) di cifre.


Il progetto allegato sfrutta questo per analizzare il contenuto numerico.

Quindi la condizione: quando l'IA ha un numero variabile di cifre, devi fare un'ipotesi.
Negli esempi pubblicati, Codice: 301921123456789012
L'AI=30 può avere un numero variabile di cifre. Se lo faccio 2 funziona nell'esempio, ma probabilmente non in generale.

Spero comunque che questo possa aiutare a trovare una soluzione.
Grazie mille per il tuo interesse faro delle prove, ma se in generale esiste una regola, faro,' in modo che il fornitore la rispetti, cosi che posso usare il metodo di @sirjo66, che mi sembra ottimo.
Grazie a tutti per aver contribuito alla soluzione di questo quesito, vi aggiorno a Breve del risultato ottenuto
 

Xfood

Expert
Licensed User
ho fatto delle prove con vari certificati, e sembra funzionare bene,
ma avvolte capita che nell'etichetta c'e' un codice che non ha le caratteristiche gs1 per la tracciabilita', e se letto erroneamente va in errore ed esce dalla procedura.

per caso @sirjo66 riusciresti a sistemarlo.....
per esempio questo codice
121152200354333110010024326701 key value
non ha nessuna caratteristiche, mi dovrebbe ritornare una mappa con codice 99999,"errore lettura"

grazie mille

log
B4X:
121152200354333110010024326701
b4xmainpage_decodifica (java line: 365)
java.text.ParseException: Unparseable date: "115220"
    at java.text.DateFormat.parse(DateFormat.java:362)
    at anywheresoftware.b4a.keywords.DateTime.DateParse(DateTime.java:148)
    at b4a.ean128.b4xmainpage._decodifica(b4xmainpage.java:365)
    at b4a.ean128.b4xmainpage._button1_click(b4xmainpage.java:124)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:6603)
    at android.view.View.performClickInternal(View.java:6576)
    at android.view.View.access$3100(View.java:780)
    at android.view.View$PerformClick.run(View.java:26090)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6702)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)
*** Service (starter) Create ***
** Service (starter) Start **
 

sirjo66

Well-Known Member
Licensed User
Longtime User
B4X:
Sub Decodifica(codice As String) As Map
    
    ' F = fix
    ' D = decimal
    ' V = variable
    ' D = date
    
    Dim mappa As Map
    mappa.Initialize
    
    Do While codice <> ""
        
        If codice.StartsWith(FNC1) Then
            codice = codice.SubString(1)
            If codice = "" Then Exit
        End If
        
        ' ----------------------------------------------------------------------------------------
        ' per primo cerco i codici a due cifre
        Dim cod As String = codice.SubString2(0, 2)

        Dim decoder As String = decoders.Get(cod)
        If decoder = "null" Then
            cod = codice.SubString2(0, 3) ' ora cerco quelli a 3 cifre
            
            decoder = decoders.Get(cod)
            
            If decoder = "null" Then
                Dim codInt As Int = cod
                If codInt >= 310 And codInt <= 369 Then ' prima di tutto controllo che non siano i valore Float
                    decoder = "F6"
                End If
                
                If codInt >= 390 And codInt <= 394 Then ' controllo che non sia un Float Variabile
                    decoder = "F0" ' float a lunghezza variabile
                End If

                If decoder = "null" Then
                    ' provo con quelli a 4 cifre
                    cod = codice.SubString2(0, 4)
                    decoder = decoders.Get(cod)
                    If decoder = "null" Then
                        Msgbox("Codice AI " & cod & " non riconosciuto", "ERRORE") 'ignore
                        Return Null
                    End If
                End If
            End If
        End If
        
        Dim len As Int = decoder.SubString(1)
        Select decoder.SubString2(0, 1) ' estraggo il tipo (L, F, D, V)
            Case "L" ' lunghezza fissa
                mappa.Put(cod, codice.SubString2(cod.Length, cod.Length + len))
                codice = codice.SubString(cod.Length + len)
                Continue
                
            Case "F" ' float
                Dim decimali As Int = codice.SubString2(cod.Length, cod.Length + 1)
                Dim valore As String
                If len = 0 Then ' lunghezza variabile
                    Dim vn As String = codice.SubString(cod.Length + 1).IndexOf(FNC1)
                    If vn = -1 Then
                        valore = codice.SubString(cod.Length + 1)
                        len = valore.Length
                    Else
                        valore = codice.SubString2(cod.Length + 1, cod.Length + 1 + vn)
                        len = codice.SubString2(cod.Length, cod.Length + vn).Length + 1
                    End If
                Else
                    ' lunghezza fissa
                    valore = codice.SubString2(cod.Length + 1, cod.Length + 1 + len)
                End If
                Dim intero As String = valore.SubString2(0, valore.Length - decimali)
                Dim frazione As String = valore.SubString(intero.Length)
                
                Dim valoreFloat As Float = intero & "." & frazione
                mappa.Put(cod, valoreFloat)

                codice = codice.SubString(cod.Length + 1 + len)
                Continue
                    
            Case "D" ' data ddMMyy
                DateTime.DateFormat = "yyMMdd"
                Dim data As String = codice.SubString2(cod.Length, cod.Length + len)
                Dim dataLong As Long
                Try
                    dataLong = DateTime.DateParse(data)
                Catch
                    mappa.Put("99999", "errore lettura")
                    codice = ""
                    Continue
                End Try
                mappa.Put(cod, dataLong)
                codice = codice.SubString(cod.Length + len)
                Continue
                
            Case "V" ' variabile
                Dim vn As String = codice.SubString(cod.Length).IndexOf(FNC1)
                If vn = -1 Then
                    Dim valore As String = codice.SubString(cod.Length)
                    If valore.Length > len Then 
                        valore = valore.SubString2(0, len)
                    End If
                    mappa.Put(cod, valore)
                    codice = codice.SubString(cod.Length + valore.Length)
                Else
                    If vn > len Then vn = len
                    mappa.Put(cod, codice.SubString2(cod.Length, cod.Length + vn))
                    codice = codice.SubString(cod.Length + vn)
                End If
                Continue

        End Select
            
    Loop
    
    Return mappa
    
End Sub
 
Top