problema con códigos de barras

06/06/2007 - 18:03 por Mario Esquivel Bado | Informe spam
Hola grupo

Tengo el siguiente problema: el dígito verificador que se calcula con la
función que se encuentra en http://www.portalfox.com/article.php?sid4 es
diferente al del producto.

¿Será que el código en el producto está mal? Se trata de un producto
argentino (Chicles beldent) con código 77900166.

El dígito verificador que se calcula con la función de portalfox es el 4,
sin embargo, en el producto es el 6 (el último dígito de 77900166)

¿Estoy haciendo mal algo? reitero que utilizo exactamente la función enviada
por Luis Maria, en PortalFox.

Lo llamativo es que, si cambio una parte del código de la siguiente forma,
el dígito verificador calculado coincide con el del producto:

código original:
IF MOD(lnI,2) = 0
lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 3
ELSE
lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 1
ENDIF

código cambiado:
IF MOD(lnI,2) = 0
lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 1 && 1 en vez de 3
ELSE
lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 3 && 3 en vez de 1
ENDIF

Por favor, ayúdenme a resolver este dilema! ¿Acaso hay un error en la
función? y si es así, ¿se aplicaría lo mismo para códigos EAN12?

Mario Esquivel Bado
Sistemas Epsilon
Desarrollo de Sistemas de Gestión Administrativa Financiera y Contable

Preguntas similare

Leer las respuestas

#6 Hector Quiñones
13/06/2007 - 11:15 | Informe spam
Luis María, estuve siguiendo este hilo y como quedartia cuando se quiera
imprimir dígito y caracteres.

"Luis María Guayán" escribió en el mensaje
news:
Gracias por la observación, ya he corregido las funciones de PortalFox
quedando como la siguiente para EAN 8 y 13

FUNCTION CheckDigitEan(tcCodigo)
LOCAL lnSuma, lnI, lnPos
STORE 0 TO lnSuma, lnPos
FOR lnI = LEN(tcCodigo) TO 1 STEP -1
lnPos = lnPos + 1
lnSuma = lnSuma + (VAL(SUBSTR(tcCodigo,lnI,1)) *
IIF(MOD(lnPos,2)=0,1,3))
ENDFOR
RETURN tcCodigo + TRANSFORM(MOD(10-MOD(lnSuma,10),10))
ENDFUNC

Luis María Guayán
Tucumán, Argentina
________________________________
SysOp de www.PortalFox.com
Microsoft Visual FoxPro MVP
________________________________
La palabra imposible solo figura
en el diccionario de los tontos


"Mario Esquivel Bado" escribió en el mensaje
news:
Luis Maria

Disculpame que insista. Creo que continúa estando mal la función. El caso
es que el STEP -1 no resuelve el caso.

Aquí te reenvio mi análisis para que lo verifiques, por favor:

El documento que utilicé para el análisis es el siguiente:
https://forja.rediris.es/docman/vie...1sica.pdf.

1. Según este documento el "valor corrector" debe calcularse así:
"Numerando el código de Derecha a Izquierda, se multiplican por 1 los
dígitos que ocupan posición par, y por 3 los dígitos que ocupan posición
impar".

2. La "funcióm mas simple" que mensionas no resuelve el caso para un
EAN13. Esto es debido a que la regla para determinar el "valor corrector"
establece que los dígitos deben ser numerados "de derecha a izquierda"
!!!!!. Entonces, siendo 12 los
dígitos en juego en un código EAN13, el primer dígito ocupa una posición
PAR (12) según esta regla y, atención con esto, la posición del mismo
dígito es IMPAR (1) si se enumera de izquierda a derecha. Sin embargo, y
esto es importante de notar, para los códigos EAN8 los dígitos
considerados son 7 y no importa numerarlos de derecha a izquierda o
izquierda a derecha por que, cada dígito ocupará siempre la misma
posición par o impar.

3. Propuesta: en vista de lo expuesto, someto a tu consideración el
siguiente cambio a tu función que SI puede servir tanto para EAN8 como
para EAN13:


-
FUNCTION CheckDigitEan(tcString)

LOCAL lcRet, lnI, lnCheckSum, lnAux, lnPos

lcRet = ALLTRIM(tcString)
IF !inlist(LEN(lcRet),7,12)
MESSAGEBOX("La longitud de la cadena"+CHR(13)+;
"debe ser 7 o 12 caracteres.",16,"Error")
RETURN ""
ENDIF

lnCheckSum = 0
For lnI = 1 To Len(lcRet)
lnPos = Len(lcRet)-lnI+1 && determina la posición !!!!!
If Mod(lnPos,2) = 0
lnCheckSum = lnCheckSum + Val(Subs(lcRet,lnI,1)) * 1 && posición PAR
Else
lnCheckSum = lnCheckSum + Val(Subs(lcRet,lnI,1)) * 3 && posición
IMPAR
Endif
Endfor

lnAux = MOD(lnCheckSum,10)
lcRet = lcRet + ALLTRIM(STR(IIF(lnAux = 0, 0, 10-lnAux)))
RETURN lcRet
ENDFUNC
-

En esta propuesta, el cambio importante es el cálculo que resulta de
"lnPos
= Len(lcRet)-lnI+1". Así, en un código EAN13 resulta:

lnI = 1 > lnPos = 12 > PAR: valor corrector = 1
lnI = 2 > lnPos = 11 > IMPAR: valor corrector = 3
lnI = 3 > lnPos = 10 > PAR: valor corrector = 1
...
...
lnI = 12 > lnPos = 1 > IMPAR: valor corrector = 3

Como puedes ver, no es lo mismo hacer simplemente "For lnI = Len(lcRet)
To 1 Step -1": El último dígito ocuparía siempre la posición 12 que es
PAR y sin embargo, el último dígito debe ocupar la posición 1 (uno!!) que
es IMPAR!!!!.

Espero sus comentario.

Mario Esquivel Bado






Respuesta Responder a este mensaje
#7 Luis María Guayán
14/06/2007 - 03:53 | Informe spam
Los códigos de barras EAN8 y EAN13 son solo para numeros. Si necesitas numeros y
caracteres deberias utilizar Codigo 128 A ó B; ó Codigo 39


Luis María Guayán
Tucumán, Argentina
________________________________
SysOp de www.PortalFox.com
Microsoft Visual FoxPro MVP
________________________________
La palabra imposible solo figura
en el diccionario de los tontos

"Hector Quiñones" escribió en el mensaje
news:
Luis María, estuve siguiendo este hilo y como quedartia cuando se quiera
imprimir dígito y caracteres.

"Luis María Guayán" escribió en el mensaje
news:
Gracias por la observación, ya he corregido las funciones de PortalFox
quedando como la siguiente para EAN 8 y 13

FUNCTION CheckDigitEan(tcCodigo)
LOCAL lnSuma, lnI, lnPos
STORE 0 TO lnSuma, lnPos
FOR lnI = LEN(tcCodigo) TO 1 STEP -1
lnPos = lnPos + 1
lnSuma = lnSuma + (VAL(SUBSTR(tcCodigo,lnI,1)) * IIF(MOD(lnPos,2)=0,1,3))
ENDFOR
RETURN tcCodigo + TRANSFORM(MOD(10-MOD(lnSuma,10),10))
ENDFUNC

Luis María Guayán
Tucumán, Argentina
________________________________
SysOp de www.PortalFox.com
Microsoft Visual FoxPro MVP
________________________________
La palabra imposible solo figura
en el diccionario de los tontos


"Mario Esquivel Bado" escribió en el mensaje
news:
Luis Maria

Disculpame que insista. Creo que continúa estando mal la función. El caso es
que el STEP -1 no resuelve el caso.

Aquí te reenvio mi análisis para que lo verifiques, por favor:

El documento que utilicé para el análisis es el siguiente:
https://forja.rediris.es/docman/vie...1sica.pdf.

1. Según este documento el "valor corrector" debe calcularse así: "Numerando
el código de Derecha a Izquierda, se multiplican por 1 los dígitos que
ocupan posición par, y por 3 los dígitos que ocupan posición impar".

2. La "funcióm mas simple" que mensionas no resuelve el caso para un EAN13.
Esto es debido a que la regla para determinar el "valor corrector" establece
que los dígitos deben ser numerados "de derecha a izquierda" !!!!!.
Entonces, siendo 12 los
dígitos en juego en un código EAN13, el primer dígito ocupa una posición PAR
(12) según esta regla y, atención con esto, la posición del mismo dígito es
IMPAR (1) si se enumera de izquierda a derecha. Sin embargo, y esto es
importante de notar, para los códigos EAN8 los dígitos considerados son 7 y
no importa numerarlos de derecha a izquierda o izquierda a derecha por que,
cada dígito ocupará siempre la misma posición par o impar.

3. Propuesta: en vista de lo expuesto, someto a tu consideración el
siguiente cambio a tu función que SI puede servir tanto para EAN8 como para
EAN13:


-
FUNCTION CheckDigitEan(tcString)

LOCAL lcRet, lnI, lnCheckSum, lnAux, lnPos

lcRet = ALLTRIM(tcString)
IF !inlist(LEN(lcRet),7,12)
MESSAGEBOX("La longitud de la cadena"+CHR(13)+;
"debe ser 7 o 12 caracteres.",16,"Error")
RETURN ""
ENDIF

lnCheckSum = 0
For lnI = 1 To Len(lcRet)
lnPos = Len(lcRet)-lnI+1 && determina la posición !!!!!
If Mod(lnPos,2) = 0
lnCheckSum = lnCheckSum + Val(Subs(lcRet,lnI,1)) * 1 && posición PAR
Else
lnCheckSum = lnCheckSum + Val(Subs(lcRet,lnI,1)) * 3 && posición IMPAR
Endif
Endfor

lnAux = MOD(lnCheckSum,10)
lcRet = lcRet + ALLTRIM(STR(IIF(lnAux = 0, 0, 10-lnAux)))
RETURN lcRet
ENDFUNC
-

En esta propuesta, el cambio importante es el cálculo que resulta de "lnPos
= Len(lcRet)-lnI+1". Así, en un código EAN13 resulta:

lnI = 1 > lnPos = 12 > PAR: valor corrector = 1
lnI = 2 > lnPos = 11 > IMPAR: valor corrector = 3
lnI = 3 > lnPos = 10 > PAR: valor corrector = 1
...
...
lnI = 12 > lnPos = 1 > IMPAR: valor corrector = 3

Como puedes ver, no es lo mismo hacer simplemente "For lnI = Len(lcRet) To 1
Step -1": El último dígito ocuparía siempre la posición 12 que es PAR y sin
embargo, el último dígito debe ocupar la posición 1 (uno!!) que es
IMPAR!!!!.

Espero sus comentario.

Mario Esquivel Bado










email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida