A impressão de etiquetas com código de barras é um componente crítico em diversos setores, especialmente na logística e no gerenciamento de estoque. Para desenvolvedores que trabalham com o ERP Protheus, dominar a programação de impressoras térmicas em ADVPL é uma habilidade essencial. Este guia abrangente explorará as nuances da geração e impressão de etiquetas com código de barras usando ADVPL, uma linguagem robusta utilizada no ecossistema Protheus.
Fundamentos da Programação de Impressoras Térmicas em ADVPL
A programação de impressoras térmicas em ADVPL envolve o uso de funções especializadas que permitem a criação de layouts complexos de etiquetas. Estas funções são projetadas para trabalhar com várias linguagens de impressão térmica, incluindo:
- ZPL (Zebra Programming Language)
- EPL (Eltron Programming Language)
- DPL (Datamax Programming Language)
- IPL (Intermec Programming Language)
Uma das principais vantagens do ADVPL neste contexto é a abstração que oferece. Os desenvolvedores não precisam dominar as linguagens específicas de cada fabricante, pois o ADVPL fornece uma interface unificada para diferentes modelos de impressoras.
O que veremos:
Configuração Inicial e Preparação
Antes de mergulhar na programação, é crucial configurar corretamente a impressora. A função MSCBPrinter é fundamental neste processo:
Sintaxe Advpl
//Exemplo de função MSCBPRINTER
MSCBPRINTER(cModelPrt, cPorta, nDensidade, nTamanho, lSrv, nPorta, cServer, cEnv, nMemoria, cFila, lDrvWin, cPathSpool)
Esta função permite especificar:
É importante notar que a configuração correta destes parâmetros é essencial para garantir a qualidade e precisão da impressão.
Parâmetros | Descrição | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
[cModelPrt] | String com o modelo de impressora: | ||||||||||
|
|||||||||||
[cPorta] | String com a porta | ||||||||||
[nDensidade] | Número com a densidade referente a quantidade de pixel por mm. Este parâmetro só deve ser informado quando o parâmetro cModelPrt não for informado, pois cModelPrt o atualizará automaticamente. A utilização deste parâmetro deverá ser usada quando não souber o modelo da impressora, a aplicação entenderá que se trata de uma impressora Zebra. O tamanho da etiqueta será necessário quando a mesma não for contínua. | ||||||||||
[nTamanho] | Tamanho da etiqueta em Milímetros. Lembrando que este tamanho só deve ser passado se a etiqueta for contínua. | ||||||||||
[lSrv] | Se .t. imprime no server, .f. no client. O seu valor padrão é .f. | ||||||||||
[nPorta] | Número da porta de outro server | ||||||||||
[cServer] | Endereço IP de outro server | ||||||||||
[cEnv] | Environment do outro server | ||||||||||
[nMemoria] | Número com bloco de memória da impressora térmica. Caso seja enviada muita informação para a impressora, a fim que esta venha imprimir (sobrecarregando a memória), pode ocorrer perda de dados. Por outro lado, se for informado blocos muito pequenos de memória, implicará na diminuição da performance da impressora. Sendo assim, o programador deverá fazer uma avaliação para ver o que melhor se adequa a sua situação. | ||||||||||
[cFila] | Diretório onde será gravada as filas | ||||||||||
[lDrvWin] | Indica se será utilizado os drivers do Windows para impressão | ||||||||||
[cPathSpool] | Caminho do diretório onde serão geradas as filas de impressão |
Criando Layouts de Etiquetas
O processo de criação de uma etiqueta geralmente segue uma estrutura definida:
- Iniciar a etiqueta com MSCBBegin
- Adicionar elementos como texto, linhas, caixas, código de barras e imagens. Ou até mesmo um bloco com código da linguagem nativa da impressora
- Finalizar a etiqueta com MSCBEnd
Vamos explorar um exemplo mais avançado:
Sintaxe Advpl MSCBBEGIN e MSCBEND
MSCBBEGIN(1, 6) // Inicia a etiqueta
MSCBBOX(02, 01, 76, 34, 1) // Cria uma caixa
MSCBSAY(10, 06, "PRODUTO:", "N", "A", "012,008")
MSCBSAY(10, 12, cDescProd, "N", "A", "012,008")
MSCBSAY(10, 18, "LOTE:", "N", "A", "012,008")
MSCBSAY(10, 24, cLote, "N", "A", "012,008")
MSCBSAYBAR(23, 30, cCodigo, "N", "C", 8.36, .F., .T., .F., , 2, 1) // Imprime o código de barras
MSCBEND() // Finaliza a etiqueta
Este exemplo demonstra como criar uma etiqueta mais complexa, incluindo múltiplos campos de texto e um código de barras.
Trabalhando com Códigos de Barras Avançados
A função MSCBSayBar é o coração da impressão de códigos de barras em ADVPL. Ela suporta uma ampla variedade de simbologias, incluindo:
- Code 128
- EAN-13
- QR Code
- Data Matrix
Aqui está um exemplo avançado usando o GS1-128, um padrão amplamente utilizado na indústria:
Sintaxe Advpl MSCBSAYBAR
aConteudo := {;
{"01", "07893316010411" } ,;// GTIN
{"10", "0000970100" + MSCB128B() + "1" + MSCB128C() } ,;// Lote
{"37", "0004" } ,;// Quantidade
{"21", "000494" } } // Número de Série
MSCBSAYBAR(08, 10, aConteudo, "N", "MB07", 10, .F., .T., .F., "C", 2, 1, .F.)
Este código cria um código de barras GS1-128 que incorpora múltiplas informações em um único código, uma prática comum em logística avançada e rastreamento de produtos.
Otimização para Diferentes Fabricantes de Impressoras
Embora o ADVPL abstraia muitas diferenças entre fabricantes, é crucial entender algumas particularidades:
- Zebra (ZPL): O ponto de origem está no canto superior esquerdo.
- Datamax (DPL): O ponto de origem está no canto inferior esquerdo.
- Intermec (IPL): Similar ao Zebra, mas com algumas diferenças no sistema de coordenadas.
Conhecer essas nuances é fundamental para criar layouts precisos e resolver problemas específicos de cada fabricante.
Melhores Práticas e Otimização de Performance
Embora o ADVPL abstraia muitas diferenças entre fabricantes, é crucial entender algumas particularidades:
Utilização de Variáveis
A função `MSCBVar` permite criar variáveis para elementos que mudam frequentemente, melhorando significativamente a eficiência da impressão.
Gerenciamento de Memória
Use o parâmetro `nMemoria` em `MSCBPrinter` para otimizar o uso de memória da impressora, especialmente importante em ambientes de alto volume, e se drive windows estiver desabilitado (caso contrário será o windows que administrará a memória).
Testes Extensivos
Devido às variações entre modelos de impressoras, é crucial testar seu código em diversas configurações e cenários.
Documentação Detalhada
Mantenha uma documentação clara e abrangente, especialmente ao lidar com layouts complexos de etiquetas ou integrações avançadas.
Conhecer essas nuances é fundamental para criar layouts precisos e resolver problemas específicos de cada fabricante.
Funções ADVPL para Etiquetas Térmicas
Segue abaixo funções ADVPL para etiquetas térmicas:
1. MSCBPrinter (Configuração da Impressora)
Objetivo:
Permite realizar as configurções da impressora, as quais permitirão ao programador determinar as caracteristicas de impressão, definidas pelos parâmetros abaixo.
Sintaxe:
MSCBPRINTER(cModelPrt, cPorta, nDensidade, nTamanho, lSrv, nPorta, cServer, cEnv, nMemoria, cFila, lDrvWin, cPathSpool)
Já vimos anteriormente os detalhes dos parâmetros da função MSCBPrinter, clique aqui para mais detalhes.
MSCBPrinter (Configuração da Impressora)
User Function ConfigImpressora()
Local cModelo := "ZEBRA"
Local cPorta := "LPT1"
Local nDensidade := 203 // DPI
Local nTamanho := 100 // mm
MSCBPRINTER(cModelo, cPorta, nDensidade, nTamanho, .F.)
// Outras configurações...
MSCBCHKSTATUS(.T.) // Ativa verificação de status
Return
2. MSCBClosePrinter (Finaliza a conexão com a impressora)
Objetivo:
Finaliza a conexão com a impressora.
Sintaxe:
MSCBClosePrinter()
Exemplo usando o padrão de programação Zebra (família ZPL):
MSCBClosePrinter (Finaliza a conexão com a impressora)
User Function FinalizaConexao()
Local cPorta := "COM1:9600,N,8,1"
Local nx := 0
MSCBPRINTER("S500-8", cPorta, , 40, .F.)
For nx:=1 to 3
MSCBBEGIN(1, 6)
MSCBSAY(10, 06, "CODIGO", "N", "A", "015,008")
MSCBSAY(33, 09, Strzero(nX, 10), "N", "0", "032,035")
MSCBSAY(05, 17, "IMPRESSORA ZEBRA S500-8", "N", "0", "020,030")
MSCBEND()
Next nx
MSCBCLOSEPRINTER() // Finaliza Conexao
Return
3. MSCBBegin (Início da Etiqueta)
Objetivo:
Inicializa a montagem da imagem para cada etiqueta.
Sintaxe:
MSCBBEGIN(nxQtde,nVeloc,nTamanho,lSalva)
Parâmetros | Descrição |
[nQtde] | Quantidade de cópias |
[nVeloc] | Velocidade (1,2,3,4,5,6) polegadas por segundo |
[nTamanho] | Tamanho da etiqueta em Milímetros. |
[lSalva] | Variável utilizada somente para definição de form´s. O valor default da variável é .f. |
Exemplo:
MSCBBegin (Início da Etiqueta)
User Function IniciaEtiqueta()
Local nCopias := 1
Local nVelocidade := 3 // Velocidade de impressão
MSCBBEGIN(nCopias, nVelocidade)
// Conteúdo da etiqueta será adicionado aqui...
Return
4. MSCBEnd
Objetivo:
Finaliza a montagem da imagem, que foi inicializada por um “MSCBBegin( )”.
Sintaxe:
MSCBEND()
Exemplo:
MSCBEnd (Finalizar Etiqueta)
User Function FinalizaEtiqueta()
MSCBEND()
Return
5. MSCBSay (Imprimir Texto)
Objetivo:
Imprime uma string.
Sintaxe:
MSCBSAY(nXmm, nYmm, cTexto, cRotacao, cFonte, cTam, lReverso, lSerial, cIncr, lZerosL, lNoAlltrim)
Parâmetro | Descrição | ||||||||||
nXmm | Posição X em Milímetros | ||||||||||
nYmm | Posição Y em Milímetros | ||||||||||
cTexto | String a ser impresso ou itens especificando uma variável “@”.(Ex: “@2”).
|
||||||||||
cRotação | String com o tipo de Rotação (N,R,I,B):
|
||||||||||
cFonte | String com os tipos de Fonte:
|
||||||||||
cTam | String com o tamanho da Fonte | ||||||||||
*[lReverso] | Imprime em reverso quando tiver sobre um box preto | ||||||||||
[lSerial] | Serializa o código | ||||||||||
[cIncr] | Incrementa quando for serial positivo ou negativo | ||||||||||
*[lZerosL] | Coloca zeros a esquerda no numero serial | ||||||||||
[lNoAlltrim] | Permite brancos a esquerda e direita |
Exemplo usando o padrão de programação Zebra (família ZPL):
MSCBSay (Imprimir Texto)
User Function ImprimeTexto()
Local cTexto := "Produto: Widget XYZ"
Local nX := 10, nY := 15
Local cRotacao := "N" // Normal
Local cFonte := "A"
Local cTamanho := "020,010"
MSCBSAY(nX, nY, cTexto, cRotacao, cFonte, cTamanho)
Return
6. MSCBSayBar (Imprimir Código de Barras)
Objetivo:
Imprime código de barras.
Sintaxe:
MSCBSAYBAR(nXmm, nYmm, cConteudo, cRotacao, cTypePrt, nAltura, lDigVer, lLinha, lLinBaixo, cSubSetIni, nLargura, nRelacao, lCompacta, lSerial, cIncr, lZerosL)
Parâmetro | Descrição | ||||||||||||||||
nXmm | Posição X em Milímetros | ||||||||||||||||
nYmm | Posição Y em Milímetros | ||||||||||||||||
cConteudo | String a ser impressa especificando uma variável “@” ou array somente quando o parâmetro cTypePrt for igual á MB07.
|
||||||||||||||||
cRotação | String com o tipo de Rotação:
|
||||||||||||||||
cTypePrt | String com o Modelo de Código de Barras:
Obs: Caso o leitor queira utilizar o modelo do padrão de programação da impressora, o mesmo deverá consultar documentação do fabricante.
|
||||||||||||||||
[nAltura] | Altura do código de Barras em Milímetros | ||||||||||||||||
*[ lDigver] | Imprime dígito de verificação | ||||||||||||||||
[lLinha] | Imprime a linha de código | ||||||||||||||||
*[lLinBaixo] | Imprime a linha de código acima das barras | ||||||||||||||||
[cSubSetIni] | Utilizado no code128 | ||||||||||||||||
[nLargura] | Largura da barra mais fina em pontos default 3 | ||||||||||||||||
[nRelacao] | Relação entre as barras finas e grossas em pontos default 2 | ||||||||||||||||
[lCompacta] | Parâmetro fora de uso. | ||||||||||||||||
[lSerial] | Serializa o código | ||||||||||||||||
[cIncr] | Incrementa quando for serial positivo ou negativo | ||||||||||||||||
[lZerosL] | Coloca Zeros a esquerda do conteúdo. Este parâmetro só é valido quando lSerial estiver ativado (.t.). |
Exemplo usando o padrão de programação Zebra (família ZPL):
MSCBSayBar (Imprimir Código de Barras)
User Function ImprimeCodigoBarras()
Local cConteudo := "7891234567890"
Local nX := 20, nY := 30
Local cTipo := "EAN13"
Local nAltura := 15
Local lDigVerif := .T.
Local lLinha := .T.
MSCBSAYBAR(nX, nY, cConteudo, "N", cTipo, nAltura, lDigVerif, lLinha)
Return
7. MSCBBox (Desenhar Caixa)
Objetivo:
Imprime um box.
Sintaxe:
MSCBBOX(nX1mm, nY1mm, nX2mm, nY2mm, nExpessura, cCor)
Parâmetro | Descrição |
nX1mm | Posição X1 em Milímetros |
nY1mm | Posição Y1 em Milímetros |
nX2mm | Posição X2 em Milímetros |
nY2mm | Posição Y2 em Milímetros |
[nEspessura] | Numero com a espessura em pixel |
*[cCor] | String com a Cor Branca ou Preta (“W” ou “B”) |
Exemplo:
MSCBBox (Desenhar Caixa)
User Function DesenhaCaixa()
Local nX1 := 5, nY1 := 5
Local nX2 := 95, nY2 := 45
Local nEspessura := 1
MSCBBOX(nX1, nY1, nX2, nY2, nEspessura)
Return
8. MSCBLineH (Imprime Linha Horizontal)
Objetivo:
Imprime uma linha horizontal.
Sintaxe:
MSCBLineH(nX1mm, nY1mm, nX2mm, nExpessura, cCor)
Parâmetro | Descrição |
nX1mm | Posição X1 em Milímetros |
nY1mm | Posição Y1 em Milímetros |
nX2mm | Posição X2 em Milímetros |
[nEspessura] | Numero com a espessura em pixel |
*[cCor] | String com a Cor Branca ou Preta (“W” ou “B”) |
Exemplo:
MSCBLineH (Imprime Linha Horizontais)
User Function LinhaHorizontal()
// Linha Horizontal
MSCBLINEH(10, 20, 90, 2)
Return
9. MSCBLineV (Imprime Linha Vertical)
Objetivo:
Imprime uma linha vertical.
Sintaxe:
MSCBLineV(nX1mm, nY1mm, nY2mm, nExpessura, cCor)
Parâmetro | Descrição |
nX1mm | Posição X1 em Milímetros |
nY1mm | Posição Y1 em Milímetros |
nY2mm | Posição X2 em Milímetros |
[nEspessura] | Numero com a espessura em pixel |
*[cCor] | String com a Cor Branca ou Preta (“W” ou “B”) |
Exemplo:
MSCBLineV (Imprime Linha Vertical)
User Function LinhaVertical()
// Linha Vertical
MSCBLINEV(50, 10, 40, 2)
Return
10. MSCBLoadGraf (Carrega Imagem na Memória da Impressora)
Objetivo:
Carrega uma imagem para memória da impressora.
Sintaxe:
MSCBLOADGRF(cImagem)
Parâmetro | Descrição |
cImagem | Nome do arquivo que será carregado, inclusive o path + nome completo + extensão |
Observações:
Exemplo do código usando o padrão de programação ZPL:
MSCBLoadGraf (Carrega Imagem na Memória da Impressora)
User Function ImprimeImagem()
Local cNomeImagem := "LOGO"
Local nX := 5, nY := 5
MSCBLOADGRF("LOGO.GRF") // Carrega a imagem
MSCBGRAFIC(nX, nY, cNomeImagem)
Return
11. MSCBGraphic (Imprimir Imagem)
Objetivo:
Imprime gráfico que está armazenado na memória da impressora.
Sintaxe:
MSCBGRAFIC(nXmm, nYmm, cArquivo, lReverso)
Parâmetro | Descrição |
NXmm | Posição X em Milímetros |
NYmm | Posição Y em Milímetros |
cArquivo | Nome do gráfico que foi carregado na memória da impressora (não colocar a extensão do arquivo) |
*[lReverso] | Imprime em reverso quando tiver sobre um box preto |
Exemplo usando o padrão de programação ZPL:
MSCBGrafic (Imprimir Imagem)
User Function ImprimeImagem()
Local cNomeImagem := "LOGO"
Local nX := 5, nY := 5
MSCBLOADGRF("LOGO.GRF") // Carrega a imagem
MSCBGRAFIC(nX, nY, cNomeImagem)
Return
12. MSCBWrite (Comando Direto para Impressora)
Objetivo:
Permite enviar para impressora uma linha de programação nativa.
Sintaxe:
MSCBWrite(cConteudo)
Parâmetro | Descrição |
cConteudo | Linha de programação nativa da impressora. |
Exemplo usando o padrão de programação Zebra (família ZPL):
MSCBWrite (Comando Direto para Impressora)
User Function ComandoDireto()
// Exemplo para Zebra (ZPL)
MSCBWRITE("^XA^FO50,50^A0N,30,30^FDHello World^FS^XZ")
Return
Atenção: o MSCBWrite é muito poderoso em conjunto com ferramentas como o ZebraDesigner e BarTender, que são ferramentas de desenho e geração de etiquetas de código de barras, além do Labelary(Em outro blog irei detalhar como o Labelary poderá ser útil pre-visualização das etiquetas no dia a dia).
13. MSCBInfoEti (Informações da Etiqueta)
Objetivo:
Grava informações para gerenciamento do MSCBSpool.
Sintaxe:
MSCBInfoEti(cDescr,cFiltro)
Parâmetro | Descrição |
cDescr | Descrição que gerará informação no MSCBSpool para identificar a etiqueta. |
cFiltro | É utilizado para realizar filtros no MSCBSpool. Vide documentação MSCBSpool. |
Exemplo:
MSCBInfoEti (Informações da Etiqueta)
User Function InfoEtiqueta()
Local cDescricao := "Etiqueta de Produto"
Local cFiltro := "PROD001"
MSCBInfoEti(cDescricao, cFiltro)
Return
Exemplo Completo Integrando Várias Funções:
User Function ImprimirEtiquetaCompleta()
Local cCodProd := "PROD001"
Local cDescProd := "Widget XYZ"
Local cCodBarras := "7891234567890"
// Configurar impressora
MSCBPRINTER("ZEBRA", "LPT1", 203, 100, .F.)
// Iniciar etiqueta
MSCBBEGIN(1, 3)
// Desenhar caixa
MSCBBOX(5, 5, 95, 45, 1)
// Imprimir textos
MSCBSAY(10, 10, "Código: " + cCodProd, "N", "A", "012,008")
MSCBSAY(10, 20, "Descrição: " + cDescProd, "N", "A", "012,008")
// Imprimir código de barras
MSCBSAYBAR(20, 30, cCodBarras, "N", "EAN13", 15, .T., .T.)
// Imprimir logo
MSCBLOADGRF("LOGO.GRF")
MSCBGRAFIC(70, 5, "LOGO")
// Finalizar e imprimir etiqueta
MSCBEND()
// Fechar conexão com a impressora
MSCBCloseprinter()
Return
Este conjunto de exemplos demonstra como utilizar as principais funções ADVPL para impressão de etiquetas térmicas. Cada função desempenha um papel específico na criação de uma etiqueta completa, desde a configuração da impressora até a impressão final e fechamento da conexão.
Para empresas que buscam implementar soluções avançadas de etiquetagem ou otimizar seus processos existentes, contar com uma DO THINK especializada pode ser extremamente benéfico. Especialistas podem ajudar a personalizar essas funções para atender às necessidades específicas do negócio, garantindo eficiência e precisão na geração de etiquetas.