Ir al contenido principal

función code128 en Transact-SQL

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.

barcode128

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

Comentarios

  1. Te Amooo loco!!! No sabes lo que busqué esta solución, Genioooo!!!

    ResponderEliminar
  2. Hola Carlos,

    Me alegro de haberte ayudado.

    Atentamente,
    Josep

    ResponderEliminar
  3. Gracias por compartir el código, estaba justo por hacer lo mismo.

    ResponderEliminar
  4. Hola, tendras también para interleaved 2 of 5, gracias.

    ResponderEliminar
    Respuestas
    1. Hola Charles,

      Pues no, no tengo desarrollado para interleaved 2 of 5.

      Un saludo,

      Eliminar
  5. Estimado Pep, a mi no me funciona, no se si sea la fuente que descargué o el generador pero no me lee los codigos

    ResponderEliminar
  6. Hola 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

Publicar un comentario

Entradas populares de este blog

Comparte en WhatsApp - Botón personalizado

Aquí tenéis una manera sencilla de adaptar el botón para compartir mediante WhatsApp, utilizando un icono personalizado para integrarlo con vuestra hoja de estilos. Pasos a seguir: Seguir la instalación tal y como se recomienda en la página   WhatsApp Sharing Button Generator .   Conseguir un icono para utilizar de botón hacia WhatsApp del mismo estilo que el resto de botones de nuestra web (En mi caso utilicé los botones de compartir en redes sociales de   Simple Sharing Buttons Generator   y el botón de WhatsApp lo creé con Photoshop ). Modificar la línea de código del botón para sobrescribir los estilos por defecto :  A la etiqueta   class  sólo dejar "wa_btn". A la etiqueta   style  añadir "border:none;background-color: transparent;background-image: none;". Entre la apertura y el cierre del enlace incluir nuestro icono . Es decir, justo antes de </a> añadir  <img src="ruta hacia vuestro icono" alt="Whatsapp"> E n

Receta de masa para pizza sin cereales (sin gluten) y baja en hidratos

No utilizaremos cereales de ningún tipo, así que no tiene gluten y es baja en hidratos de carbono. Con esta receta mes salen 2 bases, así una me la como "fresca" y la otra la meto en el congelador para tenerla a punto para otro día. Además es muy fácil! Ingredientes: - 6 claras de huevo o 2 huevos enteros - 125 gramos de almendra molida - 150 gramos de queso Emmental rallado - 320 gramos de coliflor - sal al gusto Limpiamos la coliflor y la cocemos un poco. Yo la pongo unos 4 minutos en el microondas. También se podría hervir unos minutos, pero hay que asegurarse de escurrirla muy bien antes de mezclarla con los otros ingredientes. Con un tenedor la chafamos hasta dejarla como una masa homogénea y nos deshacemos del agua sobrante si la hubiera. Añadimos el queso rallado, la almendra molida. Lo mezclamos todo bien y luego añadimos las claras de huevo y la sal, y también lo mezclaremos con el tenedor hasta que nos quede una masa homogénea. Si queré