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

#1 Mario Esquivel Bado
07/06/2007 - 00:26 | Informe spam
Me respondo a mi mismo, no por que se acabaron mis dudas, sino por que estoy
analizando mejor el asunto del dígito verificador y mis conclusiones las
quiero homologar con el grupo. En mi investigación encontré el siguiente
documento en el que me baso para el estudio:
https://forja.rediris.es/docman/vie...1sica.pdf.

1. Aparentemente el código en artículo de Luis María Guayan está incorrecto
según el documento mencionado arriba donde establece la regla para el "valor
corrector" 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". Entonces, la porción de la función en
http://www.portalfox.com/article.php?sid4 debe ser (para un código
EAN8!):

FOR lnI = 1 TO 7
IF MOD(lnI,2) = 0
lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 1 && PAR=1 en
vez de 3
ELSE
lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 3 && IMPAR=3 en
vez de 1
ENDIF
ENDFOR

2. Además, el mismo código NO se puede aplicar a 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 la consideración del grupo
(para que lo analicen por favor) el siguiente método que SI puede servir
tanto para EAN8 como para EAN13:

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

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

Atención: no es lo mismo hacer simplemente "For lnI = Len(lcRet) To 1
Step -1". Ya vi esta solución pero es cometer el mismo error "desde la
puerta de atrás en vez de la de adelante".

Espero sus comentario.

Mario Esquivel Bado


"Mario Esquivel Bado" escribió en el mensaje
news:%

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


Respuesta Responder a este mensaje
#2 Germán GIraldo
07/06/2007 - 01:06 | Informe spam
La función de Luis María corregida
FUNCTION CheckDigitEan(tcCodigo)
LOCAL lnSuma, lnI, lnPos
lnSuma = 0 lnPos = LEN(tcCodigo) + 1
FOR lnI = LEN(tcCodigo) TO 1 STEP -1
lnSuma = lnSuma + (VAL(SUBSTR(tcCodigo,lnI,1)) * IIF(MOD(lnPos -
lnI,2)=0,1,3))
ENDFOR
RETURN tcCodigo + TRANSFORM(MOD(10-MOD(lnSuma,10),10))
ENDFUNCEsta función te debe funcionar para todos los códigos EAN

Saludos

Germán Giraldo


"Mario Esquivel Bado" escribió en el mensaje
news:%
Me respondo a mi mismo, no por que se acabaron mis dudas, sino por que
estoy analizando mejor el asunto del dígito verificador y mis conclusiones
las quiero homologar con el grupo. En mi investigación encontré el
siguiente documento en el que me baso para el estudio:
https://forja.rediris.es/docman/vie...1sica.pdf.

1. Aparentemente el código en artículo de Luis María Guayan está
incorrecto según el documento mencionado arriba donde establece la regla
para el "valor corrector" 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". Entonces, la porción de la
función en http://www.portalfox.com/article.php?sid4 debe ser (para un
código EAN8!):

FOR lnI = 1 TO 7
IF MOD(lnI,2) = 0
lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 1 && PAR=1 en
vez de 3
ELSE
lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 3 && IMPAR=3
en vez de 1
ENDIF
ENDFOR

2. Además, el mismo código NO se puede aplicar a 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 la consideración del grupo
(para que lo analicen por favor) el siguiente método que SI puede servir
tanto para EAN8 como para EAN13:

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

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

Atención: no es lo mismo hacer simplemente "For lnI = Len(lcRet) To 1
Step -1". Ya vi esta solución pero es cometer el mismo error "desde la
puerta de atrás en vez de la de adelante".

Espero sus comentario.

Mario Esquivel Bado


"Mario Esquivel Bado" escribió en el mensaje
news:%

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






Respuesta Responder a este mensaje
#3 Luis María Guayán
10/06/2007 - 16:32 | Informe spam
Gracias por la corrección.

En el mismo artículo hay un comentario de una funcióm mas simple y que
contempla el codigo EAN 13, EAN 8 y UCC 12:

FUNCTION CheckDigitEan(tcCodigo)
LOCAL lnSuma, lnI
lnSuma = 0
FOR lnI = LEN(tcCodigo) TO 1 STEP -1
lnSuma = lnSuma + (VAL(SUBSTR(tcCodigo,lnI,1)) * IIF(MOD(lnI,2)=0,3,1))
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 de
noticias news:%

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


Respuesta Responder a este mensaje
#4 Mario Esquivel Bado
12/06/2007 - 22:28 | Informe spam
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
#5 Luis María Guayán
13/06/2007 - 04:11 | Informe spam
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
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida