Tiempo atrás tuve que imprimir un código de barras en formato 128 en unos informes de Crystal Reports ejecutados desde una aplicación web .NET.
Para ello utilicé la fuente code128.ttf. A esta fuente hay que enviarle codificada la cadena de texto que queremos imprimir como código de barras 128.
Buscando por Internet encontré la web grandzebu code128 con la función que permite hacer esta codificación en diferentes lenguajes de programación. Pero, por temas de rendimiento necesitaba recibir todos los datos directamente desde nuestro servidor de base de datos SQL Server 2008 R2, y en este lenguaje no encontré la función. Así que hice la traducción en Transact-SQL. Quería compartirla con el autor, pero no he conseguido ponerme en contacto con él y, por esta razón, la publico en este blog.
Podéis descargar el código aquí: code128.sql
A continuación podéis ver el código:
/****** Object: UserDefinedFunction [dbo].[Code128] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Code128] (@stringToEncode VARCHAR(255))
returns VARCHAR(255)
AS
BEGIN
DECLARE @I AS INT
DECLARE @CHECKSUM AS INT
DECLARE @MINI AS INT
DECLARE @DUMMY AS INT;
DECLARE @TABLEB AS BIT;
DECLARE @CODE128 AS NVARCHAR(4000);
DECLARE @LONG AS INT;
DECLARE @LONG_CODE128 AS INT;
SET @CHECKSUM = 0;
SET @CODE128 = '';
SET @LONG = Len(@stringToEncode);
--Verificamos la cadena de entrada
IF ( @LONG = 0 )
BEGIN
RETURN '' --'Cadena de código de barras vacía';
END;
SET @I = 1;
WHILE @I <= @LONG
BEGIN
IF ( ( Ascii(Substring(@stringToEncode, @I, 1)) < 32 )
OR ( Ascii(Substring(@stringToEncode, @I, 1)) > 126 ) )
BEGIN
RETURN '' -- 'Cadena de código de barras no válida';
END;
SET @I = @I + 1;
END;
--cálculo de la cadena resultante con optimización de uso de las tablas B y C
SET @TABLEB = 1;
SET @I = 1;
WHILE @I <= @LONG
BEGIN
IF ( @TABLEB = 1 )
--Miramos si interesa pasar a la tabla C.
--Afirmativo para 4 dígitos al inicio o al final, o sino para 6 dígitos
BEGIN
IF ( @I = 1
OR @I + 3 = @LONG )
BEGIN
SET @MINI = 4;
END
ELSE
BEGIN
SET @MINI = 6;
END
--Si los caracteres de @MINI son números luego @MINI=0
SET @MINI = @MINI - 1;
IF ( ( @I + @MINI ) <= @LONG )
BEGIN
WHILE ( @MINI >= 0 )
BEGIN
IF ( ( Ascii(Substring(@stringToEncode, @I + @MINI
,
1))
<
48 )
OR ( Ascii(Substring(@stringToEncode, @I +
@MINI,
1)
) >
57
) )
BEGIN
BREAK;
END
SET @MINI = @MINI - 1;
END
END
--si @MINI<0 pasamos a la tabla C
IF ( @MINI < 0 )
BEGIN
IF ( @I = 1 )
BEGIN
--Inicio tabla C
SET @CODE128 = Char(210)
END
ELSE
BEGIN
--Continuamos sobre la tabla C
SET @CODE128 = @CODE128 + Char(204)
END
SET @TABLEB = 0;
END
ELSE
BEGIN
IF ( @I = 1 )
BEGIN
--Inicio tabla C
SET @CODE128 = Char(209)
END
END
END
IF ( @TABLEB = 0 )
--Estamos en la tabla C, intentaremos tratar los dos dígitos
BEGIN
SET @MINI = 2
SET @MINI = @MINI - 1;
IF ( @I + @MINI <= @LONG )
BEGIN
WHILE ( @MINI >= 0 )
BEGIN
IF ( ( Ascii(Substring(@stringToEncode, @I + @MINI
,
1))
<
48 )
OR ( Ascii(Substring(@stringToEncode, @I +
@MINI,
1)
) >
57
) )
BEGIN
BREAK;
END
SET @MINI = @MINI - 1;
END
END
IF ( @MINI < 0 )
BEGIN
--OK para dos dígitos
SET @DUMMY = CONVERT(INT, Substring(@stringToEncode, @I,
2
));
IF ( @DUMMY < 95 )
BEGIN
SET @DUMMY = @DUMMY + 32;
END
ELSE
BEGIN
SET @DUMMY = @DUMMY + 105;
END
SET @CODE128 = @CODE128 + Char(@DUMMY);
SET @I = @I + 2;
END
ELSE
BEGIN
--No tenemos dos dígitos y volvemos a la tabla B
SET @CODE128 = @CODE128 + Char(205);
SET @TABLEB = 1;
END
END
IF ( @TABLEB = 1 )
BEGIN
SET @CODE128 = @CODE128 + Substring(@stringToEncode, @I, 1);
SET @I= @I + 1;
END
END;
--Cálculo del control
SET @I = 1;
SET @LONG_CODE128 = LEN(@CODE128)
WHILE @I <= @LONG_CODE128
BEGIN
SET @DUMMY = Ascii(Substring(@CODE128, @I, 1));
IF ( @DUMMY < 127 )
BEGIN
SET @DUMMY = @DUMMY - 32;
END
ELSE
BEGIN
SET @DUMMY = @DUMMY - 105;
END
IF ( @I = 1 )
BEGIN
SET @CHECKSUM = @DUMMY;
END
SET @CHECKSUM = ( @CHECKSUM + (@I-1) * @DUMMY ) % 103;
SET @I = @I+1;
END
--Cálculo del código ASCII de control
IF ( @CHECKSUM < 95 )
BEGIN
SET @CHECKSUM = @CHECKSUM + 32;
END
ELSE
BEGIN
SET @CHECKSUM = @CHECKSUM + 105;
END
--Añadimos el control al stop
SET @CODE128 = @CODE128 + Char(@CHECKSUM) + Char(211);
RETURN @CODE128
END
Para ello utilicé la fuente code128.ttf. A esta fuente hay que enviarle codificada la cadena de texto que queremos imprimir como código de barras 128.
Buscando por Internet encontré la web grandzebu code128 con la función que permite hacer esta codificación en diferentes lenguajes de programación. Pero, por temas de rendimiento necesitaba recibir todos los datos directamente desde nuestro servidor de base de datos SQL Server 2008 R2, y en este lenguaje no encontré la función. Así que hice la traducción en Transact-SQL. Quería compartirla con el autor, pero no he conseguido ponerme en contacto con él y, por esta razón, la publico en este blog.
Podéis descargar el código aquí: code128.sql
A continuación podéis ver el código:
/****** Object: UserDefinedFunction [dbo].[Code128] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Code128] (@stringToEncode VARCHAR(255))
returns VARCHAR(255)
AS
BEGIN
DECLARE @I AS INT
DECLARE @CHECKSUM AS INT
DECLARE @MINI AS INT
DECLARE @DUMMY AS INT;
DECLARE @TABLEB AS BIT;
DECLARE @CODE128 AS NVARCHAR(4000);
DECLARE @LONG AS INT;
DECLARE @LONG_CODE128 AS INT;
SET @CHECKSUM = 0;
SET @CODE128 = '';
SET @LONG = Len(@stringToEncode);
--Verificamos la cadena de entrada
IF ( @LONG = 0 )
BEGIN
RETURN '' --'Cadena de código de barras vacía';
END;
SET @I = 1;
WHILE @I <= @LONG
BEGIN
IF ( ( Ascii(Substring(@stringToEncode, @I, 1)) < 32 )
OR ( Ascii(Substring(@stringToEncode, @I, 1)) > 126 ) )
BEGIN
RETURN '' -- 'Cadena de código de barras no válida';
END;
SET @I = @I + 1;
END;
--cálculo de la cadena resultante con optimización de uso de las tablas B y C
SET @TABLEB = 1;
SET @I = 1;
WHILE @I <= @LONG
BEGIN
IF ( @TABLEB = 1 )
--Miramos si interesa pasar a la tabla C.
--Afirmativo para 4 dígitos al inicio o al final, o sino para 6 dígitos
BEGIN
IF ( @I = 1
OR @I + 3 = @LONG )
BEGIN
SET @MINI = 4;
END
ELSE
BEGIN
SET @MINI = 6;
END
--Si los caracteres de @MINI son números luego @MINI=0
SET @MINI = @MINI - 1;
IF ( ( @I + @MINI ) <= @LONG )
BEGIN
WHILE ( @MINI >= 0 )
BEGIN
IF ( ( Ascii(Substring(@stringToEncode, @I + @MINI
,
1))
<
48 )
OR ( Ascii(Substring(@stringToEncode, @I +
@MINI,
1)
) >
57
) )
BEGIN
BREAK;
END
SET @MINI = @MINI - 1;
END
END
--si @MINI<0 pasamos a la tabla C
IF ( @MINI < 0 )
BEGIN
IF ( @I = 1 )
BEGIN
--Inicio tabla C
SET @CODE128 = Char(210)
END
ELSE
BEGIN
--Continuamos sobre la tabla C
SET @CODE128 = @CODE128 + Char(204)
END
SET @TABLEB = 0;
END
ELSE
BEGIN
IF ( @I = 1 )
BEGIN
--Inicio tabla C
SET @CODE128 = Char(209)
END
END
END
IF ( @TABLEB = 0 )
--Estamos en la tabla C, intentaremos tratar los dos dígitos
BEGIN
SET @MINI = 2
SET @MINI = @MINI - 1;
IF ( @I + @MINI <= @LONG )
BEGIN
WHILE ( @MINI >= 0 )
BEGIN
IF ( ( Ascii(Substring(@stringToEncode, @I + @MINI
,
1))
<
48 )
OR ( Ascii(Substring(@stringToEncode, @I +
@MINI,
1)
) >
57
) )
BEGIN
BREAK;
END
SET @MINI = @MINI - 1;
END
END
IF ( @MINI < 0 )
BEGIN
--OK para dos dígitos
SET @DUMMY = CONVERT(INT, Substring(@stringToEncode, @I,
2
));
IF ( @DUMMY < 95 )
BEGIN
SET @DUMMY = @DUMMY + 32;
END
ELSE
BEGIN
SET @DUMMY = @DUMMY + 105;
END
SET @CODE128 = @CODE128 + Char(@DUMMY);
SET @I = @I + 2;
END
ELSE
BEGIN
--No tenemos dos dígitos y volvemos a la tabla B
SET @CODE128 = @CODE128 + Char(205);
SET @TABLEB = 1;
END
END
IF ( @TABLEB = 1 )
BEGIN
SET @CODE128 = @CODE128 + Substring(@stringToEncode, @I, 1);
SET @I= @I + 1;
END
END;
--Cálculo del control
SET @I = 1;
SET @LONG_CODE128 = LEN(@CODE128)
WHILE @I <= @LONG_CODE128
BEGIN
SET @DUMMY = Ascii(Substring(@CODE128, @I, 1));
IF ( @DUMMY < 127 )
BEGIN
SET @DUMMY = @DUMMY - 32;
END
ELSE
BEGIN
SET @DUMMY = @DUMMY - 105;
END
IF ( @I = 1 )
BEGIN
SET @CHECKSUM = @DUMMY;
END
SET @CHECKSUM = ( @CHECKSUM + (@I-1) * @DUMMY ) % 103;
SET @I = @I+1;
END
--Cálculo del código ASCII de control
IF ( @CHECKSUM < 95 )
BEGIN
SET @CHECKSUM = @CHECKSUM + 32;
END
ELSE
BEGIN
SET @CHECKSUM = @CHECKSUM + 105;
END
--Añadimos el control al stop
SET @CODE128 = @CODE128 + Char(@CHECKSUM) + Char(211);
RETURN @CODE128
END
Te Amooo loco!!! No sabes lo que busqué esta solución, Genioooo!!!
ResponderEliminarHola Carlos,
ResponderEliminarMe alegro de haberte ayudado.
Atentamente,
Josep
Mil gracias, te felicito!
ResponderEliminarGracias a ti por el comentario
EliminarGracias por compartir el código, estaba justo por hacer lo mismo.
ResponderEliminarHola, tendras también para interleaved 2 of 5, gracias.
ResponderEliminarHola Charles,
EliminarPues no, no tengo desarrollado para interleaved 2 of 5.
Un saludo,
Estimado Pep, a mi no me funciona, no se si sea la fuente que descargué o el generador pero no me lee los codigos
ResponderEliminarHola amigo, lo ejecuto y me genera el código pero con dos cuadros uno al principio y otro al final del código y no se deja leer
ResponderEliminar